in_array($needle, $haystack) returns true if the value is somewhere in the array and false if not. Pass true as the third argument, in_array($needle, $haystack, true), to require the same type as well; that strict form is the one to use by default.
in_array() only looks at values. To check whether a key exists, use array_key_exists() or isset().
The strict parameter
Without the third argument, in_array() compares with ==, which converts types before comparing. With true, it compares with ===: the value and the type must both match. The difference shows up as soon as the array mixes numbers and strings, which is common with data from forms, URLs and CSV files.
Each cell below is what == and === return for that pair of values in PHP 8.3. in_array() answers true if the needle and any element give true in the table for the mode you use. Switch between the tabs and look at the null, true and numeric string rows.
| $a == $b | true | false | null | 0 | 1 | "0" | "1" | "" | "abc" | "10" | "1e1" | 10 | [] |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| true | |||||||||||||
| false | |||||||||||||
| null | |||||||||||||
| 0 | |||||||||||||
| 1 | |||||||||||||
| "0" | |||||||||||||
| "1" | |||||||||||||
| "" | |||||||||||||
| "abc" | |||||||||||||
| "10" | |||||||||||||
| "1e1" | |||||||||||||
| 10 | |||||||||||||
| [] |
One rule changed in PHP 8: a non-numeric string no longer equals 0, so in_array('abc', [0]) is false today but was true in PHP 7. Code written for PHP 7 sometimes relied on that, which is one more reason to pass true and not depend on the conversion rules. The comparison operators page explains them in full.
Case-insensitive in_array
in_array() compares strings exactly, so 'PHP' and 'php' are different. Lowercase both the needle and the array before checking. mb_strtolower() handles accented and non-Latin letters as well.
Check several values at once
in_array() takes one needle. For several, compare the arrays as sets: array_diff() returns the needles that are missing, so an empty result means all are present, and array_intersect() returns the needles that were found.
array_diff() and array_intersect() compare values as strings, so 1 and '1' count as equal there.
in_array on a multidimensional array
in_array() does not search inside nested arrays. To check whether any row has a field with a given value, extract that field first with array_column(), then search the flat list.
The last line shows that the needle can itself be an array: it matches a row that is identical, same keys, values and order.
in_array vs array_search vs isset
All three answer "is it there?", but they return different things and run at different speeds:
| Call | Returns | Speed on a large array |
|---|---|---|
in_array($v, $arr, true) | true or false | scans every element |
array_search($v, $arr, true) | the key, or false | scans every element |
isset($set[$v]) | true or false | one hash lookup |
Use array_search() when you need to know where the value is. When you check many values against the same large list, flip the list once so its values become keys, and use isset().
The times change from run to run, but the gap does not: the isset() lookup stays flat while in_array() grows with the size of the list. array_flip() only works for string and integer values, and duplicates collapse into one key, which does not matter for a membership check.
Frequently Asked Questions
What does the third parameter of in_array do?
It turns on strict comparison. in_array($x, $arr, true) compares with ===, so the type must match as well as the value: in_array('1', [1, 2], true) is false. Without it, PHP compares with == and converts types first.
Should I always use strict mode with in_array?
Usually yes. Loose mode makes in_array(null, [0]), in_array(true, ['any string']) and in_array('1e1', ['10']) all return true. Leave it off only when you deliberately want '5' from a form to match the integer 5.
How do I make in_array case-insensitive?
Lowercase both sides: in_array(strtolower($needle), array_map('strtolower', $haystack), true). Use mb_strtolower when the text can contain non-ASCII letters.
How do I check if several values are in an array?
To require all of them, check that nothing is left over: !array_diff($needles, $haystack). To require at least one, check for an overlap: (bool) array_intersect($needles, $haystack).
Is in_array slow?
It scans the array element by element, so it is slow for large arrays checked many times. Flip the array once with $set = array_flip($haystack); and use isset($set[$value]), which is a single hash lookup.