を取得します出力時にこのコード
<?php
class FunctionsProvider
{
protected static $closures = [];
public static function addClosure($name, $closure)
{
if (is_callable($closure)) {
static::$closures[$name] = $closure;
} else {
throw new \Exception('Closure is not callable');
}
}
public static function __callStatic($name, $arguments)
{
if (array_key_exists($name, static::$closures)) {
return call_user_func_array(static::$closures[$name], $arguments);
} else {
throw new \Exception('Unknown method');
}
}
}
//Lets prepare sample closure
$foo = function() {
return "bar";
};
FunctionsProvider::addClosure('foo', $foo);
$return = FunctionsProvider::foo();
var_dump($return);
に似魔法機能__callStatic
でこれをachiveすることができます私が使用して作成するために管理しましたevil eval
,ReflectionClassおよびSuperClosureライブラリー。
<?php
function register_function(string $name, Closure $closure)
{
$serializedBody = (new SuperClosure\Serializer)->serialize($closure);
$obj = unserialize($serializedBody);
$reflection = new ReflectionClass($obj);
$property = $reflection->getProperty('data');
$property->setAccessible(true);
$data = $property->getValue($obj);
$body = preg_replace('/^function \(/', "function {$name} (", $data['code']);
eval($body);
}
$closure = function($a = 1, $b = 2, $c = 3) {
var_dump(compact('a', 'b', 'c'));
};
register_function('test', $closure);
var_dump(function_exists('test')); // true
test(13, 2, 3);
// array(3) {
// ["a"]=>
// int(13)
// ["b"]=>
// int(2)
// ["c"]=>
// int(3)
// }
「名前付き関数が必要です」とはどういう意味ですか?あなたは 'library_function( 'my_func')'を実行しなければなりませんし、 'function library_function($ func){$ func(); } '? –
@MarcB:そうしたいと思う。いいえ、ライブラリはSmartyで、ユースケースはプラグインを登録しています。それはあなたがそれを与えるどの種類の呼び出し可能で、現在はClosureをサポートしていないかに応じてテンプレートの特定のコンパイルを行います。インスタンスメソッド、静的メソッド、または名前付き関数のいずれかです。 –
smartyは名前付きの関数を望んでいますが、名前を付けたくありませんか? – AbraCadaver