为什么PHP的call_user_func()函数不支持通过引用传递?

Wil*_*tin 8 php language-design reference callback

为什么函数处理函数不call_user_func()支持通过引用传递参数?

文件说,简洁喜欢的东西"请注意,对于call_user_func()的参数不是按引用传递." 我假设PHP开发人员在这种情况下有某种原因禁用该功能.

他们是否面临技术限制?它是语言设计的选择吗?这是怎么发生的?

编辑:

为了澄清这一点,这里有一个例子.

<?php

function more(&$var){ $var++; }

$count = 0;
print "The count is $count.\n";

more($count);
print "The count is $count.\n";

call_user_func('more', $count);
print "The count is $count.\n";

// Output:
// The count is 0.
// The count is 1.
// The count is 1.
Run Code Online (Sandbox Code Playgroud)

这是正常运作的; call_user_func不会通过引用传递$ count,即使more()将其声明为引用变量.该call_user_func文件清楚地说,这是它应该工作的方式.

我很清楚我可以通过使用获得我需要的效果call_user_func_array('more', array(&$count)).

问题是:为什么call_user_func 设计为这样工作?在路过的参考文档说,"功能定义的本身就足以正确传递引用的论点." call_user_func的行为是一个例外.为什么?

Chr*_*ash 10

答案深深嵌入PHP 模型中引用工作的方式- 不一定是实现,因为它可能会有很大差异,特别是在5.x版本中.我确定你已经听过这些行,它们不像C指针,或C++引用等等......基本上,当一个变量被赋值或绑定时,它可以以两种方式发生 - 或者通过值(在其中) case将新变量绑定到包含旧值副本的新"box"或引用(在这种情况下,新变量绑定到与旧值相同的值框).无论我们是在谈论变量,函数参数还是数组中的单元格,都是如此.

当您开始将引用传递给函数时,事情开始变得有点毛茸茸 - 显然,目的是能够修改原始变量.很久以前,调用时传递引用(将引用传递给不期望的函数的能力)已被弃用,因为一个不知道它正在处理引用的函数可能会"意外" '修改输入.将它带到另一个层次,如果该函数调用第二个函数,那本身就不期望引用...那么一切都会断开连接.它可能会起作用,但它不能保证,并且可能会破坏某些PHP版本.

这就是call_user_func()进来的地方.假设您将引用传递给它(并获得相关的调用时间传递引用警告).然后你的引用绑定到一个新变量 - call_user_func()自身的参数.然后,当调用目标函数时,其参数不会绑定到您期望的位置.它们根本不受原始参数的约束.它们与call_user_func()声明中的局部变量绑定.call_user_func_array()也要小心.将引用放在数组单元格中可能会有麻烦 - 因为PHP通过"copy-on-write"语义传递该数组,您无法确定数组是否会在您下面被修改,并且副本将无法获得脱离原始参考.

我见过的最有见地的解释(帮助我了解了参考文献)是对PHP"通过引用传递"手册的评论:

http://ca.php.net/manual/en/language.references.pass.php#99549

基本上逻辑是这样的.你会怎么写自己的版本call_user_func()? - 然后解释它如何打破引用,以及当你避免调用时传递引用时它如何失败.换句话说,调用函数的正确方法(指定值,让PHP从函数声明中决定是否传递值或引用)在你使用时不会起作用call_user_func()- 你要调用两个函数,第一个按值,第二个参考第一个中的值.

了解这一点,您将对PHP参考资料有更深入的了解(如果可以的话,还有更大的动力去指导).