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: 2021-11-16 13:27 UTC
Votes:6
Avg. Score:4.3 ± 0.9
Reproduced:4 of 5 (80.0%)
Same Version:3 (75.0%)
Same OS:2 (50.0%)
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 Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
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

Pull Requests

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.)
 [2021-11-16 13:27 UTC] cmb@php.net
For reference: <https://3v4l.org/rEQN8>.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Oct 04 18:01:29 2024 UTC