DIコンテナについて

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ライブラリがあります。

・PHP-DI
・Pimple

この記事では Pimple を使って話を進めます。

 

Pimpleとは

Pimpleとは DIコンテナ(DIを一元管理)を利用するPHPのライブラリーです。

Composerを使ってインストールします。

(※gitクローンでも入手できます。)

Pimple Official web site.

 

インストール方法

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 にアクセス

 
以上です。

PHP おススメ教材(by Udemy)

 

本庄マサノリ

仕事で Laravel を使っています。気づいたことや新しい発見など情報を発信していきます。問い合わせはこちら

>> Twitter をフォローする

 

-周辺知識