有没有办法轻松解决这个问题,还是我真的需要重写所有遗留代码?
PHP致命错误:第30行的......已删除了呼叫时间传递引用
这种情况随处可见,因为变量作为整个代码中的引用传递给函数。
答案 0 :(得分:335)
您应该在函数定义中通过引用表示调用,而不是实际调用。由于PHP开始在5.3版本中显示弃用错误,我想说重写代码是个好主意。
函数调用上没有引用符号 - 仅在函数定义上。单独的函数定义足以通过引用正确传递参数。从PHP 5.3.0开始,当您在
&
中使用foo(&$a);
时,系统会收到一条警告,指出“调用时间传递参考”已被弃用。
例如,而不是使用:
// Wrong way!
myFunc(&$arg); # Deprecated pass-by-reference argument
function myFunc($arg) { }
使用:
// Right way!
myFunc($var); # pass-by-value argument
function myFunc(&$arg) { }
答案 1 :(得分:7)
对于像我这样的人来说这是因为他们需要将一个巨大的遗留项目更新到5.6:正如这里的答案所指出的那样,没有快速修复:你真的需要手动找到每一个问题,并修复它。
我发现在项目中找到所有有问题的线条的最方便的方法(没有使用完整的静态代码分析器,这是非常准确但我不知道任何将你带到正确的位置编辑器正在使用Visual Studio Code,它内置了一个很好的PHP linter,它的搜索功能允许Regex搜索。 (当然,您可以使用任何IDE /代码编辑器进行PHP linting和Regex搜索。)
使用此正则表达式:
^(?!.*function).*(\&\$)
可以仅在不是函数定义的行中在项目范围内搜索&$
的出现。
这仍然会导致许多误报,但它确实使工作变得更容易。
VSCode的搜索结果浏览器可以让您轻松查找违规行:您只需点击每个结果,然后查看linter下划线为红色的那些结果。那些你需要解决的问题。
答案 2 :(得分:6)
PHP和引用有点不直观。如果使用得当,在适当的位置引用可以提供大的性能改进或避免非常丑陋的变通方法和不寻常的代码。
以下内容会产生错误:
function f(&$v){$v = true;}
f(&$v);
function f($v){$v = true;}
f(&$v);
这些都不会失败,因为他们可以遵循以下规则,但毫无疑问已被删除或禁用,以防止许多遗留混乱。
如果它们确实有效,则两者都涉及冗余转换为引用,第二种也涉及冗余转换回带范围的变量。
第二个过去可能允许将引用传递给不适用于引用的代码。这对于可维护性来说非常难看。
这无济于事:
function f($v){$v = true;}
$r = &$v;
f($r);
更具体地说,它会将引用转回正常变量,因为您没有要求引用。
这将有效:
function f(&$v){$v = true;}
f($v);
这会看到您传递的是非引用但需要引用,因此将其转换为引用。
这意味着您无法将引用传递给未明确要求引用的函数,使其成为PHP严格传递类型的少数区域之一,或者在这种情况下更多是元类型。
如果您需要更多动态行为,这将有效:
function f(&$v){$v = true;}
$v = array(false,false,false);
$r = &$v[1];
f($r);
这里它看到你想要一个引用并且已经有一个引用,所以不管它。它也可能链接参考,但我对此表示怀疑。