在PHP中接受函数作为参数
我一直在想是否有可能在PHP中传递函数作为参数; 我想要的东西,当你在JS编程:
object.exampleMethod(function(){ // some stuff to execute });
我想要的是在exampleMethod的某处执行该函数。 在PHP中可能吗?
如果您使用的是PHP 5.3.0或更高版本,则可以。
请参阅手册中的匿名函数 。
在你的情况下,你可以像这样定义exampleMethod
:
function exampleMethod($anonFunc) { //execute anonymous function $anonFunc(); }
只要添加到其他人,您可以传递一个函数名称:
function someFunc($a) { echo $a; } function callFunc($name) { $name('funky!'); } callFunc('someFunc');
这将在PHP4中工作。
你也可以使用create_function来创build一个函数作为variables并传递它。 虽然,我更喜欢匿名function的感觉。 去吃一下
只需要像这样编码:
function example($anon) { $anon(); } example(function(){ // some codes here });
如果你能发明这样的东西(来自Laravel Illuminate的启发),那将是非常棒的:
Object::method("param_1", function($param){ $param->something(); });
使用类的简单示例:
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; });
PHP VERSION> = 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; });
testing了PHP 5.3
正如我在这里看到的,匿名函数可以帮助你: http : //php.net/manual/en/functions.anonymous.php
你可能需要什么,而不是在如何传递一个函数,而不是将它包装在一个即时创build的函数中 。 正如你稍后会看到的那样,你需要传递函数的名字作为参数写在string中,检查它的“callability”然后调用它。
做检查的function:
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*/ /*NB: "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)*/ ?>
根据@ zombat的回答,最好先validation匿名函数:
function exampleMethod($anonFunc) { //execute anonymous function if (is_callable($anonFunc)) { $anonFunc(); } }