PHP

「!== false」 V.S. 「false !==」


導入


PHP Manual - array_search

配列から探したい値に対応するキーを取ってくる関数です。見つからなかった場合には FALSE が返されます。この記事の内容には直接関係ないですが、この関数にはいろいろ落とし穴があるので注意してください。


  • 結果の比較には === !== を使わなければならない

  • 第3引数 $strictTRUE にすることが推奨される

さて、これを例として問題を提起します。

/* 問題 */

echo "ランダムに選出したアルファベットはH~Nの中に含まれているか?\n";
echo "またそのアルファベットは(Hから数えて)何番目のアルファベットか?\n";
echo "\n";

/* 変数の準備 */
$range = range('H', 'N'); // 限定する範囲
$all = range('A', 'Z'); // 全範囲
$rand = $all[array_rand($all)]; // ランダムに選出されたアルファベット

/* 判定と表示 */
$pos = array_search($rand, $range, true);
if ($pos !== false) {
printf("アルファベット[%s]は[%d]番目にありました\n", $rand, $pos);
} else {
printf("アルファベット[%s]は見つかりませんでした\n", $rand);
}

この場面において

$pos = array_search($rand, $range, true);

if ($pos !== false) { }

を1つにまとめたいとき、あなたならどう書きますか・・・?


考察


!== false を用いたとき

以下のコードは正しく動作しません。

if ($pos = array_search($rand, $range, true) !== false) { }

何故ならば =より!==の方が優先度が高いことにより、array_search関数の返り値と FALSE を比較した結果が $pos に代入されてしまうからです。この書き方をしたい場合には

if (($pos = array_search($rand, $range, true)) !== false) { }

として明示的に評価の順番を変更する必要があります。


false !== を用いたとき

if (false !== $pos = array_search($rand, $range, true)) { }

if (false !== ($pos = array_search($rand, $range, true))) { }

実はコレ、どっちでも動いちゃうんです。


( ) が省略できる理由

異なる順番で評価されれば、それが代入式として無効なものとなるのが理由です。代入式は必ず $変数 = 値; という形である必要がありますが、false !== $pos が先に評価されてしまった場合、次に評価される代入式は 値 = 値; という形になってしまいます。そこでPHPがこのようなものは例外として考えて、順番を自動的に最適化してくれているのです。


他の例

他によく見る例として、 下記のような ! 演算子でのケースが考えられるでしょうか。これも同様の省略を行うことが出来ます。

$str = (string)filter_input(INPUT_GET, 'str');

if (!$len = strlen($str)) {
echo "入力された文字列は{$len}バイトです";
} else {
echo "文字列が入力されていません";
}