#29992 [Com]: foreach by reference corrupts the array

From: Date: Mon, 04 Oct 2004 14:49:05 +0000
Subject: #29992 [Com]: foreach by reference corrupts the array
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-67087@lists.php.net to get a copy of this message
 ID:               29992
 Comment by:       yaroukh at email dot cz
 Reported By:      fletch at pobox dot com
 Status:           Open
 Bug Type:         Zend Engine 2 problem
 Operating System: linux
 PHP Version:      5.0.1
 New Comment:

I'm [Apache/2.0.48 (Win32) PHP/5.0.2]


Previous Comments:
------------------------------------------------------------------------

[2004-10-04 16:37:43] yaroukh at email dot cz

I believe the problem I'm gonna describe here has the same roots as the
one fletch has described ...
Try this:

<?	class ArrayWrapper {

		protected $slots;

		public function __construct($slots = Array())
		{
			$this->slots =& $slots;
		}

		public function & getSlot($idx)
		{
			if(IsSet($this->slots[$idx]))
				return $this->slots[$idx];

			return null;
		}

		public function getLength()
		{
			return Count($this->slots);
		}
	}

	// fill the array and create object {

	$slots = Array(
			'zero',
			'one',
			'two',
			'three',
			'four'
		);

	$aw = new ArrayWrapper($slots);

	// }

	// output A
	var_dump($aw);

	// iteration 1
	for($idx = 0; $idx < $aw->getLength(); $idx++)
		$aw->getSlot($idx);

	// output B; everything is OK
	var_dump($aw);

	// iteration 2
	for($idx = 0; $idx < $aw->getLength(); $idx++)
		if($aw->getSlot($idx))
		{
		}

	// output C; elements have been changed to references
	var_dump($aw);
?>

As you can see in output "C" the second iteration altered elements of
the array - the elements have been turned into references. (Or did I
get the ampersand-sign wrong?) The problem is that I loose control over
the REAL objects and the elements get changed unreasonably later in the
script.

I kind of understand what's the diference between getSlot() and
getSlot() used within an if-loop (I guess the scope created by if-loop
makes the difference), but I'm not sure this difference entitles PHP to
alter my array.

Can anyone explain this to me? Is it a bug or a regular behaviour?

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

[2004-09-06 08:04:28] fletch at pobox dot com

changed the summary

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

[2004-09-06 05:54:50] fletch at pobox dot com

Description:
------------
foreach with a reference seems to corrupt the last element in an array

Reproduce code:
---------------
<?php
$array = array(1,2,3);
foreach( $array as &$item ) { }
print_r( $array );
foreach( $array as $item ) { }
print_r( $array );
?>

Expected result:
----------------
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
)
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
)

Actual result:
--------------
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
)
Array
(
    [0] => 1
    [1] => 2
    [2] => 2
)


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


-- 
Edit this bug report at http://bugs.php.net/?id=29992&edit=1


Thread (43 messages)

« previous php.bugs (#67087) next »