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

ext/spl: extract AppendIterator constructor (#21367)

The implementation of it is simple whereas spl_dual_it_construct() is extremely convoluted
This commit is contained in:
Gina Peter Banyard
2026-03-21 17:05:33 +00:00
committed by GitHub
parent f102735d71
commit 4d528531be
2 changed files with 30 additions and 26 deletions

View File

@@ -1341,15 +1341,6 @@ static spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAMETERS, z
}
break;
}
case DIT_AppendIterator:
if (zend_parse_parameters_none() == FAILURE) {
return NULL;
}
intern->dit_type = DIT_AppendIterator;
object_init_ex(&intern->u.append.zarrayit, spl_ce_ArrayIterator);
zend_call_method_with_0_params(Z_OBJ(intern->u.append.zarrayit), spl_ce_ArrayIterator, &spl_ce_ArrayIterator->constructor, "__construct", NULL);
intern->u.append.iterator = spl_ce_ArrayIterator->get_iterator(spl_ce_ArrayIterator, &intern->u.append.zarrayit, 0);
return intern;
case DIT_RegexIterator:
case DIT_RecursiveRegexIterator: {
zend_string *regex;
@@ -2814,7 +2805,21 @@ static void spl_append_it_next(spl_dual_it_object *intern) /* {{{ */
/* {{{ Create an AppendIterator */
PHP_METHOD(AppendIterator, __construct)
{
spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, spl_ce_AppendIterator, zend_ce_iterator, DIT_AppendIterator);
ZEND_PARSE_PARAMETERS_NONE();
spl_dual_it_object *intern = Z_SPLDUAL_IT_P(ZEND_THIS);
/* TODO: This should be converted to a normal Error as this is triggered when calling the constructor twice */
if (intern->dit_type != DIT_Unknown) {
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "%s::getIterator() must be called exactly once per instance", ZSTR_VAL(spl_ce_AppendIterator->name));
RETURN_THROWS();
}
intern->dit_type = DIT_AppendIterator;
object_init_ex(&intern->u.append.zarrayit, spl_ce_ArrayIterator);
zend_call_method_with_0_params(Z_OBJ(intern->u.append.zarrayit), spl_ce_ArrayIterator, &spl_ce_ArrayIterator->constructor, "__construct", NULL);
intern->u.append.iterator = spl_ce_ArrayIterator->get_iterator(spl_ce_ArrayIterator, &intern->u.append.zarrayit, 0);
} /* }}} */
/* {{{ Append an iterator */

View File

@@ -3,6 +3,13 @@ SPL: AppendIterator::append() rewinds when necessary
--FILE--
<?php
$ap = new AppendIterator();
try {
$ap->__construct();
} catch (\Throwable $e) {
echo $e::class, ': ', $e->getMessage(), "\n";
}
class MyArrayIterator extends ArrayIterator
{
function rewind(): void
@@ -14,8 +21,7 @@ class MyArrayIterator extends ArrayIterator
$it = new MyArrayIterator(array(1,2));
foreach($it as $k=>$v)
{
foreach($it as $k=>$v) {
echo "$k=>$v\n";
}
@@ -44,31 +50,24 @@ class MyAppendIterator extends AppendIterator
parent::append($what);
}
function parent__construct()
{
function parent__construct() {
parent::__construct();
}
}
$ap = new MyAppendIterator;
try
{
try {
$ap->append($it);
}
catch(\Error $e)
{
} catch(\Error $e) {
echo $e->getMessage() . "\n";
}
$ap->parent__construct();
try
{
try {
$ap->parent__construct($it);
}
catch(BadMethodCallException $e)
{
} catch(BadMethodCallException $e) {
echo $e->getMessage() . "\n";
}
@@ -76,13 +75,13 @@ $ap->append($it);
$ap->append($it);
$ap->append($it);
foreach($ap as $k=>$v)
{
foreach($ap as $k=>$v) {
echo "$k=>$v\n";
}
?>
--EXPECT--
BadMethodCallException: AppendIterator::getIterator() must be called exactly once per instance
MyArrayIterator::rewind
0=>1
1=>2