| ユーザフォーラムで議論/質問 | マニュアル検索 | ハイライト | ハイライトオフ | ポータル | php spot |
参照に関する処理の変更概要PHP スクリプトの開発者としての観点から見ると、 既存のコードに与える影響がもっとも大きいのは、 PHP 4.4.0 以降での参照に関する扱いの変更です。 PHP 4.3 を含むそれ以前のバージョンでは、本来は値を返すべき場所、 たとえば定数・一時的な値 (例: 式の結果)・値を返す関数の結果 などで参照を使用することが可能でした。以下がその例です。
<?php このコードは PHP 4.3 以下では通常通り動作しますが、一般的に結果は未定義となります。 Zend エンジンはこれらの値を参照として正しく扱えません。このバグにより、 再現不可能な問題が数多く発生していました。特に大規模なコードになるほどこの問題は深刻でした。
PHP 4.4.0、PHP 5.0.4 以降のリリースでは Zend エンジンが修正され、
参照を使用すべきでない場面で参照の操作が行われた場合はそれを「知る」
ことができるようになりました。今ではそのような場合には実際の値が使用されるようになり、
警告を発生するようになりました。この警告の形式は、
PHP 4.4.0 以降では これまでメモリ破壊を起こす可能性のあったコードは、もはやその心配はなくなりました。 しかし、既存のコードの中にはこれまでと挙動が変わってしまうものもあります。 PHP 4.3.x では動作するものの、現在は動作しないコード
<?php 参照に関する修正が行われる前の PHP で上のスクリプトを実行すると、このような結果になります。 array(3) { [0]=> &string(1) "a" [1]=> &string(1) "b" [2]=> &string(1) "c" } 修正後は、同じコードの結果が次のようになります。 array(3) { [0]=> &string(1) "c" [1]=> &string(1) "c" [2]=> &string(1) "c" } 理由は、今回の変更によって func() の結果が値として代入されるようになったことです。 $y の値は代入しなおされ、そして、$z では $y への参照が残り続けます。 この修正が行われる前は、func() の結果が参照として代入され、 先頭の $y は毎回代入されてしまっていました。 一時的な変数を参照で渡そうとすることが、メモリ破壊の原因となっていました。 修正前のバージョンの PHP と修正後のバージョンの PHP とで、 このようなコードの挙動を同じにすることは可能です。 func() の定義を変更して参照を返すようにするか、あるいは func() が返す結果を参照として代入する処理を取り除けばよいのです。
<?php PHP 4.3 では $x は 'もとの値' となりますが、 この変更以降のバージョンでは '関数の返す値' となります。関数は参照を返さず、 値が直接代入されることを覚えておきましょう。もう一度いいます。 このような挙動の違いをなくすには、func() が参照を返すようにするか、 関数の返す値を直接参照として代入することをやめるかのどちらかを行います。 PHP 4.3.x では動作するものの、現在はエラーとなるコード
<?php
PHP 5.0.3 では、$bar はオブジェクトを返さずに
PHP 4.3.x では動作しなかったが、現在は動作するコード
<?php
PHP 4.3 では var_dump() を 3 度目にコールした際に
<?php PHP 5.0.5 より前のバージョンでは、 このようにして配列の要素に参照を代入することができませんでした。 現在はできるようになっています。 本来は PHP 5.0.x で正常に動作すべきだったコード
参照関連の修正が行われるより前の PHP 5.0 ではいくつかのバグが報告されていましたが、
それらは今では正常に「動作します」。しかし、いずれの場合についても PHP 5.1.x
ではエラーがスローされます。なぜなら、まず第一にそのコードが不正なものだからです。
現在では self::
を使用して値を参照で返すことができるようになりましたが、
現れて、そしていなくなった警告
参照を返す関数をネストしてコールすることは、PHP 4.3.x および PHP 5.1.x
のどちらでも有効です。しかし、それらの間のバージョンの PHP では、
<?php |
各種マニュアル:
PHPマニュアル |
PEARマニュアル |
Smarty(英語)マニュアル |
PHP-GTKマニュアル |
「参照に関する処理の変更」をGoogle検索
|