hysryt / wiki

https://hysryt.github.io/wiki/
0 stars 0 forks source link

PHP:DIコンテナ #108

Open hysryt opened 5 years ago

hysryt commented 5 years ago
hysryt commented 5 years ago

Pimple

v3.2.3

Pimple はサービスパラメータを管理する。

サービスはDBコネクション、テンプレートエンジン、メーラーなどが該当する。 パラメータはサービスの生成に必要な設定値などが該当する。

Composer でインストール

$ composer require pimple/pimple ~3.0
<?php

include './vendor/autoload.php';

$container = new Pimple\Container();

サービスの定義

定義は無名関数でおこなう。 引数の $c はコンテナを指す。

$container = new Pimple\Container();

$container['db_connection'] = function($c) {
  return new DBConnection();
};

// インスタンス取得
$db_con = $container['db_connection'];

class DBConnection {
  // 実装
}

インスタンスは必要とされたタイミングで初めて作成される。 すでにインスタンスが作成されている場合はそれを返す。

インスタンスを取得するたびに新しいインスタンスを生成したい場合は factory() メソッドを使用する。

$container['db_connection'] = $container->factory(function($c) {
  return new DBConnection();
});

あまりないケースだと思うが、サービス定義に使用した無名関数自体を取得したい場合は raw() メソッドを使用する。

$connection_function = $container->raw('db_connection');

パラメータの定義

$container['param'] = 'parameter';

パラメータはサービスの生成に必要な値などを設定する。

$container['db_name'] = 'database';
$container['db_user'] = 'user';
$container['db_pass'] = 'password';

$container['db_connection'] = function($c) {
  return new DBConnection($c['db_name'], $c['db_user'], $c['db_pass']);
};

パラメータとして関数を設定する場合は、サービスの定義と区別できるように protect() メソッドで無名関数をラップする。

$container['random_func'] = $container->protect(function () {
    return rand();
});

$container['random_func']();
hysryt commented 5 years ago

PHP-DI

v6.0.5

PHP 7.0 以降必須

Composer でインストール

$ composer require php-di/php-di
<?php

include './vendor/autoload.php';

$container = new DI\Container();

Auto wiring(自動配線)

与えられたクラス名から自動的にインスタンス生成までを行うため、 Pimple のようなサービスの定義は不要。

$container = new DI\Container();
$db_con = $container->get('DBConnection');

class DBConnection {
  // 実装
}

Annotation

アノテーションによるサービスの定義。 Doctrine Annotations ライブラリが必要。

$ composer require doctrine/annotations

インスタンス変数への注入

<?php

$builder = new DI\ContainerBuilder();
$builder->useAnnotations(true);
$container = $builder->build();

$db_con = $container->get('DBConnection');
$db_con->connect();

class DBConnection {
  /**
   * @Inject
   * @var DB
   */
  private $db;

  function connect() {
    $this->db->open();
  }
}

class DB {
  function open() {
    echo 'opening db.';
  }
}
opening db.

コンストラクタへの注入

<?php

$builder = new DI\ContainerBuilder();
$builder->useAnnotations(true);
$container = $builder->build();

$db_con = $container->get('DBConnection');
$db_con->connect();

class DBConnection {
  private $db;

  /**
   * @Inject
   * @param DB $db
   */
  function __construct($db) {
    $this->db = $db;
  }

  function connect() {
    $this->db->open();
  }
}

class DB {
  function open() {
    echo 'opening db.';
  }
}
opening db.

PHP記法による定義

PHPでの記述によるサービスの定義。

$builder = new DI\ContainerBuilder();
$builder->addDefinitions([
  'DB' => DI\create(),
  'DBConnection' => DI\create()->constructor(DI\get('DB'))
]);
$container = $builder->build();

$db_con = $container->get('DBConnection');
$db_con->connect();

class DBConnection {
  private $db;

  function __construct($db) {
    $this->db = $db;
  }

  function connect() {
    $this->db->open();
  }
}

class DB {
  function open() {
    echo 'opening db.';
  }
}
hysryt commented 5 years ago

Aura.Di

v3.4.0

Composer でインストール

$ composer require aura/di
<?php

include './vendor/autoload.php';

$builder = new Aura\Di\ContainerBuilder();
$container = $builder->newInstance();

$db_con = $container->newInstance('DBConnection');

class DBConnection {
  // 実装
}