mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
RFC: Make the iterator_*() family accept all iterables (#8819)
https://wiki.php.net/rfc/iterator_xyz_accept_array
This commit is contained in:
4
NEWS
4
NEWS
@@ -48,6 +48,10 @@ PHP NEWS
|
||||
- Random:
|
||||
. Added new random extension. (Go Kudo)
|
||||
|
||||
- SPL:
|
||||
. Widen iterator_to_array() and iterator_count()'s $iterator parameter to
|
||||
iterable. (timwolla)
|
||||
|
||||
- Standard:
|
||||
. Fixed empty array returned by str_split on empty input. (Michael Vorisek)
|
||||
. Added ini_parse_quantity function to convert ini quantities shorthand
|
||||
|
||||
@@ -189,6 +189,11 @@ PHP 8.2 UPGRADE NOTES
|
||||
dba_fetch(string|array $key, $skip, $dba): string|false
|
||||
is still accepted, but it is recommended to use the new standard variant.
|
||||
|
||||
- SPL
|
||||
. The $iterator parameter of iterator_to_array() and iterator_count() is
|
||||
widened to iterable from Iterator, allowing arrays to be passed.
|
||||
RFC: https://wiki.php.net/rfc/iterator_xyz_accept_array
|
||||
|
||||
========================================
|
||||
6. New Functions
|
||||
========================================
|
||||
|
||||
@@ -48,7 +48,7 @@ function spl_object_id(object $object): int {}
|
||||
|
||||
function iterator_apply(Traversable $iterator, callable $callback, ?array $args = null): int {}
|
||||
|
||||
function iterator_count(Traversable $iterator): int {}
|
||||
function iterator_count(iterable $iterator): int {}
|
||||
|
||||
/** @refcount 1 */
|
||||
function iterator_to_array(Traversable $iterator, bool $preserve_keys = true): array {}
|
||||
function iterator_to_array(iterable $iterator, bool $preserve_keys = true): array {}
|
||||
|
||||
6
ext/spl/php_spl_arginfo.h
generated
6
ext/spl/php_spl_arginfo.h
generated
@@ -1,5 +1,5 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: 7359e9e5aa07c00d0e0be2642f11c1131a17e61e */
|
||||
* Stub hash: 2590b06c4e9798c2ceba9aa364f66d05c5690bc1 */
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_implements, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE)
|
||||
ZEND_ARG_INFO(0, object_or_class)
|
||||
@@ -53,11 +53,11 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_iterator_apply, 0, 2, IS_LONG, 0
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_iterator_count, 0, 1, IS_LONG, 0)
|
||||
ZEND_ARG_OBJ_INFO(0, iterator, Traversable, 0)
|
||||
ZEND_ARG_OBJ_TYPE_MASK(0, iterator, Traversable, MAY_BE_ARRAY, NULL)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_iterator_to_array, 0, 1, IS_ARRAY, 0)
|
||||
ZEND_ARG_OBJ_INFO(0, iterator, Traversable, 0)
|
||||
ZEND_ARG_OBJ_TYPE_MASK(0, iterator, Traversable, MAY_BE_ARRAY, NULL)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, preserve_keys, _IS_BOOL, 0, "true")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
|
||||
@@ -3171,8 +3171,18 @@ PHP_FUNCTION(iterator_to_array)
|
||||
zval *obj;
|
||||
bool use_keys = 1;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|b", &obj, zend_ce_traversable, &use_keys) == FAILURE) {
|
||||
RETURN_THROWS();
|
||||
ZEND_PARSE_PARAMETERS_START(1, 2)
|
||||
Z_PARAM_ITERABLE(obj)
|
||||
Z_PARAM_OPTIONAL
|
||||
Z_PARAM_BOOL(use_keys)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
if (Z_TYPE_P(obj) == IS_ARRAY) {
|
||||
if (use_keys) {
|
||||
RETURN_COPY(obj);
|
||||
} else {
|
||||
RETURN_ARR(zend_array_to_list(Z_ARRVAL_P(obj)));
|
||||
}
|
||||
}
|
||||
|
||||
array_init(return_value);
|
||||
@@ -3195,12 +3205,16 @@ PHP_FUNCTION(iterator_count)
|
||||
zval *obj;
|
||||
zend_long count = 0;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &obj, zend_ce_traversable) == FAILURE) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_ITERABLE(obj)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
if (spl_iterator_apply(obj, spl_iterator_count_apply, (void*)&count) == FAILURE) {
|
||||
return;
|
||||
if (Z_TYPE_P(obj) == IS_ARRAY) {
|
||||
count = zend_hash_num_elements(Z_ARRVAL_P(obj));
|
||||
} else {
|
||||
if (spl_iterator_apply(obj, spl_iterator_count_apply, (void*)&count) == FAILURE) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_LONG(count);
|
||||
|
||||
@@ -13,7 +13,7 @@ iterator_count('1');
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught TypeError: iterator_count(): Argument #1 ($iterator) must be of type Traversable, string given in %s:%d
|
||||
Fatal error: Uncaught TypeError: iterator_count(): Argument #1 ($iterator) must be of type Traversable|array, string given in %s:%d
|
||||
Stack trace:
|
||||
#0 %s(%d): iterator_count('1')
|
||||
#1 {main}
|
||||
|
||||
14
ext/spl/tests/iterator_count_array.phpt
Normal file
14
ext/spl/tests/iterator_count_array.phpt
Normal file
@@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
SPL: iterator_count() supports arrays.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
var_dump(iterator_count([]));
|
||||
var_dump(iterator_count([1]));
|
||||
var_dump(iterator_count(['a' => 1, 'b' => 2, 5 => 3]));
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(0)
|
||||
int(1)
|
||||
int(3)
|
||||
20
ext/spl/tests/iterator_count_exception.phpt
Normal file
20
ext/spl/tests/iterator_count_exception.phpt
Normal file
@@ -0,0 +1,20 @@
|
||||
--TEST--
|
||||
SPL: iterator_count() throws if the Iterator throws
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function generator() {
|
||||
yield 1;
|
||||
throw new Exception('Iterator failed');
|
||||
}
|
||||
|
||||
var_dump(iterator_count(generator()));
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Exception: Iterator failed in %siterator_count_exception.php:5
|
||||
Stack trace:
|
||||
#0 [internal function]: generator()
|
||||
#1 %siterator_count_exception.php(8): iterator_count(Object(Generator))
|
||||
#2 {main}
|
||||
thrown in %siterator_count_exception.php on line 5
|
||||
@@ -13,7 +13,7 @@ iterator_to_array('test','test');
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught TypeError: iterator_to_array(): Argument #1 ($iterator) must be of type Traversable, string given in %s:%d
|
||||
Fatal error: Uncaught TypeError: iterator_to_array(): Argument #1 ($iterator) must be of type Traversable|array, string given in %s:%d
|
||||
Stack trace:
|
||||
#0 %s(%d): iterator_to_array('test', 'test')
|
||||
#1 {main}
|
||||
|
||||
42
ext/spl/tests/iterator_to_array_array.phpt
Normal file
42
ext/spl/tests/iterator_to_array_array.phpt
Normal file
@@ -0,0 +1,42 @@
|
||||
--TEST--
|
||||
SPL: iterator_to_array() supports arrays.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
var_dump(iterator_to_array([]));
|
||||
var_dump(iterator_to_array([1]));
|
||||
var_dump(iterator_to_array(['a' => 1, 'b' => 2, 5 => 3]));
|
||||
var_dump(iterator_to_array([], false));
|
||||
var_dump(iterator_to_array([1], false));
|
||||
var_dump(iterator_to_array(['a' => 1, 'b' => 2, 5 => 3], false));
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
array(0) {
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(1)
|
||||
}
|
||||
array(3) {
|
||||
["a"]=>
|
||||
int(1)
|
||||
["b"]=>
|
||||
int(2)
|
||||
[5]=>
|
||||
int(3)
|
||||
}
|
||||
array(0) {
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(1)
|
||||
}
|
||||
array(3) {
|
||||
[0]=>
|
||||
int(1)
|
||||
[1]=>
|
||||
int(2)
|
||||
[2]=>
|
||||
int(3)
|
||||
}
|
||||
Reference in New Issue
Block a user