【PHP】in_arrayで配列内の値を確認する方法|strict比較の罠とarray_search

PHPで「配列に特定の値が含まれているか」を確認するには in_array() を使います。手軽な関数ですが、デフォルトの緩い比較のせいでin_array(0, ["apple"]) が意図せず true になるなどの落とし穴があります。この記事では安全な使い方(厳密比較)と、関連する関数との使い分けを解説します。

この記事の結論:in_array($value, $array) で存在確認できますが、第3引数に true(厳密比較)を付けるのが安全です。値の位置(キー)が欲しいなら array_search()キーの存在を見たいなら array_key_exists() を使います。
スポンサーリンク

in_arrayの基本的な使い方

第1引数に探す値、第2引数に配列を渡します。含まれていれば true を返します。

基本の存在確認
<?php
$fruits = ["apple", "banana", "cherry"];

if (in_array("banana", $fruits)) {
    echo "バナナは存在します";
} else {
    echo "バナナは存在しません";
}

注意:デフォルトは「緩い比較」で誤判定する

in_array() はデフォルトで型を区別しない緩い比較(==を行います。このため、数値の 0 を文字列の配列で探すと意図せずヒットすることがあります。

危険な緩い比較
<?php
$fruits = ["apple", "banana"];

var_dump(in_array(0, $fruits));        // PHP 7 では true(0 == "apple" が成立)
var_dump(in_array(0, $fruits, true));  // false(厳密比較なら正しく不在)
第3引数に true(厳密比較)を付けるのを基本にしましょう。デフォルトの緩い比較は、ユーザー入力や数値・文字列が混在する配列で意図しない一致を招き、バグやセキュリティ問題の原因になります。なおPHP 8.0で文字列と数値の比較ルールが変わり 0 == "apple" は false になりましたが、型を区別したいなら常に true を指定するのが確実です。
OK: 厳密比較を基本にする
<?php
$numbers = [1, 2, 3];

var_dump(in_array("2", $numbers));        // true("2" == 2、意図とずれることがある)
var_dump(in_array("2", $numbers, true));  // false(文字列"2"と数値2は別物)

値の位置(キー)が欲しいときはarray_search

「存在するか」だけでなく「どの位置にあるか」を知りたいときは array_search() を使います。見つかればキー(インデックス)を、見つからなければ false を返します。こちらも第3引数で厳密比較を指定できます。

array_searchで位置を取得
<?php
$fruits = ["apple", "banana", "cherry"];

$key = array_search("banana", $fruits, true);
var_dump($key); // int(1)

// 戻り値の判定は型に注意(キー0と false を区別)
if ($key !== false) {
    echo "位置: {$key}";
}
array_search() の戻り値は必ず !==false と比較してください。先頭(キー0)で見つかった場合、if ($key) だと 0 が偽と扱われ「見つからなかった」と誤判定します。

「キー」の存在を確認したいときは別の関数

混同しやすいですが、in_array()を探します。連想配列でキーが存在するかを確認したいときはarray_key_exists()isset() を使います。

値の確認 vs キーの確認
<?php
$user = ["name" => "佐藤", "age" => 30];

// 値を探す
var_dump(in_array("佐藤", $user));          // true

// キーを探す
var_dump(array_key_exists("name", $user));  // true
var_dump(isset($user["name"]));             // true(値がnullだとfalseになる点に注意)
キーの存在確認の詳細は配列のキーが存在するかどうか確認する方法、キーの一覧取得は配列のキーを取得する方法を参照してください。

大量の検索を繰り返す場合の高速化

in_array() は配列を先頭から順に調べるため、要素数が多い配列で何度も検索すると遅くなります。同じ配列に対して繰り返し存在確認するなら、array_flip() で値をキーにした配列を作り isset() で調べると高速です。

array_flip + isset で高速化
<?php
$list = ["apple", "banana", "cherry", /* ...大量... */];
$set = array_flip($list); // 値をキーにする

// 以降の存在確認は高速(ハッシュ参照)
if (isset($set["banana"])) {
    echo "存在します";
}

よくある質問(FAQ)

Qin_arrayは第3引数を付けるべきですか?
A付けるのを基本にしましょう(true=厳密比較)。デフォルトの緩い比較は型を区別せず、in_array(0, ["apple"]) のような意図しない一致を招きます。
Q値の位置(インデックス)を知りたいです。
Aarray_search($value, $array, true) を使います。見つかればキーを、見つからなければ false を返します。戻り値は !== false で判定してください(キー0と false を区別するため)。
Qキーが存在するかを確認したいです。
Ain_array() は値を探す関数です。キーの確認にはarray_key_exists($key, $array) または isset($array[$key]) を使います。値が null のキーも検出したい場合は array_key_exists() が確実です。
Q大きな配列で検索が遅いです。
Ain_array() は線形探索のため、繰り返し検索すると遅くなります。array_flip() で値をキーに変換し、isset() で確認すると高速になります。

まとめ

in_arrayのポイントを整理します。

  • 存在確認は in_array($value, $array)第3引数 true(厳密比較)を基本に
  • 緩い比較は in_array(0, ["apple"]) のような誤判定を招く
  • 位置(キー)が欲しいなら array_search(戻り値は !== false で判定)
  • キーの存在は array_key_exists / isset
  • 大量検索は array_flipisset で高速化

関連として、配列のキーが存在するか確認する方法配列のキーを取得する方法配列の要素数をカウントする方法もあわせて読むと、PHPの配列操作に強くなれます。