您可以将函数存储在PHP数组中吗?


71

例如:

$functions = array(
  'function1' => function($echo) { echo $echo; }
);

这可能吗?最好的选择是什么?


1
TL; DR-自PHP 5.4起: $functions = [ 'function1' => function($echo){ echo $echo; } ]; ......自PHP 5.3起提供匿名函数,自5.4起,您可以编写[]而不是array()
jave.web,2016年

Answers:


149

推荐的方法是使用匿名函数

$functions = [
  'function1' => function ($echo) {
        echo $echo;
   }
];

如果要存储已经声明的函数,则可以简单地通过名称将其引用为字符串:

function do_echo($echo) {
    echo $echo;
}

$functions = [
  'function1' => 'do_echo'
];

在PHP的旧版本(<5.3)中,不支持匿名函数,您可能需要诉诸使用 create_function(自PHP 7.2起已弃用):

$functions = array(
  'function1' => create_function('$echo', 'echo $echo;')
);

所有这些方法都在callable伪类型的文档中列出。

无论您选择哪种方法,都可以直接调用该函数(PHP≥5.4)或使用call_user_func/ call_user_func_array

$functions['function1']('Hello world!');

call_user_func($functions['function1'], 'Hello world!');

关于call_user_func:是$ var = $ functions [“ function1”],当function1返回值时,这是不好的做法吗?
罗伊

2
嗨,罗伊。As$functions["functions1"]包含一个可调用项,将其分配给也$var将导致$var包含一个可调用项。您仍然需要调用with$var()来获取返回值。
Alex Barrett 2014年

2
刚刚发现了一个小错误,即如果数组是类成员,则PHP 5.3方法不起作用,例如:class MyClass {$ functions = [''function1'=> function($ echo){echo $ echo; }]; }
Zack Morris

@ZackMorris评论应该在答案中指出,因为在课堂上这样做不是一个不合理的想法(在发现他的评论之前我发生了至少两次)
frollo 16/09/20

4
来自php.net Warning This function has been DEPRECATED as of PHP 7.2.0. Relying on this function is highly discouraged.
ghabriel

11

从PHP“ 5.3.0匿名函数可用”开始,用法示例:

请注意,这比使用旧版本要快得多create_function

//store anonymous function in an array variable e.g. $a["my_func"]
$a = array(
    "my_func" => function($param = "no parameter"){ 
        echo "In my function. Parameter: ".$param;
    }
);

//check if there is some function or method
if( is_callable( $a["my_func"] ) ) $a["my_func"](); 
    else echo "is not callable";
// OUTPUTS: "In my function. Parameter: no parameter"

echo "\n<br>"; //new line

if( is_callable( $a["my_func"] ) ) $a["my_func"]("Hi friend!"); 
    else echo "is not callable";
// OUTPUTS: "In my function. Parameter: Hi friend!"

echo "\n<br>"; //new line

if( is_callable( $a["somethingElse"] ) ) $a["somethingElse"]("Something else!"); 
    else echo "is not callable";
// OUTPUTS: "is not callable",(there is no function/method stored in $a["somethingElse"])

参考资料:


9

create_function()从PHP 7.2.0开始,警告已被弃用。强烈建议不要使用此功能。

为了跟进Alex Barrett的文章,create_function()返回一个可以实际用于调用该函数的值,因此:

$function = create_function('$echo', 'echo $echo;' );
$function('hello world');

1

因为我可以

扩展Alex Barrett的帖子。

我将进一步完善这个想法,甚至可以将其扩展为外部静态类,甚至可以使用'...'标记来允许变长参数。

在下面的示例中,为清楚起见,我使用了关键字“数组”,但是方括号也可以。所示的使用init函数的布局旨在演示组织更复杂的代码。

<?php
// works as per php 7.0.33

class pet {
    private $constructors;

    function __construct() {
        $args = func_get_args();
        $index = func_num_args()-1;
        $this->init();

        // Alex Barrett's suggested solution
        // call_user_func($this->constructors[$index], $args);  

        // RibaldEddie's way works also
        $this->constructors[$index]($args); 
    }

    function init() {
        $this->constructors = array(
            function($args) { $this->__construct1($args[0]); },
            function($args) { $this->__construct2($args[0], $args[1]); }
        );
    }

    function __construct1($animal) {
        echo 'Here is your new ' . $animal . '<br />';
    }

    function __construct2($firstName, $lastName) {
        echo 'Name-<br />';
        echo 'First: ' . $firstName . '<br />';
        echo 'Last: ' . $lastName;
    }
}

$t = new pet('Cat');
echo '<br />';
$d = new pet('Oscar', 'Wilding');
?>

好的,现在精简为一行...

function __construct() {
    $this->{'__construct' . (func_num_args()-1)}(...func_get_args());
}

可用于重载任何函数,而不仅仅是构造函数。


-1

通过使用闭包,我们可以将函数存储在数组中。基本上,闭包是一种无需指定名称即可创建的函数-匿名函数。

$a = 'function';
$array=array(
    "a"=> call_user_func(function() use ($a) {
        return $a;
    })
);
var_dump($array);

-1
<?php 

$_['nice']=function(){
    echo 'emulate a class';
};

$_['how']=function(){
    echo ' Now you can ';
};

(function()use($_){//autorun
    echo 'construct:';

    ($_['how'])();
    ($_['nice'])();


})();




//almost the same in here. i do not recomand each of them
//using array of functions or classes isn't a very high speed execution script
//when you build 70k minimum app 
//IF YOU USE THESE ONLY TO TRIGGER SMALL THINGS OVER A FRAMEWORK THAT IS A GO
[
(function(){
    echo 'construct 2:Now you can ';
    return '';
})()

,(function(){
    echo 'emulate a class';
    return '';
})()



];


?>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.