PHP

php-master-changes 2018-09-10

2018-09-10

bukka: Fix ssl stream reneg limit test to print only after first renegotiation

weltling: Skip test on unsuitable env

dstogov: Fixed wrong assertion

sgolemon: Enforce ordering of property compare in object comparisons

  • https://github.com/php/php-src/commit/a26a107aae3f202580e5dfba8ecf735a29c907d4
  • オブジェクト同士の比較の挙動を修正
  • PHP 5.4 以降で print_r() の利用後など、オブジェクトの内部的なプロパティ順が変更されるような副作用があり、比較結果に影響を与えていた
    • https://3v4l.org/2figq こんなのあったんかとびっくり、print_r() でなく foreach で順繰りに要素アクセスしたり array キャストしても同じことが起きる
    • PHP5.4 以降、オブジェクトへのある形でのアクセス時(ハッシュテーブルを順繰りにたぐるような操作?)、内部で持ってるプロパティの C 配列が初期化されて、この並び順はオブジェクト間で共有されず、しかしオブジェクト同士の比較にはその配列が使われてた、みたいな奴かな? 修正はクラスエントリのデータ順で各オブジェクトのプロパティを引いて回るようにして一貫性を確保。時間の問題であまり見れてないので別途確認して追記(以下は追記分)
  • internals で 1 ヶ月ほど前に議論があった
  • 元は Because, PHP で出てきたネタ
  • オブジェクト同士の大小比較の挙動はマニュアルないが、php-langspec にはある程度記述がある
  • 同じクラスのオブジェクト同士で特に既定の挙動がなければ配列の比較に準ずる
  • 配列同士のの比較は左辺のキーを順繰りに見て、最初の異なる値を見つけたら比較を抜ける、という挙動
  • ただしこのケースでオブジェクトのプロパティを順繰りにたどる順序は、厳密には規定がない
    • オブジェクトから配列へのキャストについてはプロパティの宣言順に詰められるという規定がある
    • が、このケースも継承で親から引き継いだ場合などのプロパティの順については規定がない
  • 未定義の挙動は未定義の挙動としても、再現性は必要で、read-only なアクセスで変わるのはまずいですね、というので修正(動作の機序についてはまた別途追記)