PHP IDEに依存関係噴射コンテナを理解させるにはどうすればよいですか?
-
29-10-2019 - |
質問
現在の状況:私はプロジェクトに依存関係があり、依存関係の注入を使用して解決します。依存関係噴射コンテナ(DIC)を使用して、依存関係の管理を容易にし、クラスを怠lowにして、次のロジックステップを撮りたいと思います。
私は見た バケツ, にきび, 、 と sfservicecontainer, 、いくつかのテストを実行し、DICの機能に本当に感謝しています。たぶん、そのシンプルさと生の力のために、私はおそらくにきびのために行くでしょう。私がこの問題を抱えていなかった場合:
DICの申し出の抽象化により、私が使用しているIDE(phpstorm)は、私のコードで何が起こっているのかをもはや理解していません。 $ container ['Mailer']または$ sc-> Mailerがクラスオブジェクトを保持していることを理解していません。また、NetBeans IDE:同じ問題を試しました。
私のIDEが役に立たないので、これは私にとって本当に問題です。クラスを扱う際に、コードのヒント、オートコンプリート、リファクタリングツールなしでプログラムしたくありません。そして、コードを検証するときに、IDEがあらゆる種類の誤検知を見つけたくありません。
だから私の質問は、誰かがこの問題に対処し、解決策を見つけたのですか?
解決
変数のクラスを「手動で」定義できます。
/** @var YourClassType $mailer */
$mailer = $container['mailer'];
phpstorm(およびby 基準)、2つのアスタリスクを使用して、変数の名前の前にデータ型を書きます。
変数の名前なしでデータ型を記述できます(ただし、データ型なしでは名前ではありません)。
他のヒント
あなたは確かにあなたのコンテナから引き抜かれたオブジェクトのタイプをあなたのIDEに伝えることができますが あなたがそれにアクセスするたびに、 一度やる方が良いです。次のソリューションの両方に、コンテナのサブクラス化が含まれます。とにかくこれを行うことをお勧めします。
アクセスしたインスタンスメンバーを使用するコンテナ用 ->
または魔法を介して露出します __get
方法、IDEがどのタイプを保持しているかを伝えることができます。これは、コードが実行されたときに追加の解析を伴わないため、これは素晴らしいことです。
/**
* My container. It contains things. Duh.
*
* @property MyService $service
* @property MyDao $dao
*/
class MyContainer extends Container { }
アレイとして機能するPimpleおよびその他のコンテナの場合、必要なトップレベルのオブジェクトのアクセサー関数を作成できます。コンテナが作成されたときにより多くの解析を意味しますが、1回行い、APCに保持する必要があります。とにかく、自動コンプリートメソッド内に忘れがちな配列キーを配置するため、とにかく配列アクセスよりもメソッドを大いに好む。
class MyContainer extends Pimple
{
/**
* @return MyService
*/
public function getMyService() {
return $this['service'];
}
}
ところで、タイプヒントのインライン変数用 @var
NetBeansでは、使用する必要があります /*
と 1つのアスタリスク. 。これは いいえ ドキュメントブロックのコメントと機能しません /**
また //
. 。また、名前はタイプの前に来ます。
public function foo() {
/* @var $service MyService */
$service = $container['service'];
...
}
IDEはコードを発生させないため、彼らはあなたを知らず、何らかの助けが必要です。これはEclipseや他のIDEでも機能することを知っています。変数のタイプを示唆しています。
netbeans / phpstorm / pdt / zendstudioの例
/* @var $mailer MailerInterface */
$mailer = $sc->mailer
コードの完了が再度動作し始めます $mailer
.
PDTの場合、それは重要です:
- コメントは1つから始まります
*
それだけ。 - 最初にヒントよりも変数名。
代替コメントバリエーション
多くの議論の対象となるため、IDEによって異なる場合があります。ただし、ほとんどのIDEは、上記のようにインラインコード変数の変動ヒントをサポートしています。したがって、IDEに応じて、これは異なって書かれているかもしれませんが、ここのように、前に2つのアスタリスクがあります。
/** @var $mailer MailerInterface */
phpdoc互換性
インラインコードのクラスvar doc-commentを模倣する場合、phpdocパーサーは問題を抱えています。
/** @var MailerInterface $mailer */
そのドキュメントは通常、クラス変数に使用されます(@var-クラス変数のデータ型を文書化する)。 PHPDOCは、QAの負担を伴うコメントの後、クラス変数の定義を欠落しています。
ただし、一部のIDEは、phpdoc clas-variableスタイルで書かれた場合、単純な変数のコード完了を提供します。現在のクラスのコード完了に対して、それが実際に存在しない新しいメンバーが導入される可能性があるため、副作用があるかどうかはわかりません。
Googleからここに来た人のために。
phpstormは実際に、phpdocsを何度も繰り返し作成するのではなく、この種の問題を解決する方法を提供します - 作成と設定 .phpstorm.meta.php
ある意味でファイル ここで説明します スムーズに動作し、オートコンプリートとタイプ検査を獲得します。
私は質問がDICだけについてであることを知っていますが、 Silex Pimple Dumper コンテナをJSONファイルにダンプするサービスプロバイダー。同じ著者が書いた phpstorm用プラグイン そのファイルを読み取り、サービス名とそのタイプ(クラス、文字列など)でオートコンプリートを開くことができます。私はこれらの2つのコンポーネントを使用していますが、Silex/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(
);
}
}
正直に言うと、「プログラミング」で書かれている容器は、lanuageが間違っています。コンテナの責任とは、オブジェクトの初期化されたグラフを発信者に持ち込むことです。 「プログラミング言語」にアクセスすることで、簡単にその責任に違反することができます。依存関係を構成するための一部のDSLの方が優れています。さらに、元の依存関係情報のほとんど(コンストラクターの引数タイプヒント)は、PimpleとSFDepenencyContainerによって無視され、構成が肥大化して脆弱になります。