2

考虑以下代码,它是将回调函数存储为成员,然后使用它的方案:

class MyClass {
  function __construct($callback) {
    $this->callback = $callback;
  }

  function makeCall() {
    return $this->callback();
  }
}

function myFunc() {
  return 'myFunc was here';
}

$o = new MyClass(myFunc);
echo $o->makeCall();

我希望myFunc was here得到回应,但相反我得到:

Call to undefined method MyClass::callback()

谁能解释这里出了什么问题,以及我可以做些什么来获得所需的行为?

万一这很重要,我使用的是 PHP 5.3.13。

4

3 回答 3

3

您可以将makeCall方法更改为:

function makeCall() {
  $func = $this->callback; 
  return $func();
}
于 2012-08-26T15:32:42.007 回答
2

将其作为字符串传递并通过call_user_func调用它。

class MyClass {
  function __construct($callback) {
    $this->callback = $callback;
  }

  function makeCall() {
    return call_user_func($this->callback);
  }
}

function myFunc() {
  return 'myFunc was here';
}

$o = new MyClass("myFunc");
echo $o->makeCall();
于 2012-08-26T15:35:33.560 回答
2

关于 PHP 的一件重要的事情是它通过语法而不是符号的内容来识别符号的类型,因此您需要明确说明您所指的内容。
在许多语言中,您只需编写:

myVariable
myFunction
myConstant
myClass
myClass.myStaticMethod
myObject.myMethod

解析器/编译器知道每个符号的含义,因为它只需知道分配给它们的内容就知道它们所指的内容。
然而,在 PHP 中,您需要使用语法让解析器知道您指的是什么“符号命名空间”,因此通常您编写:

$myVariable
myFunction()
myConstant
new myClass
myClass::myStaticMethod()
$myObject->method()

但是,如您所见,这些是调用而不是引用。要在 PHP 中传递对函数、类或方法的引用,使用组合的字符串和数组语法:

'myFunction'
array('myClass', 'myStaticMethod')
array($myObject, 'myMethod')

在您的情况下,您需要使用'myFunc'代替myFunc让 PHP 知道您正在传递对函数的引用,而不是检索myFunc常量的值。

另一个后果是,当您编写 $myObject->callback() 时,PHP会因为括号而假定callback是一个方法,并且它不会尝试循环一个 property
为了达到预期的结果,您需要将属性回调的副本/引用存储在局部变量中,并使用以下语法:

$callback = $this->callback;
return $callback();

由于美元符号和括号,将其标识为闭包;或使用 call_user_func 函数调用它:

call_user_func($this->callback);

另一方面,它是一个需要回调的内置函数。

于 2012-08-26T15:58:09.297 回答