リスティング広告 運用代行サービス|株式会社カルテットコミュニケーションズ|Yahoo広告/Google広告正規代理店

PHPでDI(Dependency Injection)

公開日:
更新日:

何かと話題のPHPでのDIについてまとめてみました。

そもそも DI(Dependency Injection)ってなんぞ?

その名の通り、 依存性(Dependency)注入(Injection)です。

依存をクラス内で生成せずに外から設定します。
まだパッとしないので具体例を挙げて説明してみます。

まずDIでないパターン

[php]
/**
* Car.php
*/
class Car
{
/**
* @var EngineInterface
*/
private $engine;

public function __construct()
{
$this->engine = new Engine();
}

public function run()
{
$energy = $this->engine->burn();
}
}
[/php]


このコードの良くない点

  1. 別のエンジンに変えたい時にCar.phpを修正しなければならない。
  2. エンジンがうまく動作しない時のテストはほぼ不可能
  3. Engineが完成するまでCarを作る事ができない。

DIパターンを適用してみる


方法1: コンストラクターインジェクション

[php]
/**
* Car.php
*/
class Car
{
/**
* @var EngineInterface
*/
private $engine;

/**
* @param EngineInterface $engine
*/
public function __construct(EngineInterface $engine)
{
$this->engine = $engine;
}

public function run()
{
$energy = $this->engine->burn();
}
}
[/php]


方法2: セッターインジェクション

[php]
/**
*
*/
class Car
{
/**
* @var EngineInterface
*/
private $engine;

/**
* @param EngineInterface $engine
*/
public function setEngine(EngineInterface $engine)
{
$this->engine = $engine;
}

public function run()
{
$energy = $this->engine->burn();
}
}
[/php]

これで先述の問題点は解決できました。

1.別のエンジンに変えたい時にCar.phpを修正しなければならない。

> Carを使う側が好きにすれば良い。

2.エンジンがうまく動作しない時のテストはほぼ不可能

>テスト時に設定するエンジンを変えてしまえば良い。

3.Engineが完成するまでCarを作る事ができない。

>開発中は仮のエンジン(モック)を作って使えば良い。

DIとはこういう事

意外と簡単ですねー

だが依存を手動で解決するには少し大変という話

[php]

// CarFactory.php

class CarFactory
{
public function get($type)
{
if ($type === ‘economy’) {
return new Car(new HybridEngine(new GasolineEngine(), new ElectricMotor(new Battery())));
}
if ($type === ‘monster’) {
return new Car(new V8Engine(6600));
}
}
}
[/php]

引数が多くて管理しきれなくなる事は見えてます。
そこで登場するのが DIコンテナ

DI コンテナ

依存関係を定義しておくと、オブジェクトの生成時に依存を解決してくれるという代物です。
どう定義するかは、実際にコードを見た方が分かりやすいのでココでは省略。

ちなみにPHP製DIコンテナは意外と沢山あります。
有名どこはこんな所でしょうかね

Symfony/DependencyInjectionでサンプル

バンドルを作った際に{バンドルディレクトリ}/DependencyInjection/{バンドル名}BundleExtention.phpというファイルが生成されていると思います。

[php]

// HogeBundleExtention.php

public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);

// デフォルトはXMLなのでYAMLフォーマットに変更します。
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.’/../Resources/config’));
$loader->load(‘services.yml’);
}
[/php]

Resources/config/services.ymlをDIの定義ファイルとして指定したので、先述のCarFactory.phpを定義として記述してみます。

[js]

# Resources/config/services.yml

services:
car.hybrid:
class: Hoge\Car
arguments: [@engine.hybrid]

engine.hybrid:
class: Hoge\Engine\Hybrid
arguments: [@engine.gasoline, @engine.motor]

engine.gasoline:
class: Hoge\Engine\Gasoline

engine.motor:
class: Hoge\Engine\Motor
arguments: [@battery]

battery:
class: Hoge\Battery
[/js]

  1. それぞれを サービス として定義
  2. 依存しているサービスをメソッドの引数として定義

これで$container->get('car.hybrid')$factory->get('economy')の結果は同じになります。

1営業日以内に返信いたします 広告の運用代行についてのお問い合わせはこちら
シェアする

ブログ記事の中で広告運用の事例をご紹介することがありますが、実際の事例を一部加工した内容となっておりますのでご留意ください。

また、2018年7月24日よりGoogle AdWordsはGoogle広告に名称変更されました。それ以前の記事に関してはGoogle AdWordsと表記されておりますのでご了承ください。


リスティング広告の
情報をお届け

メルマガではリスティング広告に詳しくなれる記事を毎週一週間分まとめてお届けします。不定期にはなりますがリスティング広告に限らず、Web集客改善に繋がる資料もお送りしていきますので、興味のある方はぜひご登録ください。

同じカテゴリの最近の記事