導入
PHP Manual - array_search
配列から探したい値に対応するキーを取ってくる関数です。見つからなかった場合には FALSE が返されます。この記事の内容には直接関係ないですが、この関数にはいろいろ落とし穴があるので注意してください。
- 結果の比較には
===
!==
を使わなければならない - 第3引数
$strict
は TRUE にすることが推奨される
さて、これを例として問題を提起します。
/* 問題 */
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 "文字列が入力されていません";
}