北海道のとある企業で働くエンジニアのブログ

北海道でエンジニアとして働いています。技術的なことや感じたことを書きます。最近はブロックチェーンにハマってます。

PHPで文字列比較

PHPで文字列比較を行う際、注意しないとハマることになりそうな点のメモ。

結論から

文字列比較を厳密に行いたい場合は、何はともあれ「===」を使用すること!
(もしくはstrcmp())

検証

検証環境

PHP 5.5.9 (cli) (built: Feb 5 2014 13:02:39)

大文字と小文字の区別

これはイメージ通り。== も === も変わらず、きちんと区別してくれる。
逆に、区別したくない場合は大文字/小文字のどちらかに変換してから比較するか、 strcasecmp() を使う。

結果
"aaa" == "aaa" true
"aaa" === "aaa" true
strcmp("aaa", "aaa") 0
"aaa" == "AAA" false
"aaa" === "AAA" false
strcmp("aaa", "AAA") 1
strcasecmp("aaa", "AAA") 0

数値と文字列の確認

これは注意が必要。== だと数値と文字列の比較で「うまいこと」解釈してくれるおかげで、「"1.0"と1が等しい」と判定される。

結果
"1" == 1 true
"1" === 1 false
strcmp("1", 1) 0
"1.0" == 1 true
"1.0" === 1 false
strcmp("1.0", 1) 2

数字文字列と数字文字列の確認

これにも注意が必要。== は柔軟なのでなんと「"1"と"1.0"が等しい」と判定される。

結果
"1" == "1" true
"1" === "1" true
strcmp("1", "1") 0
"1.0" == "1" true
"1.0" === "1" false
strcmp("1.0", "1") 2

検証したソースコード

今回検証したソースコードはこんな感じ↓

echo '■大文字/小文字区別の確認 ―――――';
echo '"aaa" == "aaa": '.(("aaa" == "aaa") ? 'true' : 'false');
echo '"aaa" === "aaa": '.(("aaa" == "aaa") ? 'true' : 'false');
echo 'strcmp("aaa", "aaa"): '.strcmp("aaa", "aaa");
echo '"aaa" == "AAA": '.(("aaa" == "AAA") ? 'true' : 'false');
echo '"aaa" === "AAA": '.(("aaa" === "AAA") ? 'true' : 'false');
echo 'strcmp("aaa", "AAA"): '.strcmp("aaa", "AAA");
echo 'strcasecmp("aaa", "AAA"): '.strcasecmp("aaa", "AAA");

echo '■数値と文字列の確認 ―――――';
echo '"1" == 1: '.(("1" == 1) ? 'true' : 'false');
echo '"1" === 1: '.(("1" === 1) ? 'true' : 'false');
echo 'strcmp("1", 1): '.strcmp("1", 1);
echo '"1.0" == 1: '.(("1.0" == 1) ? 'true' : 'false');
echo '"1.0" === 1: '.(("1.0" === 1) ? 'true' : 'false');
echo 'strcmp("1.0", 1): '.strcmp("1.0", 1);

echo '■数字文字列と数字文字列の確認 ―――――';
echo '"1" == "1": '.(("1" == "1") ? 'true' : 'false');
echo '"1" === "1": '.(("1" === "1") ? 'true' : 'false');
echo 'strcmp("1", "1"): '.strcmp("1", "1");
echo '"1.0" == "1": '.(("1.0" == "1") ? 'true' : 'false');
echo '"1.0" === "1": '.(("1.0" === "1") ? 'true' : 'false');
echo 'strcmp("1.0", "1"): '.strcmp("1.0", "1");