PHP 5.4调用时传递引用-可以轻松修复吗?


219

有什么方法可以轻松解决此问题,或者我真的需要重写所有旧代码吗?

PHP致命错误:第30行的...中的调用时传递引用已被删除

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


Answers:


344

您应该在函数定义中通过引用表示调用,而不是实际调用。由于PHP在5.3版中开始显示弃用错误,因此我想重写代码是一个好主意。

从文档中

函数调用上没有参考符号-仅在函数定义上。仅函数定义就足以正确地通过引用传递参数。从PHP 5.3.0开始,您将收到一条警告,指出&在in中使用时,“调用时传递引用”已被弃用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) { }

9
弃用是因为PHP 5.0.0,回到那个时候给E_COMPILE_WARNING级别的错误,以供参考:php.net/manual/en/...
hakre

5
我遇到了这个错误,但需要删除添加到变量中的&insted。
戴安娜(Diana)

2
我在旧代码中使用了一个用于事件(&$ event)的对象,并且必须删除与号以使错误消息消失。
Natalia

1
在作为开发人员的所有这些年中,我实际上从未需要在php上使用&。永远不能。这正是我想要的。太棒了
Juan Vilar 2014年

8
对于注释中的人,请注意,删除&可能会导致意外结果,因为对变量的任何更改将不再共享,而仅对函数本地作用域可见。因此,除非您知道代码的功能,否则建议您如上所述修复它,而不仅仅是删除&字符
xorinzor

8

对于像我一样阅读此书的人,是因为他们需要将一个庞大的旧项目更新为5.6:正如此处的答案所指出的,没有快速解决方案:您确实需要手动查找每个问题的出现并进行修复。 。

我找到了找到项目中所有有问题的行的最便捷方法(没有使用成熟的静态代码分析器,这非常准确,但是我不知道有什么可以立即将您带到编辑器中的正确位置)使用的是Visual Studio Code,它内置了不错的PHP linter,其搜索功能允许使用Regex进行搜索。(当然,您可以为此使用任何IDE /代码编辑器来执行PHP linting和Regex搜索。)

使用此正则表达式:

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

有可能在项目范围内搜索是否发生 &$仅在不是函数定义的行中。

这仍然会带来很多误报,但确实会使工作变得更容易。

VSCode的搜索结果浏览器使遍历和查找有问题的行变得非常容易:您只需单击每个结果,然后查找棉绒底线标为红色的行。您需要修复的那些。


1
这就是我想要的!
桑尼

4
我用于此目的的更精确的正则表达式:(?<!function)[:> ][a-zA-Z0-9_]+(?<!foreach|array)\s?\([^()]*&\$
Mojo

只需使用phpcs,就会为您挖掘出具有此功能的每个文件。
托马斯程

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

在这里可以看到您想要一个参考,并且已经有了一个参考,因此不再赘述。它也可能链接参考,但我对此表示怀疑。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.