in_array($needle, $haystack)は、値が配列のどこかにあればtrueを、なければfalseを返します。第三引数にtrueを渡す(in_array($needle, $haystack, true))と、型も同じであることを求めます。デフォルトではこの厳密な形を使いましょう。
in_array()が見るのは値だけです。キーが存在するかを確認するには、array_key_exists()かisset()を使います。
第三引数strict
第三引数がないと、in_array()は比較の前に型を変換する==で比較します。trueを渡すと===で比較し、値と型の両方が一致する必要があります。配列に数値と文字列が混ざるとすぐに違いが表れますが、フォーム、URL、CSVファイルから来るデータではそれがよくあります。
下の各セルは、PHP 8.3でその値の組に対して==と===が返す結果です。使うモードの表で、探す値とどれかの要素の組がtrueになれば、in_array()はtrueを返します。タブを切り替えて、null、true、数値文字列の行を見てください。
| $a == $b | true | false | null | 0 | 1 | "0" | "1" | "" | "abc" | "10" | "1e1" | 10 | [] |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| true | |||||||||||||
| false | |||||||||||||
| null | |||||||||||||
| 0 | |||||||||||||
| 1 | |||||||||||||
| "0" | |||||||||||||
| "1" | |||||||||||||
| "" | |||||||||||||
| "abc" | |||||||||||||
| "10" | |||||||||||||
| "1e1" | |||||||||||||
| 10 | |||||||||||||
| [] |
PHP 8で変わったルールが1つあります。数値でない文字列は0と等しくなくなったので、in_array('abc', [0])は今はfalseですが、PHP 7ではtrueでした。PHP 7向けに書かれたコードがこれに頼っていることがあるのも、trueを渡して変換のルールに頼らない理由の1つです。ルールの全体は比較演算子のページで説明しています。
大文字小文字を区別しないin_array
in_array()は文字列を正確に比較するので、'PHP'と'php'は別物です。確認する前に、探す値と配列の両方を小文字にします。mb_strtolower()はアクセント付きの文字やラテン文字以外も扱えます。
複数の値を一度に確認する
in_array()が受け取る探す値は1つです。複数の値なら、配列を集合として比較します。array_diff()は見つからない値を返すので結果が空ならすべて存在し、array_intersect()は見つかった値を返します。
array_diff()とarray_intersect()は値を文字列として比較するので、そこでは1と'1'は等しいとみなされます。
多次元配列に対するin_array
in_array()はネストした配列の中までは探しません。あるフィールドが特定の値を持つ行があるかを確認するには、先にarray_column()でそのフィールドを取り出し、平らなリストを検索します。
最後の行は、探す値そのものが配列でもよいことを示しています。キー、値、順番がまったく同じ行に一致します。
in_array、array_search、issetの違い
3つとも「そこにあるか」に答えますが、返すものと速さが違います。
| 呼び出し | 戻り値 | 大きな配列での速さ |
|---|---|---|
in_array($v, $arr, true) | trueかfalse | すべての要素を調べる |
array_search($v, $arr, true) | キー、またはfalse | すべての要素を調べる |
isset($set[$v]) | trueかfalse | 1回のハッシュ検索 |
値がどこにあるかを知る必要があるならarray_search()を使います。同じ大きなリストに対して多くの値を確認するなら、リストを一度反転して値をキーにし、isset()を使います。
時間は実行のたびに変わりますが、差は変わりません。isset()の検索は一定のままで、in_array()はリストの大きさに比例して遅くなります。array_flip()は文字列と整数の値にしか使えず、重複は1つのキーにまとまりますが、存在の確認には関係ありません。
よくある質問
in_arrayの第三引数は何をしますか?
厳密な比較を有効にします。in_array($x, $arr, true)は===で比較するので、値だけでなく型も一致する必要があります:in_array('1', [1, 2], true)はfalseです。第三引数がなければ、PHPは==で比較し、先に型を変換します。
in_arrayでは常にstrictモードを使うべきですか?
たいていはそうです。ゆるいモードでは、in_array(null, [0])、in_array(true, ['any string'])、in_array('1e1', ['10'])がすべてtrueを返します。フォームの'5'を整数の5に一致させたいと意図的に考えている場合だけ、オフのままにします。
in_arrayで大文字小文字を区別しないようにするには?
両辺を小文字にします:in_array(strtolower($needle), array_map('strtolower', $haystack), true)。テキストにASCII以外の文字が含まれうるならmb_strtolowerを使います。
複数の値が配列に含まれているか確認するには?
すべてを必要とするなら、何も残らないことを確認します:!array_diff($needles, $haystack)。少なくとも1つを必要とするなら、重なりがあるかを確認します:(bool) array_intersect($needles, $haystack)。
in_arrayは遅いですか?
要素を1つずつ調べるので、大きな配列を何度も確認すると遅くなります。$set = array_flip($haystack);で一度だけ配列を反転し、1回のハッシュ検索ですむisset($set[$value])を使いましょう。