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
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: dev at cmr dot cx
New email:
PHP Version: OS:

 

 [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 Jul 21 10:01:26 2019 UTC