65

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

私はBucketPimple、およびsfServiceContainerを見て、いくつかのテストを実行し、DIC がどのように機能するかを本当に感謝しています。そのシンプルさと生の力のために、私はおそらくPimpleに行きます. この問題がなかった場合:

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

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

私の質問は、この問題に対処して解決策を見つけた人はいますか?

4

6 に答える 6

59

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

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

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

変数の名前なしでデータ型を書くことができます (ただし、データ型なしで名前を書くことはできません)。

于 2011-06-18T11:59:53.153 に答える
46

コンテナにアクセスするたびに、コンテナから引き出されたオブジェクトのタイプを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での型ヒントインライン変数の場合、 1つのアスタリスクで使用する@var必要があります。これはdoc-blockコメントではなく、またはでは機能しません。また、名前はタイプの前にあります。/*/**//

public function foo() {
    /* @var $service MyService */
    $service = $container['service'];
    ...
}
于 2011-06-20T22:38:12.470 に答える
14

IDE はコードを実行しないので、彼らは知らないので、あなたからの助けが必要です。これが Eclipse やその他の IDE でも機能することはわかっています。変数の型をヒントします。

Netbeans / Phpstorm / PDT / ZendStudio の例

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

Code complete が で再び機能し始め$mailerます。

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

  1. *コメントは 1 つだけで始まります。
  2. ヒントよりもまず変数名。

代替コメントバリアント

多くの議論の対象となったため、IDE 間で異なる場合があります。ただし、ほとんどの IDE は、上記の方法でインライン コード変数の変数ヒントをサポートしています。そのため、IDE によっては、次のように 2 つのアスタリスクが前に付いているように、異なる方法で記述される場合があります。

/** @var $mailer MailerInterface */

PHPDoc の互換性

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

/** @var MailerInterface $mailer  */

そのドキュメントは通常、クラス変数に使用されます ( @var - Document the data type of a class variable )。PHPDoc は、QA の負担を伴うコメントの後にクラス変数の定義がありません。

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

于 2011-06-18T11:46:37.863 に答える
1

にきびは、コンテナー ビルダーの原則を導入するだけです。それを理解すれば、ニキビはもう必要ありません。


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 の方が優れています。さらに、元の依存関係情報 (コンストラクターの引数 typehints) のほとんどは、Pimple と sfDepenencyContainer によって無視され、構成が肥大化して脆弱になります。

于 2012-07-07T13:26:14.687 に答える
1

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

于 2016-03-08T22:29:44.633 に答える