PHP:使用匿名函数创建全局函数

时间:2021-01-11 22:28:00

I want to create global function with dynamic name, but I dont want to write code of function as string, as it's required in PHP docs about create_function function.

我想创建具有动态名称的全局函数,但我不想将函数代码编写为字符串,因为它在PHP文档中有关create_function函数的要求。

Dream scenario would be like:

梦想场景将是:

$functionName = "new_super_function";
$functionBody = function($a,$b) { return $a + $b; };

if ( !function_exists($functionName) ) create_function($functionName, $functionBody);

//from here my function with dynamic name is ready
//I could now call it like call_user_func($functionName, 5, 7) => 12
//or just use it later like new_super_function(5,7) => 12

I was looking for such sort of possibility but I couldnt find anything. Any ideas?

我一直在寻找这种可能性,但我找不到任何东西。有任何想法吗?

2 个解决方案

#1


Just assign the function body to the function name like this:

只需将函数体指定为函数名称,如下所示:

$functionName = "new_super_function";
$functionBody = function($a,$b) { return $a + $b; };

if (!function_exists($functionName))
    $functionName = $functionBody;

echo call_user_func($functionName, 5, 7);  //Same as: echo $functionName(5, 7);

output:

12

EDIT:

If you want to declare an anonymous function which you can also call in other function, this won't be possible, since it is assigned to a variable and the variable is in a scope, so you either have to pass the variable with the anonymous function as argument or use the global keyword.

如果你想声明一个你也可以在其他函数中调用的匿名函数,这是不可能的,因为它被赋值给一个变量并且变量在一个作用域中,所以你要么必须用匿名传递变量作为参数使用或使用global关键字。

#2


I thought it would be fun to try to answer it. You would have to create your own create_function method.

我觉得尝试回答它会很有趣。您必须创建自己的create_function方法。

function my_create_function($name, $callable) {
    $GLOBALS['my_functions'][$name] = $callable;

    $call_wrapper = sprintf('function %s() {
        $arguments = func_get_args();
        return call_user_func_array($GLOBALS["my_functions"][%s], $arguments);
    }', $name, $name);

    eval($call_wrapper);
}

Test:

class Test {
    static public function prepare() {
        $add_function = function($a, $b) { return $a + $b; };

        var_dump($add_function(1, 2));

        my_create_function('my_add', $add_function);
    }

    static public function testit() {
        var_dump(call_user_func('my_add', 1, 2));

        var_dump(call_user_func_array('my_add', array(1, 2)));

        var_dump(my_add(1, 2));
    }
}

Test::prepare();
Test::testit();

#1


Just assign the function body to the function name like this:

只需将函数体指定为函数名称,如下所示:

$functionName = "new_super_function";
$functionBody = function($a,$b) { return $a + $b; };

if (!function_exists($functionName))
    $functionName = $functionBody;

echo call_user_func($functionName, 5, 7);  //Same as: echo $functionName(5, 7);

output:

12

EDIT:

If you want to declare an anonymous function which you can also call in other function, this won't be possible, since it is assigned to a variable and the variable is in a scope, so you either have to pass the variable with the anonymous function as argument or use the global keyword.

如果你想声明一个你也可以在其他函数中调用的匿名函数,这是不可能的,因为它被赋值给一个变量并且变量在一个作用域中,所以你要么必须用匿名传递变量作为参数使用或使用global关键字。

#2


I thought it would be fun to try to answer it. You would have to create your own create_function method.

我觉得尝试回答它会很有趣。您必须创建自己的create_function方法。

function my_create_function($name, $callable) {
    $GLOBALS['my_functions'][$name] = $callable;

    $call_wrapper = sprintf('function %s() {
        $arguments = func_get_args();
        return call_user_func_array($GLOBALS["my_functions"][%s], $arguments);
    }', $name, $name);

    eval($call_wrapper);
}

Test:

class Test {
    static public function prepare() {
        $add_function = function($a, $b) { return $a + $b; };

        var_dump($add_function(1, 2));

        my_create_function('my_add', $add_function);
    }

    static public function testit() {
        var_dump(call_user_func('my_add', 1, 2));

        var_dump(call_user_func_array('my_add', array(1, 2)));

        var_dump(my_add(1, 2));
    }
}

Test::prepare();
Test::testit();