hnwの日記

PHPの==演算子と巨大な16進数


(2014/8/5 0:10追記)下記の結果は32bit環境でないと再現できませんが、64bit環境でも「"0x8000000000000000"」などで再現させることが可能です。


あけましておめでとうございます。


PHPの「==」演算子に関して、バージョン間で挙動が変わる例を紹介します。


僕は半年ほど前に「PHPでも巨大な16進数が書けるようになった」という記事を書きました。この16進数に関するPHPの機能拡張により、PHPの==演算子の挙動が変わっているのです。


具体的には、次のスクリプトの実行結果がPHP5.2.0以前とPHP5.2.1以降とで異なります。

<?php
  $x = "0x10000000000";
  $y = "1099511627776";
  var_dump($x==$y);
?>


これを実行すると、PHP5.2.0まではfalse、PHP5.2.1より先のバージョンではtrueとなります。PHP5.2.0以前は文字列比較をしているのに対し、PHP5.2.1以降は数値として比較するからです。


==演算子は両辺が文字列の場合、両方ともis_numericがtrueを返す場合のみ数値として比較します。上記スクリプトに関して言うと、$xがPHP5.2.0までは文字列扱いだったのに、PHP5.2.1からは数値文字列扱いになり、比較演算子の挙動が変わったということです。


本件の影響範囲という意味では、誰も影響は受けないだろうと思っています。この変更で影響を受けるプログラムを書く方が難しいんじゃないでしょうか。ただ、==のキモさが見え隠れする事件だとも感じます。


今年もこんな毒にも薬にもならないような豆知識を書いて行きたいと思います。