💡 今日の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 も一致と判定されてしまいます)