juno (owner)

Revisions

  • a68e6a juno Mon Dec 15 00:35:12 -0800 2008
gist: 35903 Download_button fork
public
Public Clone URL: git://gist.github.com/35903.git
Embed All Files: show embed
DIContainer.php #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<?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;
    }
}
 
 
example.php #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<?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');