【发布时间】:2014-01-08 03:28:01
【问题描述】:
在 PHP 中,objects are effectively passed by reference(幕后发生的事情是 a bit more complicated)。同时,call_user_func() 的参数不是通过引用传递的。
那么这样的一段代码会发生什么?
class Example {
function RunEvent($event) {
if (isset($this->events[$event])) {
foreach ($this->events[$event] as $k => $v) {
//call_user_func($v, &$this);
// The above line is working code on PHP 5.3.3, but
// throws a parse error on PHP 5.5.3.
call_user_func($v, $this);
}
}
}
}
$e = new Example;
$e->events['example'][] = 'with_ref';
$e->events['example'][] = 'without_ref';
$e->RunEvent('example');
function with_ref(&$e) {
$e->with_ref = true;
}
function without_ref($e) {
$e->without_ref = true;
}
header('Content-Type: text/plain');
print_r($e);
输出:
Example Object
(
[events] => Array
(
[example] => Array
(
[0] => with_ref
[1] => without_ref
)
)
[without_ref] => 1
)
注意:在文件顶部添加error_reporting(E_ALL); 或error_reporting(-1); 没有区别。我没有看到任何错误或警告,当然命令行上的php -l 也没有显示任何错误。
我实际上希望它在回调函数中使用和不使用引用都可以工作。我认为在call_user_func() 中删除$this 之前的& 符号就足以为最新版本的PHP 解决这个问题。显然,带有引用的版本不起作用,但同样它不会引发任何 linting 错误,因此很难追踪这种情况(这可能在我正在使用的代码库中多次发生)。
我有一个实际的问题:有什么方法可以使with_ref() 函数工作?我只想修改RunEvent() 代码,而不是每个使用它的函数(其中大部分确实使用引用)。
我还有一个好奇的问题,因为我在这里看到的行为对我来说毫无意义。 相反会更有意义。这里到底发生了什么? 一个函数调用没有一个&符号可以修改对象,而一个有&符号的函数调用似乎令人吃惊地违反直觉不能。
【问题讨论】:
标签: php object pass-by-reference