1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

[RFC] Implement array_first() and array_last() (#18210)

This commit is contained in:
Niels Dossche
2025-05-07 08:15:50 +02:00
committed by GitHub
parent 50dc301f96
commit 168343d2e8
7 changed files with 125 additions and 1 deletions

1
NEWS
View File

@@ -211,6 +211,7 @@ PHP NEWS
(Michael Orlitzky).
. Fixed bug GH-18062 (is_callable(func(...), callable_name: $name) for first
class callables returns wrong name). (timwolla)
. Added array_first() and array_last(). (nielsdos)
- Streams:
. Fixed bug GH-16889 (stream_select() timeout useless for pipes on Windows).

View File

@@ -356,6 +356,10 @@ PHP 8.5 UPGRADE NOTES
. ReflectionConstant::getAttributes() was introduced.
RFC: https://wiki.php.net/rfc/attributes-on-constants
- Standard:
. Added array_first() and array_last().
RFC: https://wiki.php.net/rfc/array_first_last
========================================
7. New Classes and Interfaces
========================================

View File

@@ -4513,6 +4513,32 @@ PHP_FUNCTION(array_key_last)
}
/* }}} */
PHP_FUNCTION(array_first)
{
HashTable *array;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_ARRAY_HT(array)
ZEND_PARSE_PARAMETERS_END();
ZEND_HASH_FOREACH_VAL(array, zval *zv) {
RETURN_COPY_DEREF(zv);
} ZEND_HASH_FOREACH_END();
}
PHP_FUNCTION(array_last)
{
HashTable *array;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_ARRAY_HT(array)
ZEND_PARSE_PARAMETERS_END();
ZEND_HASH_REVERSE_FOREACH_VAL(array, zval *zv) {
RETURN_COPY_DEREF(zv);
} ZEND_HASH_FOREACH_END();
}
/* {{{ Return just the values from the input array */
PHP_FUNCTION(array_values)
{

View File

@@ -1712,6 +1712,16 @@ function array_key_first(array $array): int|string|null {}
*/
function array_key_last(array $array): int|string|null {}
/**
* @compile-time-eval
*/
function array_first(array $array): mixed {}
/**
* @compile-time-eval
*/
function array_last(array $array): mixed {}
/**
* @return array<int, mixed|ref>
* @compile-time-eval

View File

@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 85677dc3476d25b7820fd3a26fe39f2e9378b6e7 */
* Stub hash: f1fdd58097ccd7562c63aee8e9cc1ca88f5bdf31 */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0)
@@ -235,6 +235,12 @@ ZEND_END_ARG_INFO()
#define arginfo_array_key_last arginfo_array_key_first
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_first, 0, 1, IS_MIXED, 0)
ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0)
ZEND_END_ARG_INFO()
#define arginfo_array_last arginfo_array_first
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_values, 0, 1, IS_ARRAY, 0)
ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0)
ZEND_END_ARG_INFO()
@@ -2350,6 +2356,8 @@ ZEND_FUNCTION(array_replace_recursive);
ZEND_FUNCTION(array_keys);
ZEND_FUNCTION(array_key_first);
ZEND_FUNCTION(array_key_last);
ZEND_FUNCTION(array_first);
ZEND_FUNCTION(array_last);
ZEND_FUNCTION(array_values);
ZEND_FUNCTION(array_count_values);
ZEND_FUNCTION(array_column);
@@ -2943,6 +2951,8 @@ static const zend_function_entry ext_functions[] = {
ZEND_RAW_FENTRY("array_keys", zif_array_keys, arginfo_array_keys, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL)
ZEND_RAW_FENTRY("array_key_first", zif_array_key_first, arginfo_array_key_first, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL)
ZEND_RAW_FENTRY("array_key_last", zif_array_key_last, arginfo_array_key_last, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL)
ZEND_RAW_FENTRY("array_first", zif_array_first, arginfo_array_first, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL)
ZEND_RAW_FENTRY("array_last", zif_array_last, arginfo_array_last, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL)
ZEND_RAW_FENTRY("array_values", zif_array_values, arginfo_array_values, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL)
ZEND_RAW_FENTRY("array_count_values", zif_array_count_values, arginfo_array_count_values, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL)
ZEND_RAW_FENTRY("array_column", zif_array_column, arginfo_array_column, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL)

View File

@@ -0,0 +1,53 @@
--TEST--
array_first()/array_last()
--FILE--
<?php
$str = "hello world";
$test_cases = [
["single element"],
[&$str, 1],
[1, &$str],
[1 => 1, 0 => 0, 3 => 3, 2 => 2],
[100 => []],
[new stdClass, false],
[true, new stdClass],
];
foreach ($test_cases as $test_case) {
// Output the checked values
echo "--- Testing: ", json_encode($test_case), " ---\n";
echo "First: ", json_encode(array_first($test_case)), "\n";
echo "Last: ", json_encode(array_last($test_case)), "\n";
// Sanity check consistency with array_key_first()/array_key_last()
if (array_first($test_case) !== $test_case[array_key_first($test_case)]) {
throw new Error("Key first and value first inconsistency");
}
if (array_last($test_case) !== $test_case[array_key_last($test_case)]) {
throw new Error("Key last and value last inconsistency");
}
}
?>
--EXPECT--
--- Testing: ["single element"] ---
First: "single element"
Last: "single element"
--- Testing: ["hello world",1] ---
First: "hello world"
Last: 1
--- Testing: [1,"hello world"] ---
First: 1
Last: "hello world"
--- Testing: {"1":1,"0":0,"3":3,"2":2} ---
First: 1
Last: 2
--- Testing: {"100":[]} ---
First: []
Last: []
--- Testing: [{},false] ---
First: {}
Last: false
--- Testing: [true,{}] ---
First: true
Last: {}

View File

@@ -0,0 +1,20 @@
--TEST--
array_first()/array_last() error cases
--FILE--
<?php
var_dump(array_first([]));
var_dump(array_last([]));
$array = [1, 2, 3];
unset($array[0]);
unset($array[1]);
unset($array[2]);
var_dump(array_first($array));
var_dump(array_last($array));
?>
--EXPECT--
NULL
NULL
NULL
NULL