PHPの「==」で文字列と数値を比較する時の注意点

PHPで値の比較を行う場合、「==」と「===」のどちらを使用していますか?

「==」で文字列と数値を比較する場合は、仕様をしっかり理解した上で使用しないと、思わぬバグを引き起こしたり、セキュリティホールの原因となる可能性もあります。

今回は比較演算子「==」と「===」についての注意点をまとめました。

比較演算子「==」と「===」の違い

「==」と「===」の違いについて。

PHP公式マニュアルでは、

  • 「===」 厳密な比較
  • 「==」 緩やかな比較

と表現しています。

「===」は値と型が一致している場合のみtrueを返す

説明の都合上、先に「===」による厳密な比較について解説します。

「===」の厳密な比較は、比較した値同士が同じ値かつ、同じ型である場合のみtrueであると返します。

例えば、数字の1と、クオーテーションで囲われた’1’を比較した場合、数値型と文字型の比較のため、falseとなります。

サンプルコード
//緩やかな比較
if(1 == '1'){
    echo 'true'."<br>";
}else{
    echo 'false'."<br>";
}

//厳密な比較
if(1 === '1'){
    echo 'true'."<br>";
}else{
    echo 'false'."<br>";
}
true
false

「==」は、型の相互変換を行った後に比較を行う

下記の例は、PHP8で数値型文字列の定義が変更されたため、PHP7以前の仕様になります。

「==」は、「===」の型の比較を行わない版、と誤解されている方が多いですが、実際は違います。

型の比較を行わないというだけなら、以下の比較がtrueになってしまう説明が付きません。

サンプルコード
if(10 == '10円'){
    echo 'true';
}else{
    echo 'false';
}
true

何故、10と’10円’がイコールになってしまうのか。

「==」の比較は、どちらかの値に数値が含まれている場合は、文字列は数値に変換して比較を行うからです。

なので、この場合「文字列の’10円’」は、「数値の10」に変換を行った上で比較します。

その結果、比較は「10 == 10」となりtrueを返します。

文字列を数値に変換を行う時の法則

文字列が数値に変換される時、どのような数値に変換されるのか、一例をまとめてみました。

文字列を数値に変換(キャスト)する(int)を使用し、各文字列がどのような数値となっているか確認してみてください。

サンプルコード
echo (int)'10円'."<br>";
echo (int)'500円'."<br>";
echo (int)'この商品は10円です'."<br>";
echo (int)'hoge'."<br>";
echo (int)''."<br>";
10
500
0
0
0

簡単にまとめると、

「文字の先頭に数値がある場合は数値列に変換、それ以外は0」

という変換を行います。

なので、0と先頭が数値でない文字列を比較した場合、必ずtrueになる結果になります。

サンプルコード
if(0 == ''){
    echo 'true'."<br>";
}else{
    echo 'false'."<br>";
}

if(0 == 'hoge'){
    echo 'true'."<br>";
}else{
    echo 'false'."<br>";
}
true
true

このように、「==」の比較には、意図していないtrueを返してしまう恐れがあります。

型は違うけど同じ値の時に処理を行いたい場合

型は違っていても、値が同じ場合はしっかり分岐させたい。
でも「10 == ’10円’」がtrueになる、「==」の曖昧な比較は使いたくない。

という場合に使用できる処理を2つまとめました。

1.値を文字列型に変換(キャスト)する

比較の際に数値を文字列に変換を行うことで、文字列と文字列の比較になるため、PHPによる自動変換を介さず値同士で比較ができます。

変数の前に(string)を付けることで文字列に変換されます。

サンプルコード
$a = '10';
$b = 10;

if((string)$a === (string)$b){
    echo 'true';
}else{
    echo 'false';
}
true

2.文字列を比較するstrcmp関数を使う

2つの値を文字列として比較できるPHPの組み込み関数strcmp()を使用する方法もあります。

値が一致している場合は0を返すため、0と比較させることで条件分岐が可能です。

サンプルコード
$a = '10';
$b = 10;

if(strcmp($a, $b) === 0){
    echo 'true';
}else{
    echo 'false';
}
true

「==」と「===」の違いとその他の比較方法について解説しました。

PHPは、自動変換によって型を意識せずソースコードを書いても動くことが魅力の1つですが、同時に意図しない処理を通過させてしまう恐れもあります。

PHPの比較演算子の仕様をしっかり把握しておきましょう。

以上、PHPの「==」で文字列と数値を比較する時の注意点、でした。

PHP