Signature
array_find_key(array $array, callable $callback): mixedPurpose
array_find_key() answers the question: which key holds the first element that passes my test? You give it an array and a callback. PHP walks the array in its stored order, calls the callback for each element, and stops at the first element for which the callback reports a match. The key of that element is returned.
Before this function existed you would typically write a foreach loop with an early return or break, or combine array_filter() with array_key_first(). The array_filter() approach inspects every element even after a match is found. array_find_key() stops as soon as it has an answer.
Signature
The function is available since PHP 8.4.0.
Parameters
$arrayis the array to search. It may have integer keys, string keys, or a mix. There is no default value, and the argument is required.$callbackis called for each element with two arguments: the value first, then the key. Its shape isfunction (mixed $value, mixed $key): bool. When it returnstrue, the search ends and that element's key is returned. The callback is required and has no default.
Your callback may declare only the $value parameter if the key is irrelevant. PHP still passes both arguments, and a user-defined function simply ignores the extra one.
Return value and failure cases
The return type is mixed because array keys can be either int or string. You get the key of the first matching element, or null if no element matched. An empty array therefore always gives null, and the callback is never called.
Passing something that is not an array, or a value that is not callable, raises a TypeError. If your callback throws an exception, it propagates out of array_find_key() and the search ends there.
Example 1: finding a string key
Here the keys are product names and the values are quantities. The callback looks only at the value.
$stock = ['apples' => 12, 'pears' => 0, 'plums' => 7];
$key = array_find_key($stock, fn(int $qty): bool => $qty === 0);
echo json_encode($key, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";"pears"
The result is the string key of the first out-of-stock item.
Example 2: handling a missing match
When nothing matches, the function returns null. Check for that explicitly before using the result.
$flags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
$users = [101 => 'ana', 102 => 'ben', 103 => 'cy'];
$id = array_find_key($users, fn(string $name): bool => $name === 'zed');
echo json_encode($id, $flags), "\n";
echo $id === null ? "not found" : "found", "\n";null not found
Example 3: the key 0 pitfall
A valid key can be 0, which is falsy in a loose boolean check. Compare against null with !== instead.
$flags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
$items = ['red', 'green', 'blue'];
$key = array_find_key($items, fn(string $color): bool => $color === 'red');
echo json_encode($key, $flags), "\n";
echo $key ? "truthy" : "falsy", "\n";
echo $key !== null ? "found" : "missing", "\n";0 falsy found
The match is at key 0, so a plain if ($key) test would wrongly treat it as a failed search.
Edge cases
- Order matters. The "first" match is determined by the array's internal order, which is insertion order, not by sorted key order.
- Only one key is returned. If several elements match, the later ones are never examined. Use
array_filter()withARRAY_FILTER_USE_BOTHwhen you need all matching keys. - A
nullvalue is not a failure. The function returns a key, not a value, so an element whose value isnullcan still be found. Only anullreturn means no match. - Keys keep their PHP types. A key such as
"5"is stored as the integer5, so the callback receives anintkey in that case. - The callback result is used as a truthy or falsy condition. The manual's own example returns the result of
preg_match(), which is an integer. For clarity, prefer returning a realbool.
Common mistakes
- Testing the result with
if ($key). Keys0and""are falsy yet valid. Use$key !== null. - Expecting the value. This function returns the key. To get the element itself, use
array_find(), or read$array[$key]after checking fornull. - Swapping callback parameters. The value comes first and the key second, the opposite of what some people expect from the name.
- Writing a callback with side effects. Because the search stops early, side effects such as counters or logging happen only for the elements actually visited.
- Assuming a list of results. The return is a single key or
null, never an array.
Related functions
array_find()returns the first matching value instead of its key.array_any()reports whether at least one element satisfies the callback.array_all()reports whether every element satisfies the callback.array_filter()returns all matching elements.array_reduce()folds an array down to a single value.
Recap
array_find_key() takes an array and a callback receiving (value, key). It returns the key of the first element for which the callback matches, or null if none do. It stops early, and it works with both integer and string keys. Always compare the result to null strictly so that a legitimate key like 0 is not mistaken for a miss.
Tested examples
$stock = ['apples' => 12, 'pears' => 0, 'plums' => 7];
$key = array_find_key($stock, fn(int $qty): bool => $qty === 0);
echo json_encode($key, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
"pears"
$flags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
$users = [101 => 'ana', 102 => 'ben', 103 => 'cy'];
$id = array_find_key($users, fn(string $name): bool => $name === 'zed');
echo json_encode($id, $flags), "\n";
echo $id === null ? "not found" : "found", "\n";
null not found
$flags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
$items = ['red', 'green', 'blue'];
$key = array_find_key($items, fn(string $color): bool => $color === 'red');
echo json_encode($key, $flags), "\n";
echo $key ? "truthy" : "falsy", "\n";
echo $key !== null ? "found" : "missing", "\n";
0 falsy found