Hatena::ブログ(Diary)

わからん

2011.06.05

[] Pimple を読んだ

Pimple は PHP で実装されたシンプルな DI コンテナです。 Pimple - A simple Dependency Injection Container for PHP 5.3 で公開されています。試してみました。

<?php
require dirname(__FILE__) . '/Pimple.php';

class Klass
{
  public $v1;
  public function __construct($v1)
  {
    $this->v1 = $v1;
  }
}

$container = new Pimple();

$container['key1'] = 'val1';

$container['something'] = function ($c) {
  return new Klass($c['key1']);
};

var_dump($container['something']->v1);  //=>val1

なぜこのような挙動なのでしょうか。これだけでは、$container と 無名関数の引数 $c とのつながりが読み取れません。


Pimple.php を見てみます。

<?php
class Pimple implements ArrayAccess
{
    private $values = array();
    ...
    function offsetGet($id)
    {
      ...
      return $this->values[$id] instanceof Closure ? $this->values[$id]($this) : $this->values[$id];
    }

Closure は無名関数の型です。呼び出されたオブジェクトが無名関数なら、可変関数として $this を引数に呼び出していました。$this の内容は次のとおり。

object(Pimple)#1 (1) {
  ["values":"Pimple":private]=>
  array(2) {
    ["key1"]=>
    string(4) "val1"
    ["something"]=>
    object(Closure)#2 (1) {
      ["parameter"]=>
      array(1) {
        ["$c"]=>
        string(10) "<required>"
      }
    }
  }
}

そういうことでしたか。


あとは、

<?php
    function share(Closure $callable)            //これと
    {
        return function ($c) use ($callable) {
            static $object;                      //これの組み合わせが視覚的になんか笑える

            if (is_null($object)) {
                $object = $callable($c);
            }

            return $object;
        };
    }

といったところでしょうか。さすがファビアンさん、といった感じの内容でした。

はてなユーザーのみコメントできます。はてなへログインもしくは新規登録をおこなってください。

Google
Connection: close