PHPでは"0x0A"=="10"がtrue
2009年6月18日(木曜日)
PHPでは"0x0A"=="10"がtrue
公開: 2024年12月21日23時40分頃
「PHPの比較の素晴らしさ加減は正常 (anond.hatelabo.jp)」。
PHPでは"0x0A"=="10"がtrueになるのに、"0x0A" == "012"はfalseという話。無茶な話だなぁと思いつつも、実はマニュアルを見るとちゃんと書かれていたりするのですよね。
整数値を文字列と比較する際、文字列が 数値に変換されます。 数値形式の文字列を比較する場合、それは整数として比較されます。
以上、PHP: 比較演算子 - Manual より
というわけで、文字列比較時は「数値形式」の文字列どうしであれば数値に変換されて比較されることになっています。さらに、その変換についてはこんなふうにも書かれています。
この変換に関する詳細は、Unix のマニュアルページで strtod(3) を参照ください。
つまり、Cの標準ライブラリ関数であるstrtodを使って変換しているわけですね。man 3 strtodの内容を見るとこんな事になっています。
入力する文字列 (の先頭部分) は以下の形式が期待されている。先頭にホワイトスペース、次にプラス (aq+aq) またはマイナス (aq-aq) の記号、その後に (i) 10 進数、(ii) 16 進数、(iii) 無限、 (iv) NAN (計算できない数、not-a-number) のいずれかがある (ホワイトスペース、符号は省略可能。ホワイトスペースは isspace(3) で識別される)。
以上、Manpage of STRTOD より
なんで16進数に対応していて8進数には対応していないのかというと、単に「strtodがそういう挙動だから」。
というわけで理屈は分かりますが、嫌なバグの原因になりそうな挙動ではあります。事と次第ではセキュリティ系の問題につながりそうな気もしますね。それが嫌なら==ではなく===を使えということなのでしょうけれど……。
- 「PHPでは"0x0A"=="10"がtrue」へのコメント (4件)
- 前(古い): あずまんが大王 1年生 ゲット
- 次(新しい): iPhoneがICMP echoで死亡する脆弱性……が分かりにくい