PHPでプログラムを開発する際、配列の中に特定のデータが含まれているかを確認する場面は非常に頻繁にあります。
その際に最も汎用的に利用されるのがin_array関数ですが、使い方を誤ると予期せぬバグの原因になることも少なくありません。
本記事では、in_array関数の基本的な使い方から、実務で重要となる型比較の注意点、さらにはパフォーマンス面での考慮事項までを詳しく解説します。
PHP 8系以降のモダンな開発環境においても必須となる知識を整理していきましょう。
PHPのin_array関数とは
PHPのin_array関数は、配列の中に指定した値が存在するかどうかを検索し、その結果を真偽値(論理型)で返す関数です。
検索対象となる配列に値が見つかればtrueを、見つからなければfalseを返します。
この関数は、条件分岐(if文)と組み合わせて、特定の要素がある場合のみ処理を実行するといったフローで頻繁に利用されます。
非常にシンプルな関数ですが、引数の指定方法によって動作が大きく変わるという特徴を持っています。
in_array関数の基本構文と引数
in_array関数の基本的な構文は以下の通りです。
in_array(mixed $needle, array $haystack, bool $strict = false): bool
この関数には最大で3つの引数を渡すことができます。
- $needle:検索したい値を指定します。
- $haystack:検索対象となる配列を指定します。
- $strict:比較の厳密さを指定します(デフォルトは
false)。
基本的な使用例
まずは、最もシンプルな文字列検索の例を見てみましょう。
$fruits = ['apple', 'banana', 'orange'];
if (in_array('banana', $fruits)) {
echo 'バナナが見つかりました';
}
バナナが見つかりました
このように、配列内に指定した文字列が存在すれば、条件式はtrueとなります。
戻り値の注意点と型比較の挙動
in_arrayを使用する上で、最も注意しなければならないのが第3引数の「strict」フラグです。
デフォルトの状態(false)では、PHPの「緩やかな比較(==)」が行われます。
これにより、開発者の意図しない一致判定が発生し、システムに深刻な脆弱性や不具合を招くリスクがあります。
緩やかな比較による問題例
以下のコードは、数値の0を文字列が含まれる配列から検索する例です。
$data = ['apple', 'banana', 'orange'];
if (in_array(0, $data)) {
echo '一致しました';
} else {
echo '一致しませんでした';
}
一致しませんでした
PHP 8.0以降では、文字列と数値の比較ルールが改善されたため、上記の結果は「一致しませんでした」となります。
しかし、PHP 7.4以前の古い環境や、比較する値の内容によっては、依然として「型変換」による予期せぬ一致が起こり得ます。
例えば、空文字やnull、真偽値などが混在する場合、意図しない判定が下される可能性が高まります。
厳密な比較(strictモード)の推奨
安全なコードを書くためには、可能な限り第3引数にtrueを指定し、厳密な比較(===)を行うべきです。
$data = ['10', '20', '30'];
// 第3引数を省略(デフォルトはfalse)
var_dump(in_array(10, $data)); // bool(true) ※PHPのバージョンや型変換によりtrueになる場合がある
// 第3引数にtrueを指定
var_dump(in_array(10, $data, true)); // bool(false)
bool(true)
bool(false)
数値の10と文字列の'10'を区別したい場合は、必ず厳密モードを使用してください。
モダンなPHP開発においては、「in_arrayの第3引数は常にtrueにする」というコーディング規約を設けるプロジェクトも多いです。
大文字・小文字の区別について
in_array関数は、デフォルトで文字列の大文字と小文字を区別します。
例えば、配列内に「Apple」がある場合に「apple」で検索しても一致しません。
$list = ['Apple', 'Orange', 'Banana'];
if (in_array('apple', $list)) {
echo '見つかりました';
} else {
echo '見つかりませんでした';
}
見つかりませんでした
もし大文字・小文字を区別せずに検索したい場合は、検索前に配列の要素と検索値の両方をstrtolower関数などで小文字に統一する必要があります。
多次元配列でのin_arrayの挙動
in_arrayは、検索対象として指定された配列の直下の要素のみを検索します。
つまり、多次元配列の中身まで再帰的に検索することはありません。
$multi_array = [
['id' => 1, 'name' => '田中'],
['id' => 2, 'name' => '佐藤']
];
// '田中'を検索してもfalseになる
var_dump(in_array('田中', $multi_array));
bool(false)
多次元配列内の特定の値を検索したい場合は、array_column関数を併用するか、ループ処理(foreach)を記述する必要があります。
// array_columnを使ってname列から検索する例
if (in_array('田中', array_column($multi_array, 'name'))) {
echo '見つかりました';
}
パフォーマンスに関する注意点
in_arrayの処理速度は、配列の要素数(n)に比例して増加します(計算量はO(n))。
要素数が数万件を超えるような巨大な配列に対して、ループ内で繰り返しin_arrayを実行すると、アプリケーションのパフォーマンスが著しく低下する恐れがあります。
そのようなケースでは、配列の構造を工夫することで高速化が可能です。
issetやarray_key_existsへの置き換え
値を配列の「値」として持つのではなく、「キー」として保持することで、検索速度を劇的に向上させることができます。
PHPの連想配列のキー検索(ハッシュテーブル)は、要素数に関わらずほぼ一定の時間(O(1))で完了するためです。
// in_arrayを使う場合(遅い)
$target = 'user_12345';
if (in_array($target, $huge_list)) { ... }
// キーとして保持し、issetを使う場合(非常に速い)
$huge_list = [
'user_12345' => true,
'user_67890' => true,
];
if (isset($huge_list[$target])) { ... }
大量のデータを高速にチェックする必要がある場合は、array_flip関数などで値をキーに入れ替える手法も検討してください。
in_arrayの代替手段
値を検索するだけでなく、その値が「どこにあるか」を知りたい場合には、他の関数が適しています。
| 関数名 | 特徴 |
|---|---|
in_array() | 存在するかどうかをtrue/falseで返す。 |
array_search() | 一致した要素のキー(インデックス)を返す。見つからない場合はfalse。 |
array_filter() | 複雑な条件で要素を抽出したい場合に便利。 |
単純な存在チェックであればin_arrayが最適ですが、その後の処理でキー情報が必要な場合はarray_searchを選択しましょう。
まとめ
PHPのin_array関数は非常に便利な道具ですが、正しく使うためにはその特性を理解しておく必要があります。
最後に、本記事の重要ポイントをまとめます。
- 基本的な配列検索には
in_arrayを使用する。 - 意図しない型変換を防ぐため、第3引数には原則として
trueを指定する。 - 大文字・小文字は区別されるため、必要に応じて前処理を行う。
- 多次元配列はそのままでは検索できないため、
array_columnなどを活用する。 - 要素数が極めて多い場合は、
issetによるキー検索への変更を検討する。
これらのポイントを押さえておくことで、バグの少ない、堅牢で効率的なPHPプログラムを記述できるようになります。
日々の開発において、配列操作は避けて通れない要素ですので、この機会にしっかりとマスターしておきましょう。
