2011-01-12 80 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