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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
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: Wed Oct 07 11:00:02 2026 UTC