Skip to content

Instantly share code, notes, and snippets.

@juno
Created December 15, 2008 08:35
Show Gist options
  • Save juno/35903 to your computer and use it in GitHub Desktop.
Save juno/35903 to your computer and use it in GitHub Desktop.
Simple DIContainer examples in PHP
<?php
class DIContainer
{
private $components = array();
/**
* 指定された名前でコンポーネントを登録します。
*
* @param string $name 登録する際の名前
* @param mixed $value コンポーネントとして登録する値
*/
public function add($name, $value)
{
$this->components[$name] = $value;
}
/**
* 指定された名前で登録されたコンポーネントを返します。
*
* @param string $name 取得するコンポーネントの名前
* @return mixed コンポーネントまたはNULL
*/
public function get($name)
{
if (!array_key_exists($name, $this->components)) {
return null;
}
$component = $this->components[$name];
$this->injectDependency($component);
return $component;
}
/**
* 指定されたコンポーネントに、setterを利用して他コンポーネントの値を設定します。
*
* @param object $component コンポーネント
*/
private function injectDependency($component)
{
foreach (get_class_methods(get_class($component)) as $method) {
$property = self::extractPropertyName($method);
if (is_null($property) || !array_key_exists($property, $this->components)) {
continue;
}
call_user_func(array($component, 'set' . $property), $this->components[$property]);
}
}
/**
* 指定されたsetterメソッド名からプロパティ名を取得します。
*
* @param string $name メソッド名
*/
private static function extractPropertyName($method_name)
{
return preg_match("/^set([A-Z][A-Za-z]+)$/", $method_name, $matches) ? strtolower($matches[1]) : null;
}
}
<?php
require_once 'DIContainer.php';
/**
* PDOクラスをDIコンテナに登録するためのラッパクラス。
*/
class PDOComponent
{
private $delegate;
/**
* メソッド呼び出しをPDOオブジェクトに転送します。
*
* @param string $name メソッド名
* @param array $arguments 引数
*/
public function __call($name, $arguments)
{
$callback = array($this->delegate, $name);
if (!is_callable($callback)) {
throw new Exception("Call to undefined method " . __CLASS__ . "::" . $name . "()");
}
return call_user_func_array($callback, $arguments);
}
/**
* データベース接続設定を設定し、新しいPDOオブジェクトを生成します。
*
* @param array $config データベース接続設定
*/
public function setConfig($config)
{
$dsn = $config['db'] . ':dbname=' . $config['dbname'] . ';host=' . $config['host'];
$this->delegate = new PDO($dsn, $config['user'], $config['password']);
$this->delegate->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
}
// テスト時のデータベース接続設定
$test_config = new ArrayObject(array(
'db' => 'mysql',
'dbname' => 'hoge_test',
'host' => 'localhost',
'user' => 'dbusername',
'password' => 'dbpassword',
));
// 本番稼働時のデータベース接続設定
$prod_config = new ArrayObject(array(
'db' => 'mysql',
'dbname' => 'hoge_prod',
'host' => 'localhost',
'user' => 'dbusername',
'password' => 'dbpassword',
));
$container = new DIContainer;
$container->add('config', getenv('TEST') ? $test_config : $prod_config);
$container->add('pdo', new PDOComponent);
// オブジェクトをコンテナから取り出す
$pdo = $container->get('pdo');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment