Arrays7 min readExamples run on PHP 8.5.10

array_find_key()

Learn how PHP 8.4 array_find_key() returns the key of the first array element that satisfies a callback, with examples, edge cases and common mistakes.

Signature

array_find_key(array $array, callable $callback): mixed
Available since PHP 8.4.07.48.08.18.28.38.48.5All versions →

Purpose

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

  • $array is the array to search. It may have integer keys, string keys, or a mix. There is no default value, and the argument is required.
  • $callback is called for each element with two arguments: the value first, then the key. Its shape is function (mixed $value, mixed $key): bool. When it returns true, 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.

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

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

Example
<?php
$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";
Output
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() with ARRAY_FILTER_USE_BOTH when you need all matching keys.
  • A null value is not a failure. The function returns a key, not a value, so an element whose value is null can still be found. Only a null return means no match.
  • Keys keep their PHP types. A key such as "5" is stored as the integer 5, so the callback receives an int key 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 real bool.

Common mistakes

  1. Testing the result with if ($key). Keys 0 and "" are falsy yet valid. Use $key !== null.
  2. Expecting the value. This function returns the key. To get the element itself, use array_find(), or read $array[$key] after checking for null.
  3. Swapping callback parameters. The value comes first and the key second, the opposite of what some people expect from the name.
  4. 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.
  5. Assuming a list of results. The return is a single key or null, never an array.
  • 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

Find the string key of the first out-of-stock item
<?php
$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";
Output
"pears"
Handle the case where nothing matches
<?php
$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";
Output
null
not found
Avoid the falsy key 0 pitfall
<?php
$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";
Output
0
falsy
found