是否有任何方法可以轻松地修复这个问题,或者我真的需要重写所有遗留代码?
PHP致命错误:调用时引用传递已被删除…第30行
在整个代码中将变量作为引用传递给函数时,这种情况随处可见。
是否有任何方法可以轻松地修复这个问题,或者我真的需要重写所有遗留代码?
PHP致命错误:调用时引用传递已被删除…第30行
在整个代码中将变量作为引用传递给函数时,这种情况随处可见。
当前回答
对于任何像我一样,因为需要将一个巨大的遗留项目更新到5.6而阅读这篇文章的人来说:正如这里的答案所指出的那样,没有快速解决方案:您确实需要手动找到每个问题的出现,并修复它。
我发现找到项目中所有有问题的行最方便的方法(不需要使用成熟的静态代码分析器,这是非常准确的,但我不知道是否可以立即将你带到编辑器中的正确位置)是使用Visual Studio code,它有一个很好的内置PHP linter,它的搜索功能允许通过Regex进行搜索。(当然,您可以使用任何IDE/代码编辑器来进行PHP检测和Regex搜索。)
使用这个正则表达式:
^(?!.*function).*(\&\$)
可以在项目范围内搜索&$,只在不是函数定义的行中出现。
这仍然会出现很多假阳性,但它确实使工作更容易。
VSCode的搜索结果浏览器让浏览和查找违规行变得超级简单:你只需要点击每个结果,然后寻找那些被linter强调为红色的行。那些你需要解决的问题。
其他回答
您应该在函数定义中通过引用来表示调用,而不是实际调用。由于PHP在5.3版开始显示弃用错误,我认为重写代码是个好主意。
从文档中可以看到:
函数调用上没有引用符号,只有函数定义上有引用符号。函数定义本身就足以通过引用正确地传递参数。从PHP 5.3.0开始,当你在foo(&$a);中使用&时,你会得到一个警告,说“调用时引用传递”已弃用。
例如,不要用:
// Wrong way!
myFunc(&$arg); # Deprecated pass-by-reference argument
function myFunc($arg) { }
Use:
// Right way!
myFunc($var); # pass-by-value argument
function myFunc(&$arg) { }
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);
在这里,它看到您想要一个引用,并且已经有一个引用,所以不要管它。它也可能链接引用,但我对此表示怀疑。
对于任何像我一样,因为需要将一个巨大的遗留项目更新到5.6而阅读这篇文章的人来说:正如这里的答案所指出的那样,没有快速解决方案:您确实需要手动找到每个问题的出现,并修复它。
我发现找到项目中所有有问题的行最方便的方法(不需要使用成熟的静态代码分析器,这是非常准确的,但我不知道是否可以立即将你带到编辑器中的正确位置)是使用Visual Studio code,它有一个很好的内置PHP linter,它的搜索功能允许通过Regex进行搜索。(当然,您可以使用任何IDE/代码编辑器来进行PHP检测和Regex搜索。)
使用这个正则表达式:
^(?!.*function).*(\&\$)
可以在项目范围内搜索&$,只在不是函数定义的行中出现。
这仍然会出现很多假阳性,但它确实使工作更容易。
VSCode的搜索结果浏览器让浏览和查找违规行变得超级简单:你只需要点击每个结果,然后寻找那些被linter强调为红色的行。那些你需要解决的问题。