今日の小ネタ: create_closure()

http://p0t.jp/mt/archives/2007/04/php_22.html より。
リンク先のコメントで id:bobchin さんが書かれている方法とはまた別のやつを考えてみました。

<?php
$GLOBALS['__CLOSURE_VARS'] = array();

function create_closure($args, $code, $vars)
{
    $n = count($GLOBALS['__CLOSURE_VARS']);
    $GLOBALS['__CLOSURE_VARS'][$n] = $vars;
    $defs = '';
    foreach (array_keys($vars) as $key) {
        $defs .= sprintf('$%s = &$GLOBALS["__CLOSURE_VARS"][%d]["%s"];',
                         $key, $n, $key);
    }
    return create_function($args, $defs . $code);
}

if (isset($_SERVER['argv']) && realpath($_SERVER['argv'][0]) == __FILE__) {
    function get_adder($start = 0)
    {
        return create_closure('', 'return ++$count;', array('count' => $start));
    }
    $adder = get_adder();
    for ($i = 0; $i < 10; $i++) {
        var_dump($adder());
    }
}

NGワード: グローバル変数使ってる時点で「クロージャ」とは言わない (先日のアレも・・・)


ちなみに、create_function() で作成した関数 (NULL バイトで始まる文字列) は、可変関数スタイルで $func() として呼び出せます。