php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #32088 Reference fails after use of unset() on array
Submitted: 2005-02-23 23:30 UTC Modified: 2005-06-19 01:21 UTC
Votes:1
Avg. Score:4.0 ± 0.0
Reproduced:0 of 1 (0.0%)
From: karl at posmaster dot com dot au Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 5CVS-2005-02-28 OS: *
Private report: No CVE-ID: None
 [2005-02-23 23:30 UTC] karl at posmaster dot com dot au
Description:
------------
Using "for each" I wanted to remove some items and change others.  It seems that the reference in the loop no longer works once unset() has been called on the array.

The commented line achieves the desired end, but circumvents the reference.

The reference works if the unset() line is commented.

This is reproduced without the use of Zend or 3rd part extensions.

-----------------------



Reproduce code:
---------------
<?php
$stuff = array(array('one','two'),array('one','two'),
array('three','four'),array('five','six'),
array('seven','eight'),array('nine','ten'));

var_dump($stuff);

foreach ($stuff as $key => &$values) {
    print "on key:$key<br>";
	if(($key%2)==0){
	    print "Running unset for $key <br>";
	    unset ($stuff[$key]);
	}else{
	    print "Running change for $key <br>";
	    $values[1]='foo';
//	    $stuff[$key][1] = 'foo';
	}
}
var_dump($stuff);
?>

Expected result:
----------------
I expected to see elements $stuff[1][1], $stuff[3][1] and $stuff[5][1] to be set to 'foo'

Actual result:
--------------
The elements are left unchanged. Are values 'two', 'six' and 'ten' respectively.

Patches

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-02-28 22:49 UTC] karl at posmaster dot com dot au
- &$value is a refernce used in the foreach loop.
- If the unset is commented out, the reference to $stuff[1] as $value on the second iteration of the loop works.
- The call to unset() on the first iteration breaks the reference

Actaul Output:
array(1) { [1]=> string(3) "two" }

Expected Output
array(1) { [1]=> string(3) "This should appear below in the var_dump() because $value is passed by reference" }

<?php
$stuff = array('one','two');
foreach ($stuff as $key => &$value) {
	if($key==0){
	    unset ($stuff[$key]);
	}else{
	    $value='This should appear below in the var_dump() because $value is passed by reference';
	}
}
var_dump($stuff);
?>
 [2005-02-28 22:57 UTC] tony2001@php.net
You are modifying array in the foreach loop.
Consider using for/while instead of foreach.
See this code:
<?php
$stuff = array('one','two');
foreach ($stuff as $key => &$value) {
    $value='This should appear below in the var_dump() because $value is passed by reference';
}
var_dump($stuff);
?>
 [2005-03-01 00:50 UTC] karl at posmaster dot com dot au
Although I can use a workaround for this problem (and in the meantime I have), this is still a bug in php isn't it?

After using unset() on the array, in the loop, the reference breaks.
 [2005-05-19 20:52 UTC] pollita@php.net
Even more fun:  Try this variant and you'll see that $fluff not only gets reset to NULL, it gets completely unset.

<?php
$stuff = array('one','two');
$fluff = &$stff;
var_dump($stuff);
var_dump($fluff);
foreach ($stuff as $key => &$value) {
    if($key==0){
        unset ($stuff[$key]);
    }else{
        $value='This should appear below in the var_dump() because $value
is passed by reference';
    }
}
var_dump($stuff);
var_dump($fluff);
?>

 [2005-06-19 01:21 UTC] sniper@php.net
Yes, the above example fails because of the obvious
typo there:
-$fluff = &$stff;
+$fluff = &$stuff;

After that change it works as expected. No bug here.

 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed Aug 14 14:01:29 2024 UTC