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値の位置(インデックス)を知りたいです。
A
array_search($value, $array, true) を使います。見つかればキーを、見つからなければ false を返します。戻り値は !== false で判定してください(キー0と false を区別するため)。Qキーが存在するかを確認したいです。
A
in_array() は値を探す関数です。キーの確認にはarray_key_exists($key, $array) または isset($array[$key]) を使います。値が null のキーも検出したい場合は array_key_exists() が確実です。Q大きな配列で検索が遅いです。
A
in_array() は線形探索のため、繰り返し検索すると遅くなります。array_flip() で値をキーに変換し、isset() で確認すると高速になります。まとめ
in_arrayのポイントを整理します。
- 存在確認は
in_array($value, $array)。第3引数true(厳密比較)を基本に - 緩い比較は
in_array(0, ["apple"])のような誤判定を招く - 位置(キー)が欲しいなら
array_search(戻り値は!== falseで判定) - キーの存在は
array_key_exists/isset - 大量検索は
array_flip+issetで高速化
関連として、配列のキーが存在するか確認する方法・配列のキーを取得する方法・配列の要素数をカウントする方法もあわせて読むと、PHPの配列操作に強くなれます。
