PHP 8.4 added four searches that take a predicate fn($value, $key): bool. array_find() returns the first matching value and array_find_key() its key, each null on no match; array_any() and array_all() ask whether some or every element matches. All four stop at the first decisive element, unlike array_filter(). PHP 8.5 added array_first() and array_last(), which return the end values in array order, or null for an empty array.
<?php
$books = [['sku' => 'BK-101', 'title' => 'Dune', 'price' => 9.99, 'stock' => 7],
['sku' => 'BK-205', 'title' => 'Emma', 'price' => 4.5, 'stock' => 0],
['sku' => 'BK-300', 'title' => 'Odes', 'price' => 3.75, 'stock' => 9]];
$calls = 0;
$cheap = function (array $b) use (&$calls): bool { $calls++; return $b['price'] < 5; };
echo array_find($books, $cheap)['title'], " after $calls calls | ",
array_find_key($books, fn(array $b, int $i): bool => $b['sku'] === 'BK-300'), "\n";
echo json_encode([array_find($books, fn(array $b): bool => $b['price'] > 100), // no match
array_any($books, fn(array $b): bool => $b['stock'] === 0), // sold out?
array_all($books, fn(array $b): bool => $b['price'] > 0), // all priced?
array_all([], fn($b): bool => false), array_any([], fn($b): bool => true)]), "\n";
echo array_first($books)['title'], ' ', array_last($books)['title'], "\n";Emma after 2 calls | 2 [null,true,true,true,false] Dune Odes
array_find() stopped after two calls. array_all([]) is true and array_any([]) false, as in logic. They replace idioms such as count(array_filter($a, $f)) > 0 and reset($a). When null can be a stored value, use array_find_key(). symfony/polyfill-php84 and -php85 backport the six.