Slim4でDIコンテナ(PHP-DI)を導入する
2024/01/29
DIコンテナを利用すると、ルートに登録したコールバック関数の引数でクラス名を指定すると、インスタンスが自動で渡されるようになります(依存注入)。複雑なインスタンス化プロセスもDIコンテナに設定することができます。例えば、コールバック関数の処理に入る前にDBへの接続をしておくといった使い方ができます。 ```php /** @var Slim\App $app */ $app->get('/', function (Doctrine\DBAL\Connection $conn) { // $connにDoctrine\DBAL\Connectionのインスタンスが代入されている $result = $conn->fetchAssociative('SELECT ...'); }); ``` ## 導入手順 まず、Composerで[PHP-DI](https://github.com/PHP-DI/PHP-DI)をインストールします。Slim4専用に用意されたものがあるので、そちらを使用します。 ```bash composer require php-di/slim-bridge ``` Composerでインストールしたら、次にSlim\Appクラスの生成方法を変更します。あらかじめ依存解決のルールを定義しておく必要があります。 ```diff + $containerBuilder = new DI\ContainerBuilder(); + $containerBuilder->addDefinitions([ + // ここで依存解決のルールを定義します + ]); + $container = $containerBuilder->build(); - $app = Slim\Factory\AppFactory::create(); + $app = DI\Bridge\Slim\Bridge::create($container); /** @var Slim\App $app */ $app->get('/', function (Doctrine\DBAL\Connection $conn) { // $connにDoctrine\DBAL\Connectionのインスタンスが代入されています $result = $conn->fetchAssociative('SELECT ...'); }); $app->run(); ``` ## 依存解決ルールの定義 最も簡単な定義方法は、クラス名とインスタンスを直接紐づける方法です。 ```php $containerBuilder->addDefinitions([ MyClass::class => new MyClass('hoge'), ]); ``` しかし、こちらの定義方法は**非推奨**になっています。必要不必要に関わらずHTTPリクエストがあるたびにインスタンスを生成してしまうためです。必要になった時だけインスタンスを生成する**lazy-loading**のための定義は以下のようになります。 ```php $containerBuilder->addDefinitions([ MyClass::class => DI\create(MyClass::class)->constructor('hoge'), // または MyClass::class => function () {return new MyClass('hoge');}, ]); ``` ほかにも便利な機能がたくさん用意されているので、詳しく知りたい方は[公式ドキュメント](https://php-di.org/doc/php-definitions.html)を参照してください。