php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #70471 foreach skips values with array_splice
Submitted: 2015-09-10 19:21 UTC Modified: 2015-09-20 01:02 UTC
Votes:5
Avg. Score:4.6 ± 0.8
Reproduced:3 of 4 (75.0%)
Same Version:2 (66.7%)
Same OS:1 (33.3%)
From: dev at cmr dot cx Assigned:
Status: Open Package: Arrays related
PHP Version: 7.0.0RC2 OS: Linux
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2015-09-10 19:21 UTC] 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
)

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-09-19 19:37 UTC] 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-20 01:02 UTC] nikic@php.net
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.)
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Sun Jun 16 21:01:28 2019 UTC