2021/12/19
前回、「依存性の注入について」の記事をエントリーしました。
今回はその延長にある "DIコンテナ" についてエントリーします。
DIコンテナとは
DI のやり方は3つあるのですが本記事では主に コンストラクタ・インジェクション を利用して話を進めます。
前回の記事「依存性の注入」のチュートリアルのコードを例にとります。
: $cassette = new Cassette('スーパーマリオ'); $famikon = new Famikon($cassette); $twitter_client = new TwitterClient(); $nikonama = new Nikonama($cassette,$famikon,$twitter_client); :
コンストラクタ・インジェクションのデメリットは注入したいオブジェクトが多いとその分、引数が多くなることです。
また毎回インスタンスを生成するのも手間ですよね。
ここから DIの設定を管理する という考え生まれてきました。
それが DIコンテナ とよばれるものです。
DIコンテナは以下の二つを一元管理することができます。
・インスタンスの生成
DIコンテナを利用するには以下の二つのPHPライブラリがあります。
・Pimple
この記事では Pimple を使って話を進めます。
Pimpleとは
Pimpleとは DIコンテナ(DIを一元管理)を利用するPHPのライブラリーです。
Composerを使ってインストールします。
(※gitクローンでも入手できます。)
インストール方法
ex)プロジェクトファイルが C:\xampp\htdocs\demo にある場合。
1)コマンドプロンプトを起動して cd コマンドでプロジェクトディレクトリまで移動します。
cd C:\xampp\htdocs\demo
2)requireコマンドを実行
composer require pimple/pimple "^3.0"
3)確認
C:\xampp\htdocs\demo にあるディレクトリを確認
チュートリアル
前回の「依存性の注入について」の記事で扱ったチュートリアルを利用します。
pimple を使ってDIコンテナでDIを一元管理します。
手順
1)pimple のインストール
2)DIコンテナの作成
3)実行
4)動作確認
1)pimple のインストール
コマンドプロンプトを起動してプロジェクトがあるディレクトリまで移動します。
移動後、composer の require コマンドで pimple を入れます。
cd C:\xampp\htdocs\demo composer require pimple/pimple "^3.0"
2)DIコンテナの作成
<?php require_once __DIR__ . '/vendor/autoload.php'; //(1) use Pimple\Container; //(2) $container = new Container(); //(3) $container['cassette.title'] = ''; $container['cassette'] = $container->factory(function($c){ return new Cassette($c['cassette.title']); }); $container['famikon'] = $container->factory(function ($c){ return new Famikon($c['cassette']); }); $container['twitter_client'] = function ($c){ return new TwitterClient(); }; $container['nikonama'] = $container->factory(function($c){ return new Nikonama($c['cassette'],$c['famikon'],$c['twitter_client']); });
1)オートローダ―を実装
2)+3)pimpleを使うためのお作法
仕組みとしては、
// 対象クラス $container['nikonama'] = $container->factory(function($c){ return new Nikonama($c['cassette'],$c['famikon'],$c['twitter_client']); });
// 実行 $nikonama = $container['nikonama'];
1.$container['nikonama']が実行時に呼ばれる
2.無名関数が呼ばれる
3.インスタンスが生成される
という流れになっています。
factory()を用いることで無名関数が呼ばれる度に新たなインスタンスを生成します。
3)実行
(クラス/インターフェースの定義) : $container['cassette.title'] = 'スーパーマリオ'; $nikonama = $container['nikonama']; $nikonama->play(); $nikonama->tweet();
クラス/インターフェース定義については変更はありません。
ちなみにDIコンテナを使わない場合はこんな記述でした。
(クラス/インターフェースの定義) : $cassette = new Cassette('スーパーマリオ'); $famikon = new Famikon($cassette); $twitter_client = new TwitterClient(); $nikonama = new Nikonama($cassette,$famikon,$twitter_client); $nikonama->play(); $nikonama->tweet();
DIコンテナを使うことで
・各インスタンスの生成
・引数の指定
この辺りスッキリしました。
4)動作確認
http://{ホスト名}/demo/di4_demo.php にアクセス
以上です。
仕事で Laravel を使っています。気づいたことや新しい発見など情報を発信していきます。問い合わせはこちら。