2011-01-12 13 views
11

PHP 5.3ではnewの戻り値を参照で代入するのはdeprecatedでした。したがって、PHP 5.3でnewの戻り値を参照で代入

$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に置き換えると、PHP 5.3の動作が変更されます。
  3. これを使用する一般的なライブラリの例は、問題を引き起こすことが知られています。
  4. =& newの膨大な量を扱うために他にどのようなアイデアをお勧めしますか?

これはうまくいくと思われますが、問題が発生する可能性のあるエッジのケースを探しています。はい、私はちょうどエラー報告の設定を変更することができます知っています。しかし、私は通知を隠したくない、私はそれらを修正したい。

+0

E_DEPRECATEDは通知のクラスに属し、エラーはありません。私はあなたがそれを修正して急いでする必要があるか分からない(magic_quotesはphp 4.2で廃止されたと宣言されていた)。正規表現については、 'new 'の後ろに' \ b'を追加する必要があります。それ以外の場合は、実行可能な書き換えアプローチです。しかし、期待される処理ロジックが損なわれているかどうかだけをテストすることは可能です(ただし、そうは思わないでしょう)。 – mario

+0

@mario E_DEPRECATEDは単なるエラー*レベル*です。いずれにしてもそれを参照するのが適切でしょう。しかし、\ bとの良い点。 – mfonda

答えて

14

あなたの気持ちは正しいです。それは一般的にはうまくいくが、そうではない場合がある。 =&を使用して

=と、これらの違いがあります。

  • =&は右側が参照を得作るしようとします。 =は、たとえ右側が参照を返すことができても、参照によって返される関数のようにはなりません。
  • =&=&は、古い参照セットを破棄して左右両方を新しいものに入れますが、=は、左側と同じ参照セットのすべての要素の値を右側の値に変更します。

この場合、最初の差と2番目の差の半分は無関係です。代入の後、新しいオブジェクト*の値を持つ変数は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は、それが指していても、別の変数かもしれない限り、同じオブジェクトにだから私はこれに起因する行動の違いを観察することができないのではないかと思う。

+4

+1古い参照の破損を示すためです。しかし、タイプミスでは、 '=&'ではなく、 '&='でなければなりません。 – Jonah

+0

@Jonah固定、ありがとう! – Artefacto

+0

うわー、クールなもの。違いがあるとは決して考えなかったでしょう。 +1 – NikiC

3

はい、=& new= newに置き換えることができます。 PHP 5.3では、オブジェクトはデフォルトで参照渡しされるため、動作は変更されません。

+1修正通知を隠す代わりに+1します。

+0

+1(義務的な "参照は値渡しで、オブジェクトは参照渡しではありません" pedantryはここに行きます) – BoltClock

+0

+1私は早く学びます。 – Ish

+0

-1間違っていて無関係です。それらは交換可能ではなく、誰も参照や値によって何かを(コンストラクタの引数を除いて)渡していません... – Artefacto

2

問題はありません。最悪の場合、これはPHP 4のアプリケーションを少し遅くしますが、間違いなく機能を変更することはありません。

あなたが理論的に実行できる唯一の問題は、誰かが=& newを文字列に書いたことです。私は知っている、これは非常に可能性は低いですが、実際には'=' T_WHITESPACE? '&' T_WHITESPACE? T_NEWのすべての発生を置き換える場合は、Tokenizerを使用してください。

+0

確かに、それはいいことかもしれません。誰かがコメント内のコードの "使用例"を持っていた場合、正規表現はその使用例を修正します。しかし、どうしたらいいかの例があれば悪いと思う: – mfonda

+0

彼らは同じものではない。しかし、文字列に '=&new'が付いているのは良い点です。 – Artefacto

関連する問題