在PHP中通过引用传递函数

时间:2011-06-25 01:08:07

标签: php

是否可以通过引用传递函数?

这样的事情:

function call($func){
    $func();
}

function test(){
    echo "hello world!";
}

call(test);

我知道你可以'test',但我真的不想那样,因为我需要通过引用来传递函数。

这是通过匿名函数实现这一目的的唯一方法吗?

澄清:如果你从C ++中回想起来,你可以通过指针传递一个函数:

void call(void (*func)(void)){
    func();
}

或者在Python中:

def call(func):
    func()

这就是我想要完成的事情。

9 个答案:

答案 0 :(得分:26)

对于它的价值,给这样的东西怎么样? (是的,我知道这是匿名函数在帖子中提及,但我对回复中没有提及闭包/功能的大量不满 - 所有的对象,所以这主要是针对在这篇文章中运行的人的注释。)

我不使用PHP ,但using a closure似乎在 PHP 5.3 (但不是PHP 5.2)中工作为demonstrated here我不确定有什么限制,如果有的话。(据我所知,闭包会吃掉你的孩子。你已被警告过。)

function doIt ($fn) {
  echo "doIt\n";
  return $fn();
}

function doMe () {
  echo "doMe\n";
}

// I am using a closure here.
// There may be a more clever way to "get the function-object" representing a given
// named function, but I do not know what it is. Again, I *don't use PHP* :-)
echo doIt(function () { doMe(); });

快乐的编码。

答案 1 :(得分:14)

call_user_func()的问题是你传递了被调用函数的返回值,而不是函数本身。

我之前也遇到过这个问题,这是我提出的解决方案。

function funcRef($func){
  return create_function('', "return call_user_func_array('{$func}', func_get_args());");
}

function foo($a, $b, $c){
    return sprintf("A:%s B:%s C:%s", $a, $b, $c);
}

$b = funcRef("foo");

echo $b("hello", "world", 123);

//=> A:hello B:world C:123

ideone.com demo

答案 2 :(得分:3)

function func1(){
    echo 'echo1 ';
    return 'return1';
}

function func2($func){
    echo 'echo2 ' . $func();
}

func2('func1');

结果:

echo1 echo2 return1

答案 3 :(得分:2)

不,函数不是PHP中的第一类值,它们不能通过 name literal 传递(这就是你要求的)。即使是通过create_function创建的匿名函数或函数也会通​​过对象或字符串引用传递。

您可以将函数名称作为字符串传递,将对象名称作为(object, string)数组传递,或将匿名函数作为对象传递。这些都不传递指针或引用,它们只是传递函数的名称。所有这些方法都称为callback伪类型:http://php.net/callback

答案 4 :(得分:1)

在PHP 5.4.4中(未测试较低版本或其他版本),您可以完全按照建议进行操作。

以此为例:

function test ($func) {
    $func('moo');
}

function aFunctionToPass ($str) {
    echo $str;
}

test('aFunctionToPass');

脚本将回显“moo”,就像你直接调用“aFunctionToPass”一样。

答案 5 :(得分:1)

您可以通过在声明函数时将函数分配给局部变量来创建引用:

$test = function() {
    echo "hello world!";
};

function call($func){
    $func();
}

call($test);

答案 6 :(得分:0)

你可以说

$fun = 'test'; 
call($fun); 

答案 7 :(得分:0)

而不是call(test);,请使用call_user_func('test');

答案 8 :(得分:0)

这个Javascript第一类函数的类似模式:

// first class function
$add = function($first, $second, $callback) {
  echo "\n\n". $first+$second . "\n\n";
  if ($callback) $callback();
};

function logDone(){
  echo "\n\n done \n\n";
}
call_user_func_array($add, array(2, 3, logDone));
call_user_func_array($add, array(3, 6, function(){
  echo "\n\n done executing an anonymous function!";
}));

可以通过以下方式在PHP中完成(在C9 IDE上使用5.5.9-1ubuntu测试):

{{1}}

结果:5完成9完成执行匿名功能!

参考:https://github.com/zenithtekla/unitycloud/commit/873659c46c10c1fe5312f5cde55490490191e168