【问题标题】:PHP 5.3 and assigning the return value of new by referencePHP 5.3 并通过引用分配 new 的返回值
【发布时间】:2011-06-08 02:11:55
【问题描述】:

在 PHP 5.3 中通过引用分配 new 的返回值是 deprecated。因此,

$obj =& new Foo();

现在抛出 E_DEPRECATED 错误。

将包含大量遗留代码的大型应用程序升级到 5.3 时,会导致很多不需要的通知。

作为解决此问题的一个潜在方法,我正在考虑使用正则表达式来查找 =& new 的所有实例并将其替换为 = new。例如,以下将查找所有 PHP 文件,并清除所有 =& new 实例:

find ./ -name '*.php' | xargs perl -p -i -e 's/=(\s*)&(\s*)?new\b/= new/g'

寻找以下问题的答案:

  1. 它可以正常工作吗?我可能会遇到哪些潜在问题?
  2. 如果不是这样,将 =& new 替换为 = new 的代码示例将改变 PHP 5.3 中的行为。
  3. 已知任何带有此功能的流行库示例都会导致问题。
  4. 对于修复大量的=& new,您还有什么建议?

我怀疑这会正常工作,但要寻找可能遇到麻烦的边缘情况。是的,我知道我可以更改错误报告设置。但我不想隐藏通知,我想修复它们。

【问题讨论】:

  • E_DEPRECATED 属于通知类,而不是错误。我不确定您是否需要尽快修复它(magic_quotes 在 php 4.2 左右被宣布弃用)。至于正则表达式:您应该在new 之后添加\b,否则这是一种可行的重写方法。但是您只能测试它是否会损害预期的处理逻辑(虽然不太可能)。
  • @mario E_DEPRECATED 只是一个错误级别。无论哪种方式引用它都是合适的。 \b 很好。

标签: php


【解决方案1】:

你的感觉是对的。它通常可以正常工作,但在某些极端情况下它不会。

使用=&= 有这些区别:

  • =& 将尝试使右侧产生引用; = 不会——即使右侧能够产生引用,例如通过引用返回的函数。
  • =& 将打破旧的参考集并将左侧和右侧都放入一个新的参考集中,而= 会将与左侧相同的参考集中的所有元素的值更改为右侧的值一边。

在这种情况下,第一个差异和第二个差异的一半无关紧要。赋值后,新对象*的值将只有一个变量,单元素引用集没有意义。然而,=& 打破了之前的参考集这一事实意义重大:

<?php

$g = 4;
$v =& $g;
$v = new stdclass();
var_dump($g); // object(stdClass)#1 (0) { }

$g = 4;
$v =& $g;
$v =& new stdclass();
var_dump($g); // int(4)

* 除非构造函数可能泄漏了一个引用,但即使它泄漏了,构造函数内部的$this 也可能是不同的变量,即使它指向同一个对象。所以我怀疑人们是否会因此而观察到行为差异。

【讨论】:

  • +1 用于演示旧参考文献的破坏。但是打错了,应该是=&amp;,而不是&amp;=
  • 哇,好东西。从来没有想过它会有所作为。 +1
【解决方案2】:

是的,您应该可以将=&amp; new 替换为= new。对象在 PHP 5.3 中默认通过引用传递,因此不会改变任何行为。

+1 用于修复通知而不是隐藏通知。

【讨论】:

  • +1(这里是强制性的“按值传递的引用,而不是按引用传递的对象”。)
  • -1 错误且无关紧要。它们不可互换,没有人通过引用或值传递任何东西(构造函数参数除外)......
  • @Artefacto:它们不是可以互换的吗?在创建新对象时,通过引用或按值将其传递给变量应该没有区别。究竟什么是无关紧要的?
  • @Jonah 第一句是错误的(请参阅我的答案以了解它们导致不同结果的示例),第二句无关紧要,因为没有传递任何内容——它是一个赋值,而不是一个函数打电话。
  • 我明白了。显然我没有考虑过这种情况。但是我还是不太明白你说的第二句话是什么意思……
【解决方案3】:

应该没有问题。在最坏的情况下,这会稍微减慢您在 PHP 4 上的应用程序,但绝对不会改变功能。

理论上你可能遇到的唯一问题是有人在字符串中写了=&amp; new。我知道,这是极不可能的,但如果你只想替换所有出现的'=' T_WHITESPACE? '&amp;' T_WHITESPACE? T_NEW,你应该使用Tokenizer

【讨论】:

  • 当然,但这也许是件好事。如果有人在评论中有某些代码的“示例用法”,则正则表达式将修复示例用法。但我想如果这是一个不该做的例子,那就太糟糕了:-)
  • 它们不是一回事。虽然=&amp; new 出现在字符串中,但很好。
猜你喜欢
  • 2011-07-18
  • 1970-01-01
  • 2010-11-08
  • 1970-01-01
  • 2012-12-21
相关资源
最近更新 更多