Table of Contents

PHP RFC: array_key_(first|last|index)

Introduction

Sometimes, it is necessary to retrieve the first or last key of an array, but there is no convenient means of doing so currently provided by the language without modifying the source array or resorting to odd-to-read code. This RFC and its accompanying patch add the following functions to assist with that task:

Proposal

Arrays in php are ordered maps, but there is no convenient way to get the first or last key of an array (a common function in some use cases), or even an arbitrary key by index (a fairly rare need).

array_key_first() returns the first key in an array.

array_key_last() returns the last key in an array.

array_key_index() returns the key at a specified index (using a substr-like offset; greater-than or equal to zero starts from the beginning of the array; negative from the end).

$arr ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4];
 
$key = array_key_first($arr); //$key === 'a'
 
$key = array_key_last($arr, $val); //$key === 'd', $val === 4
 
$key = array_key_index($arr, 1); //$key === 'b'
$key = array_key_index($arr, -2); //$key === 'c'
$key = array_key_index($arr, 5, $val); //$key === NULL, $val is unchanged
 
 
// Also works for numeric arrays
$numeric = [1 => 1, 5 => 2, 2 => 3];
$key = array_key_index($numeric, 0); //$key === 1
$key = array_key_index($numeric, 1); //$key === 5
$key = array_key_index($numeric, 2); //$key === 2

All three functions return the requested array key, or null if the requested array key is not found (an empty array, or an out-of-bounds index in the case of array_key_index). For convenience, each function also takes an optional $value parameter that, if provided and the specified index is found, will be set to contain the value at the specified index.

There are certain use-cases that require getting the first key of an array (and to a much lesser extent, the last key, or an arbitrary key by index order). There are three ways this could be done with existing php functionality, all of which have significant drawbacks, in either performance, legibility, or mutability:

With the reference implementation provided in the patch referenced below, array_key_first() and array_key_last() directly retrieve the array key from the underlying hash (by setting a local hash pointer to the start/end of the array and retrieving the key for that index). By necessity, array_key_index() iterates through the keys, but does so in C code, rather than in PHP code. array_key_first() and array_key_last() are implemented in terms of array_key_index(); array_key_index() exists a a consequence and extension of generalizing the common code between array_key_first() and array_key_last().

array_key_first() and array_key_last() have O(1) time complexity. array_key_index() (when not retrieving the first or last key) has O(N) time complexity. array_key_index() is intended when only one key or value from an array is needed; if repeated calls to array_key_index() are needed for a particular array, it would likely be more performant to just use array_keys() instead. (Iterating all keys of an array using array_key_index() would be O(N^2).) As such, it's included for sake of completeness, but would likely in practice see limited use.

Patches and Tests

The GitHub Pull request for this change is here: https://github.com/php/php-src/pull/347

This is a full and working implementation, and if accepted, could be merged as-is. The PR includes tests covering all new functionality.

Backward Incompatible Changes

None.

Proposed PHP Version(s)

Next PHP 7.x.

RFC Impact

As this RFC only adds new functions, it should not cause any impact to SAPIs, other extensions, or opcache.

Open Issues

* Whether or not to include the corresponding array value as an optional-return-by-reference parameter.

Proposed Voting Choices

This RFC does not add new syntax, so a 50%+1 majority is required to pass.

Implementation

After the project is implemented, this section should contain

  1. the version(s) it was merged to
  2. a link to the git commit(s)
  3. a link to the PHP manual entry for the feature