水無月ばけらのえび日記

bakera.jp > 水無月ばけらのえび日記 > PHPでは"0x0A"=="10"がtrue

PHPでは"0x0A"=="10"がtrue

2009年6月18日(木曜日)

PHPでは"0x0A"=="10"がtrue

公開: 2024年5月9日23時40分頃

PHPの比較の素晴らしさ加減は正常 (anond.hatelabo.jp)」。

PHPでは"0x0A"=="10"がtrueになるのに、"0x0A" == "012"はfalseという話。無茶な話だなぁと思いつつも、実はマニュアルを見るとちゃんと書かれていたりするのですよね。

整数値を文字列と比較する際、文字列が 数値に変換されます。 数値形式の文字列を比較する場合、それは整数として比較されます。

以上、PHP: 比較演算子 - Manual より

というわけで、文字列比較時は「数値形式」の文字列どうしであれば数値に変換されて比較されることになっています。さらに、その変換についてはこんなふうにも書かれています。

この変換に関する詳細は、Unix のマニュアルページで strtod(3) を参照ください。

以上、PHP: 文字列 - Manual 文字列の数値への変換 より

つまり、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 / プログラミング / セキュリティ

最近の日記

関わった本など