-- Views
March 22, 26
スライド概要
PHPerKaigi 2026の発表資料です。
デモで利用するソースコードのリポジトリはこちら:
https://github.com/takaram/simple-di-container
DIコンテナとAutowireの「魔法」 を実装して理解する PHPerKaigi 2026 荒巻拓哉 (@takaram71)
本発表の資料 スライド デモ用ソースコード
自己紹介 ● 荒巻拓哉 ● X: @takaram71 GitHub: @takaram ● バックエンドエンジニア @株式会社 ラクス ○ 問い合わせ自動応対システムの 開発
今日のテーマ ● DI・DIコンテナ ○ “型宣言を書いとけば勝手に代入されてるやつ”? 今日のゴール ● DIコンテナが何をしてるのかイメージできる
DI / DIコンテナとは?
DIとは Dependency Injection ● クラスAからクラスBのメソッドを呼び出す ○ クラスB = 依存 dependency ● Dependencyを外から渡してもらう = injection ● クラス自身がdependencyをnewしない ○ テストではモックに差し替えたりできる
DIしないパターン
DIするパターン コンストラクタインジェクション: newの引数に渡す
DIするパターン セッターインジェクション: setterメソッド経由で渡す
DIするパターン プロパティインジェクション: プロパティに 何らかの方法で 直 接セットする
DIするパターン ● よく使うのはコンストラクタインジェクション ○ 未設定状態にならない ○ 特殊な操作が不要
DIを使った実装 ● 大量にnewが必要 ● コンストラクタ引数変更が 大変
DIコンテナの役割 ● オブジェクト生成を担う
DIコンテナはオブジェクト生成方法をどう知る? ● 人間が事前に設定する ● DIコンテナ自身が型宣言から判断してくれる ○ → Autowire
DIコンテナライブラリ ● 多くのフレームワークはDIコンテナが組み込まれている ● 専用のDIコンテナライブラリもある
ここまでのまとめ ● DI: 利用するオブジェクトを外から渡すこと ● DIコンテナ: 渡すべきオブジェクト(依存)の用意~オブジェ クト生成までしてくれるもの ● Autowire: 依存を型宣言から自動判断してくれる機能
DIコンテナのAutowireを作る
今回作るDIコンテナの機能 ● クラス名からインスタンスを取得できる ● コンストラクタの引数を自動で解決できる (Autowire) ● インターフェースと実装クラスを紐づけられる
Step 1: クラス名からインスタンスを取得
Step 2: コンストラクタの引数を自動で解決 ● 型宣言を取得するためにリフレクションを利用 ● リフレクション ○ PHPの標準機能 ○ クラス、メソッド、関数、etc. の様々な情報を取得できる
Step 2: コンストラクタの引数を自動で解決
Step 3: インターフェースと実装クラスを紐づけ ● 紐づけの設定方法はライブラリによってバラバラ ● 今回はnew Container()の引数に渡す方式
Step 3: インターフェースと実装クラスを紐づけ
今回作るDIコンテナの機能 ● クラス名からインスタンスを取得できる ● コンストラクタの引数を自動で解決できる (Autowire) ● インターフェースと実装クラスを紐づけられる → 意外とシンプルなコードで実装できた!🎉
未対応の機能 ● 異常系の処理 ○ 循環依存 ○ 存在しないクラス、未紐づけのインターフェース ● スカラー引数対応 ● (セッター|プロパティ)インジェクション ● シングルトン管理 etc.
まとめ ● DIコンテナの本質的な部分は意外とシンプル ● リフレクションを利用すると、クラスやメソッドの情報を取れ る ● ブラックボックスなDIコンテナの中をイメージできていれば 幸いです!
付録
もう1つのインスタンス作成方法 ● new $className(...$args)以外に、リフレクションに もインスタンス作成機能がある ○ ReflectionClass::newInstance() ○ ReflectionClass::newInstanceArgs(array $args) ● 歴史の長いライブラリはこちらを使っていることも ○ ...による引数展開はPHP 5.6 (2014) からの機能
もう1つのインスタンス作成方法 ● LaravelのDIコンテナはnewInstanceArgs()だった ○ のを先日new方式に変えました (laravel/framework#58391)
PSR-11 ● DIコンテナのインターフェースのデファクトスタンダード ○ https://www.php-fig.org/psr/psr-11/ ● 多くのDIコンテナライブラリはこれをimplementしている