💡 今日の3行まとめ
- 配列に値が含まれるか調べるときは、
foreachで回さずin_array()を使う - 第3引数を省略すると緩い比較(
==)になり、'001'と'1'が同じと判定される - 必ず第3引数に
true(またはstrict: true)を渡して型と値の両方を厳密に比較する
1. 今日のお題とゴール
有効なクーポンコードの配列 ['001', '002', '100'] に対して、入力されたコードが使えるかどうかを判定する処理を作ります。
- 文字列として完全一致する
'001'だけを「利用OK」と判定する - ゼロ埋めなしの
'1'や、数値型の100は「対象外」として弾く foreachループを使わず、in_array()の1行で判定する
// 期待する出力結果
'001' (string) => 利用OK
'1' (string) => 対象外
100 (int) => 対象外
2. ❌ やりがちなNGコード vs ⭕ コピペで動く正解コード
❌ やりがちなNGコードBefore
<?php
$validCodes = ['001', '002', '100'];
// ❌ 第3引数を省略すると「==(緩い比較)」になる
var_dump(in_array('1', $validCodes)); // bool(true) ← '001' と一致してしまう!
var_dump(in_array(100, $validCodes)); // bool(true) ← int型の 100 も通ってしまう!
in_array() の第3引数を省略すると、緩い比較(==)で判定されます。そのため、ゼロ埋めなしの '1' や数値型の 100 まで一致とみなされてしまいます。
⭕ コピペで動く正解コード(PHP 8.3+)After
<?php
declare(strict_types=1);
$validCodes = ['001', '002', '100'];
$inputs = [
'001', // 文字列の '001'(完全一致)
'1', // ゼロ埋めなしの文字列
100, // 数値型(int)の 100
];
foreach ($inputs as $input) {
// 第3引数に true(strict: true)を渡すと「===」と同じ厳密比較になる
$isAllowed = in_array($input, $validCodes, strict: true);
$label = var_export($input, true);
$type = get_debug_type($input);
$status = $isAllowed ? '利用OK' : '対象外';
echo "{$label} ({$type}) => {$status}\n";
}
3. ここだけ押さえる!3つのポイント
1第3引数
true で ===(厳密比較)に切り替わる第3引数に true を渡すと、型と値の両方が一致したときだけ true を返します。PHP 8以降なら名前付き引数で strict: true と書くと意図が明確になります。
2ゼロ埋め文字列(
'001')の比較トラブルを防げる緩い比較(==)では、数字だけの文字列同士は数値として比べられるため '001' == '1' が true になります。先頭の 0 に意味があるコードやIDでは厳密比較が必須です。
3値ではなく「キー」を調べるなら
array_key_exists()in_array() は配列の「値」を探す関数です。連想配列の「キー(添字)」が存在するか調べたいときは、isset($array['key']) や array_key_exists('key', $array) を使います。
4. 1分ミニチャレンジ
🚀 手を動かしてみよう
正解コードの $inputs に真偽値の true を追加し、in_array() の strict: true を strict: false に変えるとどうなるでしょうか?(ヒント:緩い比較では '001' == true も一致と判定されてしまいます)