Bug #70471 [Opn]: foreach skips values with array_splice

From: Date: Sun, 20 Sep 2015 01:03:00 +0000
Subject: Bug #70471 [Opn]: foreach skips values with array_splice
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-196100@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=70471&edit=1

 ID:                 70471
 Updated by:         nikic@php.net
 Reported by:        dev at cmr dot cx
 Summary:            foreach skips values with array_splice
 Status:             Open
 Type:               Bug
 Package:            Arrays related
 Operating System:   Linux
 PHP Version:        7.0.0RC2
 Block user comment: N
 Private report:     N

 New Comment:

The problem is that the iterator bump in http://lxr.php.net/xref/PHP_TRUNK/ext/standard/array.c#2469
can (unlike most other cases) move an iterator forward, which the code doesn't account for.
(The iterator will just be bumped forward again and again in that loop.)


Previous Comments:
------------------------------------------------------------------------
[2015-09-19 19:37:11] j dot tvr at centrum dot cz

The issue is still valid with PHP 7.0.0RC3. However I personally think that the expected result
should not skip the key 2 with y value, i.e. it should be

0: a
1: b
2: y
3: c
4: d
5: e
6: f
Array
(
    [0] => a
    [1] => x
    [2] => y
    [3] => c
    [4] => d
    [5] => e
    [6] => f
)


This following is a bit simplified test script:

<?php
$ar = ['a', 'b', 'c'];

foreach ($ar as $k => &$v) {
	echo "$k: $v\n";
	if ($k === 0) array_splice($ar, 1, 0, ['x']);
}

echo "\n";
print_r($ar);


Expected result:
----------------
0: a
1: x
2: b
3: c

Array
(
    [0] => a
    [1] => x
    [2] => b
    [3] => c
)

------------------------------------------------------------------------
[2015-09-10 19:21:11] dev at cmr dot cx

Description:
------------
In the expample skript foreach skips the values "c", "d" and "e".

As far as I can see this happens only if in the array_splice the number of elements of the
replacement array (array("x", "y")) is higher than the length parameter (1). If
I set the length to 2, I get the following output, which makes much more sense:

0: a
1: b
3: d
4: e
5: f
Array
(
    [0] => a
    [1] => x
    [2] => y
    [3] => d
    [4] => e
    [5] => f
)  

Test script:
---------------
$array = array("a", "b", "c", "d", "e",
"f");
foreach ( $array as $key => &$value ) {
	echo "$key: $value\n";
	if ( $value == "b" ) array_splice($array, $key, 1, array("x", "y"));
}
print_r($array);

Expected result:
----------------
0: a
1: b
3: c
4: d
5: e
6: f
Array
(
    [0] => a
    [1] => x
    [2] => y
    [3] => c
    [4] => d
    [5] => e
    [6] => f
)

Actual result:
--------------
0: a
1: b
6: f
Array
(
    [0] => a
    [1] => x
    [2] => y
    [3] => c
    [4] => d
    [5] => e
    [6] => f
)


------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=70471&edit=1


Thread (4 messages)

« previous php.bugs (#196100) next »