Arrays7 min readExamples run on PHP 8.5.10

array_search()

Learn how PHP 8.4 array_search() finds the first key for a value, how strict mode changes matching, and why you must test the result with ===.

Signature

array_search(mixed $needle, array $haystack, bool $strict = false): int|string|false
Available since PHP 4.0.57.48.08.18.28.38.48.5All versions →

Purpose

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

  • $needle is the value you are looking for. It can be any type. When it is a string, the comparison is case-sensitive.
  • $haystack is the array to search. Only its top-level values are examined, so nested arrays are not searched recursively.
  • $strict defaults to false. In that mode values are compared loosely, as with ==. When it is true, 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.

Example
<?php
$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);
Output
{"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.

Example
<?php
$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);
Output
{"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.

Example
<?php
$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);
Output
{"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, 0 and '' may be considered equal to one another. If the types in your data are mixed, pass true.
  • Case sensitivity: 'Red' does not match 'red'. Normalize both sides first if you need case-insensitive matching.
  • Arrays and objects: with $strict set to true, 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

  1. Writing if (array_search(...)) or comparing with ==. A match at key 0 is then treated as not found.
  2. Using the default loose mode on mixed data and getting an unexpected match.
  3. Using the result as an index without first checking for false. A false key is converted to 0 when used as an array offset, which silently picks the wrong element.
  4. Using array_search() when you only need a boolean. in_array() states that intent more clearly.
  5. Expecting all matches. Only the first key is returned.
  • 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

First match and missing values
<?php
$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);
Output
{"green":2,"red":1,"purple":false}
The key 0 trap
<?php
$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);
Output
{"key":0,"loose_check":"looks missing","strict_check":"found"}
Loose and strict matching
<?php
$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);
Output
{"loose":"a","strict_int":"b","strict_string":"a","strict_float":"c","missing_strict":false}