2016-08-05 5 views
1

パッケージがアプリケーションに含まれているときに名前空間のないPHPファイルを自動的にロードする必要があるパッケージがあります。Composerに依存関係としてインクルードされたときにファイルを自動的にインクルードする

以下は、私がappA/ためPackageA依存関係を作る際に、パスのリポジトリを使用するように指示hereを追ってきた

packages/ 
    +-- PackageA/ 
     +-- Entities/ 
     +-- Mappers/ 
     +-- Services/ 
     +-- composer.json 
     +-- constants.php 

apps/appA/ 
    +-- vendors/ 
    +-- autoload/ 
    +-- composer.json 

apps/appB/ 
    +-- vendors/ 
    +-- composer.json 

私の一般的なディレクトリ構造です。この部分はスムーズに動作します。

PackageAのファイルの中には、ほとんどの場合ファイルパスにアクセスする必要があります。これは、「constants.phpは」何のためにあるのかで、これらの値は手続き的に定義されています

<?php 

define('XML_REPO_PATH', __DIR__ . '/../blah/xml/'); 

// --etc-- 

私はもともとで、「パッケージ/ PackageA/composer.json」で「ファイル」オートローディングメカニズムを使用することを考えた:

{ 
    ... 

    "autoload": { 
     "psr-4": { ... } 
     "files": ["constants.php"] 
    } 
} 

ただし、PackageAappAに含まれる場合、constants.phpは必要ありません。これを修正するには、代わりに「パッケージ/ PackageA/composer.json」で"files": [...]を入れて、私は「アプリ/ appsA/composer.json」の自動ロードセクションに次のように置く:

"files": ["vendors/packages/PackageA/constants.php"] 

をこれは非常にではありません望ましいことは、アプリケーションPackageAを使用する必要があるためです。私は、コンポーザーの性質上、PackageAのファイルが、構成定数の場合のように、特定の手続き型コードにアクセスできる(すなわち、含まれることを保証する)ことができるようになると考えています。これを行う方法はありますか?

+0

名前空間を 'constants.php'ファイルに追加することができず、定期的な自動読み込みを使用する理由はありますか? – Chris

+0

@Chris php <5.6でクラス定数を '__DIR__'のような他の定数と連結することができない – jeremy

答えて

1

コンフィギュレーションファイルまたは定数付きファイルを含めるには、Composerのfilesオートローディングを使用しないでください。他のすべての図書館でのパフォーマンスの影響について考えてください。 filesセクションのファイルは、PackageAを使用しているかどうかに関係なく、スクリプトを呼び出すたびにロードされます。また、名前空間が一定ではないため、定数名の衝突が考えられます。 filesオートローディングは唯一です!そうしなければ動作させることができないレガシーコードに使用することを意図していました。あなたはそれを使用しないでください。

ているので、PHP < 5.6に私は主な問題は、連結ではなく、定数ファイルはクラスではないことを__DIR__

のような他の定数でクラス定数を連結することはできません。 ComposerのAutoladerはクラスをロードするだけなので、オートローディングはここでは機能しません。

したがって、1つの解決策は、定数の空のクラスを導入することですが、上に副作用を追加することができます。 次に、ベンダ\ PackageAの傘の下に名前空間を付けます。 これは、 のオートロードをトリガーするために、use vendor\PackageA\Constants;を他のクラスに追加することができます。

空のクラスが含まれていますが、ファイルが自動ロードされると、その定義が副作用として発生しています。良いIDEは副作用を引き起こすため、このファイルにエラーフラグを設定します。なぜなら、他の開発者は、定義がどこから来ているのかわからないからです。クラスを含めるだけですが、autoloadingfilesセクションを使用するよりもうまくいきます。

composer.json

"autoload": { 
    "psr-4": { "\Vendor\PackageA\\" : "./src/packages/PackageA/" } 
} 

constants.php

<?php 

namespace Vendor\PackageA; 

class Constants 
{ 
    // @todo PHP 5.6 namespaced class constants 
} 

// global side effect: constant definition 
define('XML_REPO_PATH', __DIR__ . '/../blah/xml/'); 

// etc.. 

のベスト・プラクティスは、あなたのパッケージの構成の構成オブジェクトまたは配列を受け取るコンストラクタにConfigurationクラスを使用することが考えられます。 これは、ハードコードされたグローバル構成からパッケージとアプリケーションを切り離します。 基本的に、構成注入(パッケージ環境へのApp環境、パッケージはそのコンテキストに基づいて構成されます)。

+0

私はこのルートに行きました。あなたが提案したように私は' @ todo'コメントを残しました。 * PHPの本物のバージョン – jeremy

+0

うれしい –

関連する問題