PHP 5.4调用时间传递参考-简单修复可用


PHP 5.4 Call-time pass-by-reference - Easy fix available?

有什么方法可以轻松解决这个问题吗?或者我真的需要重写所有遗留代码吗?

PHP致命错误:调用时间传递引用已在中删除。。。在线30

当变量在整个代码中作为引用传递到函数中时,这种情况随处可见。

您应该在函数定义中通过引用来表示调用,而不是实际调用。由于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) { }

对于像我这样因为需要将一个巨大的遗留项目更新到5.6而阅读本文的人来说:正如这里的答案所指出的,没有快速的解决方法:你确实需要手动找到每次出现的问题,并将其修复。

我发现在一个项目中找到所有有问题的行的最方便的方法(除了使用全面的静态代码分析器之外,它非常准确,但我不知道有什么能让你立即在编辑器中找到正确的位置)是使用Visual Studio code,它内置了一个漂亮的PHP linter,它的搜索功能允许Regex进行搜索。(当然,您可以使用任何IDE/Code编辑器进行PHP linting和Regex搜索。)

使用此正则表达式:

^(?!.*function).*('&'$)

可以在项目范围内搜索仅在不是函数定义的行中出现的CCD_ 3。

这仍然会出现很多误报,但它确实让工作变得更容易。

VSCode的搜索结果浏览器使浏览和查找有问题的行变得非常容易:你只需点击每个结果,并注意那些门楣下划线为红色的行。那些你需要修复的行。

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);

在这里,它看到你想要一个引用,并且已经有了引用,所以就不用管它了。它也可能链接引用,但我对此表示怀疑。