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:
1
NEWS
1
NEWS
@@ -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).
|
||||
|
||||
@@ -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
|
||||
========================================
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
12
ext/standard/basic_functions_arginfo.h
generated
12
ext/standard/basic_functions_arginfo.h
generated
@@ -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)
|
||||
|
||||
53
ext/standard/tests/array/array_first_last.phpt
Normal file
53
ext/standard/tests/array/array_first_last.phpt
Normal 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: {}
|
||||
20
ext/standard/tests/array/array_first_last_errors.phpt
Normal file
20
ext/standard/tests/array/array_first_last_errors.phpt
Normal 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
|
||||
Reference in New Issue
Block a user