PHP 5.4 调用时传递引用 - 可以轻松修复吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8971261/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PHP 5.4 Call-time pass-by-reference - Easy fix available?
提问by bardiir
Is there any way to easily fix this issue or do I really need to rewrite all the legacy code?
有什么方法可以轻松解决此问题,还是我真的需要重写所有遗留代码?
PHP Fatal error: Call-time pass-by-reference has been removed in ... on line 30
PHP 致命错误:调用时传递引用已在第 30 行中删除...
This happens everywhere as variables are passed into functions as references throughout the code.
当变量作为整个代码的引用传递给函数时,这种情况无处不在。
回答by Tim Cooper
You should be denoting the call by reference in the function definition, not the actual call. Since PHP started showing the deprecation errors in version 5.3, I would say it would be a good idea to rewrite the code.
您应该在函数定义中通过引用来表示调用,而不是实际调用。由于 PHP 在 5.3 版本中开始显示弃用错误,我认为重写代码是个好主意。
从文档:
There is no reference sign on a function call - only on function definitions.Function definitions alone are enough to correctly pass the argument by reference. As of PHP 5.3.0, you will get a warning saying that "call-time pass-by-reference" is deprecated when you use
&
infoo(&$a);
.
函数调用没有参考符号 - 仅在函数定义上。仅函数定义就足以通过引用正确传递参数。从 PHP 5.3.0 开始,当您使用
&
in时,您将收到一条警告,指出“调用时传递引用”已被弃用foo(&$a);
。
For example, instead of using:
例如,而不是使用:
// Wrong way!
myFunc(&$arg); # Deprecated pass-by-reference argument
function myFunc($arg) { }
Use:
用:
// Right way!
myFunc($var); # pass-by-value argument
function myFunc(&$arg) { }
回答by Pekka
For anyone who, like me, reads this because they need to update a giant legacy project to 5.6: as the answers here point out, there is no quick fix: you really do need to find each occurrence of the problem manually, and fix it.
对于像我一样阅读本文的人,因为他们需要将一个巨大的遗留项目更新到 5.6:正如这里的答案所指出的那样,没有快速解决方案:您确实需要手动查找每个出现的问题,并修复它.
The most convenient way I found to find all problematic lines in a project (short of using a full-blown static code analyzer, which is very accurate but I don't know any that take you to the correct position in the editor right away) was using Visual Studio Code, which has a nice PHP linter built in, and its search feature which allows searching by Regex. (Of course, you can use any IDE/Code editor for this that does PHP linting and Regex searches.)
我发现在项目中找到所有有问题的行的最方便的方法(没有使用成熟的静态代码分析器,它非常准确,但我不知道有什么可以立即将您带到编辑器中的正确位置)使用的是 Visual Studio Code,它内置了一个很好的 PHP linter,它的搜索功能允许通过 Regex 进行搜索。(当然,您可以使用任何 IDE/代码编辑器来执行 PHP linting 和 Regex 搜索。)
Using this regex:
使用这个正则表达式:
^(?!.*function).*(\&$)
it is possible to search project-wide for the occurrence of &$
only in lines that are not a function definition.
可以在项目范围内搜索&$
仅在不是函数定义的行中出现的情况。
This still turns up a lot of false positives, but it does make the job easier.
这仍然会产生很多误报,但它确实使工作更容易。
VSCode's search results browser makes walking through and finding the offending lines super easy: you just click through each result, and look out for those that the linter underlines red. Those you need to fix.
VSCode 的搜索结果浏览器让您可以非常轻松地浏览和查找违规行:您只需单击每个结果,然后查找那些被 linter 标出红色下划线的结果。那些你需要修复的。
回答by jgmjgm
PHP and references are somewhat unintuitive. If used appropriately references in the right places can provide large performance improvements or avoid very ugly workarounds and unusual code.
PHP 和引用有些不直观。如果在正确的地方适当地使用引用,可以提供很大的性能改进或避免非常丑陋的解决方法和不寻常的代码。
The following will produce an error:
以下将产生错误:
function f(&$v){$v = true;}
f(&$v);
function f($v){$v = true;}
f(&$v);
None of these have to fail as they could follow the rules below but have no doubt been removed or disabled to prevent a lot of legacy confusion.
这些都不会失败,因为它们可以遵循以下规则,但无疑已被删除或禁用以防止许多遗留问题。
If they did work, both involve a redundant conversion to reference and the second also involves a redundant conversion back to a scoped contained variable.
如果它们确实有效,则两者都涉及到引用的冗余转换,而第二个还涉及到有作用域的包含变量的冗余转换。
The second one used to be possible allowing a reference to be passed to code that wasn't intended to work with references. This is extremely ugly for maintainability.
第二个曾经允许将引用传递给不打算使用引用的代码。这对于可维护性来说非常难看。
This will do nothing:
这不会做任何事情:
function f($v){$v = true;}
$r = &$v;
f($r);
More specifically, it turns the reference back into a normal variable as you have not asked for a reference.
更具体地说,它将引用转换回正常变量,因为您没有要求引用。
This will work:
这将起作用:
function f(&$v){$v = true;}
f($v);
This sees that you are passing a non-reference but want a reference so turns it into a reference.
这表明您正在传递一个非引用但想要一个引用,因此将其转换为引用。
What this means is that you can't pass a reference to a function where a reference is not explicitly asked for making it one of the few areas where PHP is strict on passing types or in this case more of a meta type.
这意味着您不能传递对函数的引用,其中没有明确要求引用使其成为 PHP 对传递类型或在这种情况下更多是元类型的少数几个区域之一。
If you need more dynamic behaviour this will work:
如果您需要更多动态行为,这将起作用:
function f(&$v){$v = true;}
$v = array(false,false,false);
$r = &$v[1];
f($r);
Here it sees that you want a reference and already have a reference so leaves it alone. It may also chain the reference but I doubt this.
在这里它看到您想要一个参考并且已经有了一个参考,所以不要管它。它也可能链接参考,但我对此表示怀疑。