PHP5.3無名関数のcallback引数呼び出しと、無名関数化およびその逆

in

PHP5.3の無名関数がそこそこ使えそうだったので追加調査。

まずはいままで関数名を渡していたcallback引数に無名関数を使えるか。array_walkpreg_replace_callbackのサンプルから変換してみます。追加でcall_user_func。

$fruits = array("d" => "lemon", "a" => "orange", "b" => "banana", "c" => "apple");
$test_print = function ($item2, $key)
{
    echo "$key. $item2<br />\n";
};
array_walk($fruits, $test_print);

$input = "通常の位置 [indent] 字下げ [indent] もっと字下げ [/indent] 字下げ [/indent] 通常の位置"; 
$parseTagsRecursive = function ($input) use (&$parseTagsRecursive)
{

    $regex = '#\[indent]((?:[^[]|\[(?!/?indent])|(?R))+)\[/indent]#';

    if (is_array($input)) {
        $input = '<div style="margin-left: 10px">'.$input[1].'</div>';
    }

    return preg_replace_callback($regex, $parseTagsRecursive, $input);
};
$output = $parseTagsRecursive($input);
echo $output;

$f = function ($i){
	echo $i *2;
};
call_user_func($f, 3);

どれも問題なく使えました。callback系は対応してあるの前提で、もし動かないものがあれば不具合と捉えて良いかと思います。

通常の関数を無名関数に変換するのは結構簡単にできます。今後関数型の引数前提で書いてあるライブラリーができた場合には使えるでしょうか。ライブラリー側で対処すべき問題のような気もしますが。

function anonymize($func_name)
{
	return function () use (&$func_name) {
		return call_user_func_array($func_name, func_get_args());
	};
}

function f($i){
	echo $i *2;
}
$f = anonymize('f');
$f(5);

では反対に、無名関数の名前を取得する場合ですが、例えば自前のcallback関数を作っていた場合で、何らかの理由で無名関数ではそのまま通らない場合などに使えるでしょうか? 少々やっかいでした。例えばこんな感じで。。

class AnonymousFunction {
	private static $a = array();
	private static $id = 0;
	public static function get($id){
		return self::$a[$id];
	}
	public static function register($fn, $func_num_args = 0){
		self::$a[++self::$id] = $fn;
		
		$args = array();
		for ($i = 0; $i < $func_num_args; ++$i)
			$args[] = "func_get_arg(" . $i . ")";

		return create_function('', 
			'$f = AnonymousFunction::get(' . self::$id . '); return $f(' . implode(",", $args) . ');'
		);
	}
	public static function unanonymize($fn, $func_num_args = 0)
	{
		return AnonymousFunction::register($fn, $func_num_args);
	}
}

$f = function ($i){
	echo $i *2;
};
$func_name = AnonymousFunction::unanonymize($f, 1);
$func_name(3);

実際使うならメソッドの場合の動作確認、対応など必要そうですが、一通りなんとかなりそうでした。

PHP5.3無名関数シリーズ3はこちら

Trackback URL for this post:

http://nonn-et-twk.net/twk/trackback/224
0