views:

146

answers:

3
$arr = array(array(array()));
foreach($arr as $subarr)
{
 $subarr[] = 1;
}
var_dump($arr);

Output:

array(1) {
  [0]=>
  array(1) {
    [0]=>
    array(0) {
    }
  }
}

But for object,it's reference:

class testclass {
}

$arr = array(new testclass());
foreach($arr as $subarr)
{
 $subarr->new = 1;
}
var_dump($arr);

Output:

array(1) {
  [0]=>
  object(testclass)#1 (1) {
    ["new"]=>
    int(1)
  }
}

Why treat array different from object?

+3  A: 

PHP passes all objects by reference. (PHP5?)

PHP passes all arrays by value.

Originally PHP passed both objects and arrays by value, but in order to cut down on the number of objects created, they switch objects to automatically pass by reference.

There is not really a logical reason why PHP does not pass arrays by reference, but that is just how the language works. If you need to it is possible to iterate over arrays by value but you have to declare the value explicitly by-reference:

foreach ( $myArray as &$val ){
    $val = 1; //updates the element in $myArray
}

Thanks to Yacoby for the example.

Frankly I prefer arrays to be passed by value because arrays are a type of basic data structure, while objects are more sophisticated data structures. The current system makes sense, at least to me.

Chacha102
So we can iterate array both by reference and value,but how to iterate object by value?
@user198729 Alternatively to Chacha's suggestion you could implement the iterator interface and ensure `current` returns byval rather than byref. See http://php.net/manual/en/language.oop5.iterations.php
Yacoby
+1  A: 

Why would array and object be treated the same?

PHP simply passes objects by reference (->), and passes all arrays by value.

If all objects were passed by value, the script would make many copies of the same class, thereby using more memory.

zipcodeman
A: 

Foreach copies the iterated array because it allows you to modify the original array while inside the foreach, and it's easier to use that way. Wouldn't it be the case, your first example would blow up. There is no way to keep PHP from copying the array inside a foreach. Even when using the pass-item-by-reference syntax foreach($foo as &$bar), you'll still work on a copy of the array, one that contains references instead of actual values.

Objects, on the other hand, are expected from most object-oriented developers to always be passed by reference. This became the case in PHP 5. And when you copy an array that contains objects, you actually copy the references to objects; so even though you're working on an copy of the array, you're working on the same objects.

If you want to copy an object, use the clone operator. As far as I know, there is no way to have certain objects always be passed by value.

$foo = new Foo;
$bar = clone $foo;
zneak