DIコンテナとAutowireの「魔法」を実装して理解する

-- Views

March 22, 26

スライド概要

PHPerKaigi 2026の発表資料です。
デモで利用するソースコードのリポジトリはこちら:
https://github.com/takaram/simple-di-container

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

ダウンロード

関連スライド

各ページのテキスト
1.

DIコンテナとAutowireの「魔法」 を実装して理解する PHPerKaigi 2026 荒巻拓哉 (@takaram71)

2.

本発表の資料 スライド デモ用ソースコード

3.

自己紹介 ● 荒巻拓哉 ● X: @takaram71 GitHub: @takaram ● バックエンドエンジニア @株式会社 ラクス ○ 問い合わせ自動応対システムの 開発

4.

今日のテーマ ● DI・DIコンテナ ○ “型宣言を書いとけば勝手に代入されてるやつ”? 今日のゴール ● DIコンテナが何をしてるのかイメージできる

5.

DI / DIコンテナとは?

6.

DIとは Dependency Injection ● クラスAからクラスBのメソッドを呼び出す ○ クラスB = 依存 dependency ● Dependencyを外から渡してもらう = injection ● クラス自身がdependencyをnewしない ○ テストではモックに差し替えたりできる

7.

DIしないパターン

8.

DIするパターン コンストラクタインジェクション: newの引数に渡す

9.

DIするパターン セッターインジェクション: setterメソッド経由で渡す

10.

DIするパターン プロパティインジェクション: プロパティに 何らかの方法で 直 接セットする

11.

DIするパターン ● よく使うのはコンストラクタインジェクション ○ 未設定状態にならない ○ 特殊な操作が不要

12.

DIを使った実装 ● 大量にnewが必要 ● コンストラクタ引数変更が 大変

13.

DIコンテナの役割 ● オブジェクト生成を担う

14.

DIコンテナはオブジェクト生成方法をどう知る? ● 人間が事前に設定する ● DIコンテナ自身が型宣言から判断してくれる ○ → Autowire

15.

DIコンテナライブラリ ● 多くのフレームワークはDIコンテナが組み込まれている ● 専用のDIコンテナライブラリもある

16.

ここまでのまとめ ● DI: 利用するオブジェクトを外から渡すこと ● DIコンテナ: 渡すべきオブジェクト(依存)の用意~オブジェ クト生成までしてくれるもの ● Autowire: 依存を型宣言から自動判断してくれる機能

17.

DIコンテナのAutowireを作る

18.

今回作るDIコンテナの機能 ● クラス名からインスタンスを取得できる ● コンストラクタの引数を自動で解決できる (Autowire) ● インターフェースと実装クラスを紐づけられる

19.

Step 1: クラス名からインスタンスを取得

20.

Step 2: コンストラクタの引数を自動で解決 ● 型宣言を取得するためにリフレクションを利用 ● リフレクション ○ PHPの標準機能 ○ クラス、メソッド、関数、etc. の様々な情報を取得できる

21.

Step 2: コンストラクタの引数を自動で解決

22.

Step 3: インターフェースと実装クラスを紐づけ ● 紐づけの設定方法はライブラリによってバラバラ ● 今回はnew Container()の引数に渡す方式

23.

Step 3: インターフェースと実装クラスを紐づけ

24.

今回作るDIコンテナの機能 ● クラス名からインスタンスを取得できる ● コンストラクタの引数を自動で解決できる (Autowire) ● インターフェースと実装クラスを紐づけられる → 意外とシンプルなコードで実装できた!🎉

25.

未対応の機能 ● 異常系の処理 ○ 循環依存 ○ 存在しないクラス、未紐づけのインターフェース ● スカラー引数対応 ● (セッター|プロパティ)インジェクション ● シングルトン管理 etc.

26.

まとめ ● DIコンテナの本質的な部分は意外とシンプル ● リフレクションを利用すると、クラスやメソッドの情報を取れ る ● ブラックボックスなDIコンテナの中をイメージできていれば 幸いです!

27.

付録

28.

もう1つのインスタンス作成方法 ● new $className(...$args)以外に、リフレクションに もインスタンス作成機能がある ○ ReflectionClass::newInstance() ○ ReflectionClass::newInstanceArgs(array $args) ● 歴史の長いライブラリはこちらを使っていることも ○ ...による引数展開はPHP 5.6 (2014) からの機能

29.

もう1つのインスタンス作成方法 ● LaravelのDIコンテナはnewInstanceArgs()だった ○ のを先日new方式に変えました (laravel/framework#58391)

30.

PSR-11 ● DIコンテナのインターフェースのデファクトスタンダード ○ https://www.php-fig.org/psr/psr-11/ ● 多くのDIコンテナライブラリはこれをimplementしている