php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #67096 Iterators unexpectedly works with references
Submitted: 2014-04-17 20:29 UTC Modified: 2014-04-17 20:42 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: Azq2 at ya dot ru Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 5.5.11 OS: Ubuntu 13.04
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: Azq2 at ya dot ru
New email:
PHP Version: OS:

 

 [2014-04-17 20:29 UTC] Azq2 at ya dot ru
Description:
------------
Hello! I don't good speek english... i from Ukraine ;) 

Поэтому сразу напишу на русском. Суть бага: если переменная, которая используются в foreach как ссылка на результат текущей итерации, уже была декларирована ранее - то ей присваивается значение ранее декларированной переменной. (кроме последней) И портится массив, который используется в foreach. 
так не должно быть. 

if variable what used in foreach as reference to current iterator value declared before foreach - iterator value (expect last) assigns of before declared value. 

Test script:
---------------
<?php
	$array = array(
		array(1, 1, 1), 
		array(1, 1, 1), 
		array(1, 1, 1), 
	);
	
	foreach ($array as $k => &$res) {
		$v = 27112012;
		foreach ($res as $k => &$v) {
			
			
		}
	}
	
	var_dump($array);

Expected result:
----------------
array(3) {
  [0]=>
  array(3) {
    [0]=>
    int(1)
    [1]=>
    int(1)
    [2]=>
    int(1)
  }
  [1]=>
  array(3) {
    [0]=>
    int(1)
    [1]=>
    int(1)
    [2]=>
    int(1)
  }
  [2]=>
  array(3) {
    [0]=>
    int(1)
    [1]=>
    int(1)
    [2]=>
    int(1)
  }
}

Actual result:
--------------
array(3) {
  [0]=>
  array(3) {
    [0]=>
    int(1)
    [1]=>
    int(1)
    [2]=>
    int(27112012)
  }
  [1]=>
  array(3) {
    [0]=>
    int(1)
    [1]=>
    int(1)
    [2]=>
    int(27112012)
  }
  [2]=>
  &array(3) {
    [0]=>
    int(1)
    [1]=>
    int(1)
    [2]=>
    &int(1)
  }
}

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-04-17 20:38 UTC] Azq2 at ya dot ru
Т.е. старое значение из $v по ссылке уходит в значение ключа $k массива $res. 
Value of array $res by key $k assigns by reference old value of $v.
 [2014-04-17 20:42 UTC] rasmus@php.net
-Status: Open +Status: Not a bug
 [2014-04-17 20:42 UTC] rasmus@php.net
This is expected. If you expand the foreach you have the equivalent of:

    $k = 0; $res = &$array[0];
       $v = 27112012;
       $k = 0; $v = &$res[0];
       $k = 1; $v = &$res[1];
       $k = 2; $v = &$res[2];
    $k = 1; $res = &$array[1];
       $v = 27112012; // But $v is a reference to $res[2] which is $array[0][2]
                      // So this is like doing $array[0][2] = 27112012;
       $k = 0; $v = &$res[0];
       $k = 0; $v = &$res[0];
       $k = 1; $v = &$res[1];
       $k = 2; $v = &$res[2];
    $k = 2; $res = &$array[2];
       $v = 27112012; // same here for $array[1][2]
       $k = 0; $v = &$res[0];
       $k = 0; $v = &$res[0];
       $k = 1; $v = &$res[1];
       $k = 2; $v = &$res[2];

And since there are no further iterations nothing writes to $array[2][2]
 
PHP Copyright © 2001-2026 The PHP Group
All rights reserved.
Last updated: Tue Oct 06 22:00:02 2026 UTC