Signature
array_search(mixed $needle, array $haystack, bool $strict = false): int|string|falsePurpose
array_search() looks through an array for a value and tells you where it lives. Unlike in_array(), which only answers yes or no, it returns the key of the first element that matches. That makes it useful when you need to know the position of a value in a list, or the name of the entry that holds it in an associative array.
Signature
Parameters and defaults
$needleis the value you are looking for. It can be any type. When it is a string, the comparison is case-sensitive.$haystackis the array to search. Only its top-level values are examined, so nested arrays are not searched recursively.$strictdefaults tofalse. In that mode values are compared loosely, as with==. When it istrue, values must be identical, as with===. The type must match, and objects must be the very same instance.
Return value and failure cases
The function returns the key of the first matching element. The key is an int for list-style arrays and a string for string keys. If nothing matches it returns false. It does not throw an exception for a missing value. If the needle occurs several times, only the first matching key is returned. Use array_keys() with its filter value argument when you need every matching key.
Because the key 0 is a valid result and 0 is falsy, you must always test the result with === or !==.
Example 1: first match and missing values
This example shows that the first key wins when a value repeats, and that a missing value gives false.
$colors = ['blue', 'red', 'green', 'red'];
echo json_encode([
'green' => array_search('green', $colors),
'red' => array_search('red', $colors),
'purple' => array_search('purple', $colors),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);{"green":2,"red":1,"purple":false}Example 2: the key 0 trap
The first element of a list has key 0. A loose truthiness check treats that key like a failed search, which is a classic bug.
$items = ['apple', 'banana', 'cherry'];
$key = array_search('apple', $items);
echo json_encode([
'key' => $key,
'loose_check' => $key == false ? 'looks missing' : 'found',
'strict_check' => $key !== false ? 'found' : 'missing',
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);{"key":0,"loose_check":"looks missing","strict_check":"found"}Example 3: loose and strict matching
With string keys, the returned key tells you which entry matched. The values '10', 10 and 10.0 are loosely equal to each other, but strict mode tells them apart.
$values = ['a' => '10', 'b' => 10, 'c' => 10.0];
echo json_encode([
'loose' => array_search(10, $values),
'strict_int' => array_search(10, $values, true),
'strict_string' => array_search('10', $values, true),
'strict_float' => array_search(10.0, $values, true),
'missing_strict' => array_search('11', $values, true),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);{"loose":"a","strict_int":"b","strict_string":"a","strict_float":"c","missing_strict":false}Edge cases
- Empty array: the result is always
false. - Loose mode and mixed types: numeric strings and numbers can match each other, and values such as
null,0and''may be considered equal to one another. If the types in your data are mixed, passtrue. - Case sensitivity:
'Red'does not match'red'. Normalize both sides first if you need case-insensitive matching. - Arrays and objects: with
$strictset totrue, an array needle must be identical to the element, and an object needle must be the same instance rather than an equal copy. - Nested data: the function does not look inside sub-arrays. To search one column of a list of records, extract that column first with
array_column()and search the result. - Preserved keys: the key returned is the original key, even after sorting or filtering. Do not assume it is a position counted from zero.
Common mistakes
- Writing
if (array_search(...))or comparing with==. A match at key0is then treated as not found. - Using the default loose mode on mixed data and getting an unexpected match.
- Using the result as an index without first checking for
false. Afalsekey is converted to0when used as an array offset, which silently picks the wrong element. - Using
array_search()when you only need a boolean.in_array()states that intent more clearly. - Expecting all matches. Only the first key is returned.
Related functions
in_array()checks whether a value exists and returns a boolean.array_keys()returns all keys, optionally only those whose value matches a filter.array_key_exists()checks for a key rather than a value.array_values()returns the values of an array re-indexed from zero.
Recap
array_search() returns the first key whose value matches the needle, or false if none does. Pass true as the third argument when types matter, and always compare the result with !== false.
Tested examples
$colors = ['blue', 'red', 'green', 'red'];
echo json_encode([
'green' => array_search('green', $colors),
'red' => array_search('red', $colors),
'purple' => array_search('purple', $colors),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);{"green":2,"red":1,"purple":false}
$items = ['apple', 'banana', 'cherry'];
$key = array_search('apple', $items);
echo json_encode([
'key' => $key,
'loose_check' => $key == false ? 'looks missing' : 'found',
'strict_check' => $key !== false ? 'found' : 'missing',
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);{"key":0,"loose_check":"looks missing","strict_check":"found"}
$values = ['a' => '10', 'b' => 10, 'c' => 10.0];
echo json_encode([
'loose' => array_search(10, $values),
'strict_int' => array_search(10, $values, true),
'strict_string' => array_search('10', $values, true),
'strict_float' => array_search(10.0, $values, true),
'missing_strict' => array_search('11', $values, true),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);{"loose":"a","strict_int":"b","strict_string":"a","strict_float":"c","missing_strict":false}