web-dev-qa-db-ja.com

PHP IDE Dependency Injection Containersを理解するには?

現在の状況:プロジェクトに依存関係があり、依存関係の注入を使用して解決しています。依存関係注入コンテナー(DIC)を使用して、依存関係の管理を容易にし、クラスを遅延ロードすることにより、次のロジックステップを実行したいと思います。

BucketPimple 、および sfServiceContainer を見て、いくつかのテストを実行し、DICの仕組みに本当に感謝しています。シンプルで生々しい力があるので、私はおそらくニキビに行きます。この問題がなかった場合:

DICの申し出の抽象化のため、IDE私が使用している(PHPStorm)は、私のコードで何が起こっているのか理解できなくなりました。$ container ['mailer']または$ sc-> mailerはクラスオブジェクトを保持していますが、Netbeans IDEも試しました:同じ問題です。

私のIDEが役に立たなくなります。クラスを扱うときにコードヒント、オートコンプリート、リファクタリングツールなしでプログラミングしたくないので、これは本当に問題です。そして、私の= IDEは、コードを検証するときにあらゆる種類の誤検知を検出します。

だから私の質問は次のとおりです:誰かがこの問題に対処し、解決策を見つけましたか?

64
Blaise

変数のクラスを「手動で」定義できます。

/** @var YourClassType $mailer */
$mailer = $container['mailer'];

PhpStorm(および standards による)では、2つのアスタリスクを使用して、変数の名前の前にデータ型を記述します。

変数の名前なしでデータ型を記述できます(ただし、データ型のない名前は記述できません)。

57
OZ_

確かに、IDEコンテナから引き出されたオブジェクトのタイプにアクセスするたびに、それを伝えることができますが、次の解決策は両方ともコンテナのサブクラス化を伴うため、とにかくこれを行うことをお勧めするPimpleの使用を開始しました。

_->_でアクセスされるか、魔法の___get_メソッドで公開されるインスタンスメンバーを使用するコンテナーの場合、IDE保持する型を伝えることができます。コードの実行時に追加の解析を行わないでください。IDEのみが問題になります。

_/**
 * My container. It contains things. Duh.
 *
 * @property MyService $service
 * @property MyDao $dao
 */
class MyContainer extends Container { }
_

Pimpleおよび配列として機能するその他のコンテナーの場合、必要なトップレベルオブジェクトのアクセサー関数を作成できます。コンテナが作成されるとき、より多くの解析を意味しますが、一度行われ、APCに保持される必要があります。とにかく、自動補完されたメソッド内に忘れやすい配列キーを配置するため、配列アクセスよりもメソッドを非常に好みます。

_class MyContainer extends Pimple
{
    /**
     * @return MyService
     */
    public function getMyService() {
        return $this['service'];
    }
}
_

ところで、NetBeansで_@var_を使用してインライン変数をタイプヒンティングするには、1つのアスタリスクで_/*_を使用する必要があります。これはnotdocブロックコメントであり、_/**_または_//_では機能しません。また、名前はタイプの前に来ます。

_public function foo() {
    /* @var $service MyService */
    $service = $container['service'];
    ...
}
_
44
David Harkness

IDEはコードを実行しないので、IDEはあなたの助けを必要としません。これはEclipseや他のIDEでも同様に機能することを知っています:変数の型をヒントします。

Netbeans/Phpstorm/PDT/ZendStudioの例

/* @var $mailer MailerInterface */
$mailer = $sc->mailer

完了したコードは、$mailer

PDTでは、次のことが重要です。

  1. コメントは1つの*のみ。
  2. まず、ヒントよりも変数名。

代替コメントバリアント

多くの議論が行われたため、IDEによって異なる場合があります。ただし、ほとんどのIDEは、上記の方法でインラインコード変数の変数ヒントをサポートしています。したがって、IDE

/** @var $mailer MailerInterface */

PHPDocの互換性

PHPDocパーサーは、インラインコードのクラスvar doc-commentを模倣すると問題が発生する可能性があります。

/** @var MailerInterface $mailer  */

このドキュメントは通常、クラス変数に使用されます( @ var-クラス変数のデータ型を文書化する )。 PHPDocでは、コメントの後にクラス変数の定義が欠落しているため、QAに負担がかかります。

ただし、一部のIDEは、PHPDocのclas-variableスタイルで記述された場合、単純な変数のコード補完も提供します。現在のクラスのコード補完に副作用があるかどうかはわかりませんが、実際には存在しない新しいメンバーが導入される可能性があります。

13
hakre

グーグルからここに来た人のために。

PHPStormは、実際にPHPDocを何度も作成する代わりに、この種の問題を解決する方法を提供します。つまり、.phpstorm.meta.phpある意味でファイル ここで説明 オートコンプリートとタイプ検査がスムーズに機能します。

7
woo

質問はDICのみに関することを知っていますが、コンテナをjsonファイルにダンプする Silex Pimple Dumper サービスプロバイダーがあります。同じ作者が PHPStormのプラグイン を作成しました。これは、そのファイルを読み取り、サービス名とそのタイプ(クラス、文字列など)でオートコンプリートを開くことができます。私はこれらの2つのコンポーネントを使用していますが、これはSilex/Pimpleの自動補完に適したオプションです。

1
Tales Santos

Pimpleは、コンテナビルダープリンシペを紹介するだけです。理解できれば、Pimpleはもう必要ありません。


class Container
{
    private $shared = array();

    public function getService() {
        return new Service(
            this->getFirstDependence(),
            this->getSecondDependence()
        );
    }

    protected function getFirstDependence() {
        return new FirstDependence(
            this->getSecondDependence()
        );
    }

    protected function getSecondDependence() {
        return isset($this->shared[__METHOD__]) ? $this->shared[__METHOD__] : $this->shared[__METHOD__] =
        new SecondDependence(
        );
    }
}

このように、Pimpleは混合$ c ['some key']のオブジェクトのタイプを隠しません。コンテナを編集するときに、オートコンプリートの提案があります。 Phpstormは、コードからメソッドの戻り値の型を自動解決できます。そして、あなたは明確なコンテナを持っているでしょう。コンテナをオーバーライドできます:


class TestContainer extends Container
{
    protected function getFirstDependence() {
        return new FirstDependenceMock(
        );
    }
}

正直に言うと、「プログラミング」言語で書かれたコンテナは間違った方法です。コンテナの役割は、オブジェクトの初期化されたグラフを呼び出し元に持ってくることです。 「プログラミング言語」にアクセスできると、その責任を簡単に破ることができます。依存関係を構成するためのDSLの方が優れています。さらに、PimpleとsfDepenencyContainerは、元の依存関係情報(コンストラクターの引数タイプヒント)のほとんどを無視して、構成を肥大化し、脆弱にします。

0
palex