はじめに
私のプロジェクトでは、Laravelを使用しております。
クラスAでクラスBのメソッドを使いたい時は、一般的な以下の流れでした。
1.クラスAでコンストラクタインジェクションをしてクラスBのインスタンスを取得
2.クラスAのコンストラクタ内で、プロパティXにクラスBのインスタンスを代入
3.オブジェクト演算子を使ってクラスBのメソッドを使用する$this->propertyB->myMethod()
しかし、気になる点が一点ありました。
class myServiceA implements myServiceAInterface
{
public function __construct(myRepositoryBInterface $myRepositoryB) {
$this->myRepositoryB = $myRepositoryB;
}
public function sampleMethod(string $hoge): string
{
$this->myRepositoryB->myMethod();
}
}
$myRepositoryB
の代入先のmyRepositoryBプロパティ(上述のプロパティX)が存在しない・・・
これって何で使えているんだっけ?
ということで本記事の執筆にいたりました。
動的プロパティ
オブジェクトに対して、存在しないプロパティを代入しようとした場合、 PHP は自動的に対応するプロパティを作成します。 こうして作成された動的なプロパティは、 そのインスタンスで のみ 使えます。
なるほど。存在しないプロパティに代入しようとすると、PHPがよしなにプロパティを作ってくれるそうです。
しかし、公式ドキュメントにはこうも記述されています。
警告
動的なプロパティは、PHP 8.2.0 以降は推奨されなくなりました。
代わりに、プロパティを宣言することを推奨します。
私のプロジェクトでは8.3系が使われていたので非推奨ということになります。
それではプロパティを追加しましょう。
class myServiceA implements myServiceAInterface
{
private $myRepositoryB; //追加
public function __construct(myRepositoryBInterface $myRepositoryB) {
$this->myRepositoryB = $myRepositoryB;
}
public function sampleMethod(string $hoge): string
{
$this->myRepositoryB->myMethod();
}
}
※ちなみに、2024年11月21日、PHPの新バージョンPHP 8.4.1のリリースを発表しました。
さいごに
今回のように、DI時にプロパティを定義していないとコード補完も効かず、コードジャンプも出来ないので特に支障を感じると思います。
しかし、今回の話はDIに限った話ではありません。
もし、ご自身のプロジェクトで未定義のプロパティを見つけたらしっかりと定義してあげましょう。
詳細な記事を書いていただいてる方を見つけたのでよろしければこちらもご覧ください。