2011-01-12 84 views
11

注册引用新的返回值分配新的返回值在PHP 5.3已经deprecated。因此,PHP 5.3,并通过引用

$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

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

+0

E_DEPRECATED属于通知类,而不是错误。我不确定你需要赶紧修复它(magic_quotes被声明在PHP 4.2左右)。至于正则表达式:你应该在`new`后面添加`\ b`,否则这是一种可行的重写方法。但是你只能测试它是否会损害预期的处理逻辑(尽管不太可能)。 – mario 2011-01-12 20:19:24

+0

@mario E_DEPRECATED只是一个错误*级别*。无论哪种方式提及它都是适当的。不过\ b好点。 – mfonda 2011-01-12 20:24:28

回答

14

你的感觉是对的。它通常会正常工作,但有边缘情况下没有。

使用=&有这些差异与=

  • =&将努力使右侧获得一个参考; =不会 - 即使右侧能够产生引用,就像通过引用返回的函数一样。
  • =&将打破旧的参考集,并将左侧和右侧都放入一个新的参考集中,而=会将同一参考集中与左侧相同的所有元素的值更改为右侧的值。

在这种情况下,第一个不同点和第二个不相关。赋值后,将只有一个变量具有新对象*的值,而单元素引用集是没有意义的。然而,事实是=&突破前期基准设定是显著:

<?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在构造函数中可能是一个不同的变量,即使它指向到同一个对象。所以我怀疑可以观察到由此导致的行为差异。

3

是的,你应该能够只是= new取代=& new。对象在PHP 5.3中默认通过引用传递,因此不会改变行为。

+1固定通知,而不是隐藏它们。

+0

+1(强制性的“引用值通过引用,而不是通过引用传递的对象”pedantry去这里。) – BoltClock 2011-01-12 20:19:04

+0

+1我学得很快。 – Ish 2011-01-12 20:20:01

2

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

理论上你就可以遇到的唯一问题是,有人在一个字符串中写道=& new。我知道,这是非常不可能的,但如果你只想取代'=' T_WHITESPACE? '&' T_WHITESPACE? T_NEW的所有发生,你应该使用Tokenizer