在PHP中通过引用传递函数

Pwn*_*nna 25 php

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

像这样的东西:

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

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

call(test);
Run Code Online (Sandbox Code Playgroud)

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

是通过匿名功能这样做的唯一方法吗?

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

void call(void (*func)(void)){
    func();
}
Run Code Online (Sandbox Code Playgroud)

或者在Python中:

def call(func):
    func()
Run Code Online (Sandbox Code Playgroud)

这就是我想要完成的.

小智 27

对于它的价值,给这样的东西怎么样?(是的,我知道这是一个匿名函数,在帖子提到过,但我对大量的回复都不满意,根本没有提到闭包/函数对象,所以这对于在这篇文章中运行的人来说大多是一个注释.)

我不使用PHP,但使用闭包似乎在PHP 5.3(但不是PHP 5.2)中工作,如此处所示.我不确定有什么限制,如果有的话.(据我所知,封闭会吞噬你的孩子.你已被警告过.)

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(); });
Run Code Online (Sandbox Code Playgroud)

快乐的编码.

  • @ultimate好吧,**PHP不优雅**. (10认同)
  • @macek不,这正是OP所要求的.它在所需的调用周围使用匿名函数闭包,因此接收此匿名函数作为参数的函数不需要知道它是接收类方法还是全局函数.这是迄今为止最灵活的. (4认同)
  • 所以你将一个匿名函数传递给`doIt`.那怎么"通过引用传递`doMe`"?对不起,这个答案和其他答案一样无关紧要,主要是因为这个问题非常不清楚. (3认同)
  • 我完全同意. (3认同)
  • 为了澄清这一点,PHP 知道 `callable` 的不同表示法:`'globalFunctionName'`、`'ClassName::staticMethodName'、`array('ClassName', 'staticMethodName')`、`array($object, 'methodName' ')`。所有这些都适用于 `call_user_func()`、`is_callable()` 等 - [文档](http://www.php.net/manual/en/language.types.callable.php)。尽管如此,从技术上讲,它们不是引用(符号 4 中的对象实例除外),而只是标识符。 (3认同)
  • 这与OP自己提出的有何不同? (2认同)

mač*_*ček 15

问题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
Run Code Online (Sandbox Code Playgroud)

ideone.com演示


dec*_*eze 5

不,函数不是 PHP 中的第一类值,它们不能通过名称文字传递(这就是您所要求的)。即使是匿名函数或通过创建的函数create_function也是通过对象或字符串引用传递的。编辑: PHP 8.1 现在拥有一流的 callables,因此对于较新版本的 PHP 来说不再如此。

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