A new PHP RFC proposes array_search_range(), a function for searching part of an array without creating a temporary slice first. Sepehr Mahmoudi opened the proposal for discussion on August 17.

The function would work like array_search(), but it would accept an offset and length:

function array_search_range(
    mixed $needle,
    array $haystack,
    int $offset = 0,
    ?int $length = null,
    bool $strict = false,
): int|string|false {}

How It Would Work

PHP developers can already search part of an array by combining array_slice() and array_search():

$range = array_slice($languages, 100, 50, true);
$key = array_search('PHP', $range, true);

The problem is that array_slice() creates a second array in memory. The proposed function would search the original array directly, avoiding that extra array and the second function call.

Here is an example from the RFC:

$items = ['zero', 'one', 'two', 'target', 'four', 'target'];

$key = array_search_range('target', $items, 2, 3, true);
// int(3)

The range is based on position, not array keys. However, the function returns the original key when it finds a match:

$items = [100 => 'alpha', 500 => 'target'];

$key = array_search_range('target', $items, 1, 1, true);
// int(500)

The other range rules follow array_slice():

  • A negative offset counts from the end of the array.
  • A null length searches to the end.
  • A negative length leaves that many items out at the end.
  • A zero length or an offset outside the array returns false.

The PHP Version Is Unclear

The RFC currently targets PHP 8.6. However, PHP 8.6 Beta 1 has already started the release's soft feature freeze.

Weilin Du raised that issue in the first discussion thread:

PHP 8.6 is entering soft feature freeze now. It is impossible to promote a RFC targeting 8.6. Therefore, IMO you should target 8.7 instead.

The RFC has not moved to a vote, and its target has not been changed yet. Based on the release schedule and the discussion, PHP 8.7 appears to be the more likely target.

A Broader ArraySlice Idea

The discussion is also asking whether PHP should add one search function or build a more general way to work with part of an array.

Rowan Tommins suggested a lazy ArraySlice type. It could point to part of an array without copying its values:

I think it would be better to design something more composable - that is, a way to create a "lazy array slice."

Such a type could work with more than search. Morgan noted that range support could also apply to functions such as array_find(), array_find_key(), array_all(), and array_any().

Sjoerd Langkemper pointed out that PHP's LimitIterator already offers a similar way to loop over a range. The problem is that array_search() only accepts arrays, so it cannot search a LimitIterator.

Tommins later explained why this matters for the RFC:

if we add an ArraySlice type then array_search_range would immediately become redundant.

The Case for a Smaller Function

Mahmoudi argues that array_search_range() solves a problem now, while ArraySlice has no RFC, code, or timeline:

Right now, ArraySlice doesn't exist in PHP. It's an interesting idea, but it has no RFC, no implementation, and no timeline.

He also wrote:

blocking a useful function on a hypothetical future feature doesn't help users who need it now

This leaves the discussion with two choices. PHP could add one focused function, or it could first explore a feature that works across many array operations.

The array_search_range() RFC remains a draft under discussion. An implementation is available in php-src PR #23325, but no vote has been scheduled.