在PHP中接受函数作为参数


Answers:


150

如果您使用的是PHP 5.3.0或更高版本,则是可能的。

请参见手册中的匿名函数

对于您的情况,您将这样定义exampleMethod

function exampleMethod($anonFunc) {
    //execute anonymous function
    $anonFunc();
}

9
该死,我知道有可能。本来要回答,但想先找到一些文档以链接到该文档,并且不知道它到底叫什么。好的,现在我知道何时需要执行此操作。谢谢。
罗布

3
在5.3之前,您可以使用create_function
Gordon

非常感谢。由于我必须针对PHP4.3进行此操作,所以我想我必须使用其他逻辑来完成我想做的事情。
Cristian

1
@Casidiablo-请参阅Jage的答案,您也许可以使用进行某些操作create_function()。它不是完全一样,因为您必须将函数作为一串代码传递,然后将其eval()隐藏在后台。不理想,但是您可以使用它。
zombat'4

1
你怎么称呼它?您能给一个现有功能的名字吗?例如:exampleMethod(strpos);
sumid

51

只需添加其他功能,即可传递一个函数名称:

function someFunc($a)
{
    echo $a;
}

function callFunc($name)
{
    $name('funky!');
}

callFunc('someFunc');

这将在PHP4中工作。


17

您还可以使用create_function将函数创建为变量并将其传递。虽然,我更喜欢匿名函数的感觉。去僵尸。


+1作为替代。听起来OP可能需要它。
zombat'4

谢谢!我必须坚持使用旧的PHP 5.2安装,并且anonymoys函数在那里不起作用。
diosney

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

15

像这样编码:

function example($anon) {
  $anon();
}

example(function(){
  // some codes here
});

如果您可以发明这样的东西(受Laravel Illuminate的启发),那就太好了:

Object::method("param_1", function($param){
  $param->something();
});

正是我一直在寻找
哈维

5

PHP版本> = 5.3.0

示例1:基本

function test($test_param, $my_function) {
    return $my_function($test_param);
}

test("param", function($param) {
    echo $param;
}); //will echo "param"

示例2:std对象

$obj = new stdClass();
$obj->test = function ($test_param, $my_function) {
    return $my_function($test_param);
};

$test = $obj->test;
$test("param", function($param) {
    echo $param;
});

示例3:非静态类调用

class obj{
    public function test($test_param, $my_function) {
        return $my_function($test_param);
    }
}

$obj = new obj();
$obj->test("param", function($param) {
    echo $param;
});

示例4:静态类调用

class obj {
    public static function test($test_param, $my_function) {
        return $my_function($test_param);
    }
}

obj::test("param", function($param) {
    echo $param;
});

5

根据@zombat的回答,最好先验证匿名函数:

function exampleMethod($anonFunc) {
    //execute anonymous function
    if (is_callable($anonFunc)) {
        $anonFunc();
    }
}

或者验证自PHP 5.4.0起的参数类型:

function exampleMethod(callable $anonFunc) {}

3

经过PHP 5.3测试

正如我在这里看到的那样,匿名函数可以为您提供帮助:http : //php.net/manual/en/functions.anonymous.php

您可能需要的是什么,而不是在不将其包装在动态创建的函数中的情况下如何传递函数。稍后将看到,您需要传递以字符串形式编写的函数名称作为参数,检查其“可调用性”,然后调用它。

要检查的功能:

if( is_callable( $string_function_name ) ){
    /*perform the call*/
}

然后,要调用它,请使用这段代码(如果还需要参数,请将它们放在数组中),请参见:http : //php.net/manual/en/function.call-user-func.php

call_user_func_array( "string_holding_the_name_of_your_function", $arrayOfParameters );

如下所示(以类似的,无参数的方式):

    function funToBeCalled(){
        print("----------------------i'm here");
    }
    function wrapCaller($fun){
        if( is_callable($fun)){
            print("called");
            call_user_func($fun);
        }else{
            print($fun." not called");
        }
    }

    wrapCaller("funToBeCalled");
    wrapCaller("cannot call me");

这是一个解释如何执行类似操作的类:

<?php
class HolderValuesOrFunctionsAsString{
    private $functions = array();
    private $vars = array();

    function __set($name,$data){
        if(is_callable($data))
            $this->functions[$name] = $data;
        else
            $this->vars[$name] = $data;
    }

    function __get($name){
        $t = $this->vars[$name];
        if(isset($t))
            return $t;
        else{
            $t = $this->$functions[$name];
            if( isset($t))
                return $t;
        }
    }

    function __call($method,$args=null){
        $fun = $this->functions[$method];
        if(isset($fun)){
            call_user_func_array($fun,$args);
        } else {
            // error out
            print("ERROR: Funciton not found: ". $method);
        }
    }
}
?>

以及用法示例

<?php
    /*create a sample function*/
    function sayHello($some = "all"){
    ?>
         <br>hello to <?=$some?><br>
    <?php
    }

    $obj = new HolderValuesOrFunctionsAsString;

    /*do the assignement*/
    $obj->justPrintSomething = 'sayHello'; /*note that the given
        "sayHello" it's a string ! */

    /*now call it*/
    $obj->justPrintSomething(); /*will print: "hello to all" and
        a break-line, for html purpose*/

    /*if the string assigned is not denoting a defined method
         , it's treat as a simple value*/
    $obj->justPrintSomething = 'thisFunctionJustNotExistsLOL';

    echo $obj->justPrintSomething; /*what do you expect to print?
        just that string*/
    /*N.B.: "justPrintSomething" is treated as a variable now!
        as the __set 's override specify"*/

    /*after the assignement, the what is the function's destiny assigned before ? It still works, because it's held on a different array*/
     $obj->justPrintSomething("Jack Sparrow");


     /*You can use that "variable", ie "justPrintSomething", in both ways !! so you can call "justPrintSomething" passing itself as a parameter*/

     $obj->justPrintSomething( $obj->justPrintSomething );
         /*prints: "hello to thisFunctionJustNotExistsLOL" and a break-line*/

    /*in fact, "justPrintSomething" it's a name used to identify both
         a value (into the dictionary of values) or a function-name
         (into the dictionary of functions)*/
?>

2

使用类的简单示例:

class test {

    public function works($other_parameter, $function_as_parameter)
    {

        return $function_as_parameter($other_parameter) ;

    }

}

$obj = new test() ;

echo $obj->works('working well',function($other_parameter){


    return $other_parameter;


});
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.