Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

php copying array elements by value, not by reference

I have the following code:

$data['x'] = $this->x->getResults();  

$data['y'] = $data['x'];

//some code here to modify $data['y']
//this causes (undesirably) $data['x] to be modified as well

I guess since all the elements of $data are themselves references, modifying $data['y'] also modifies $data['x']..which is NOT what I want. I want $data['x'] to remain the same. Is there any way to dereference the elements here so that I can copy the elements by value?

Thanks.

Update: $this->x->getResults(); returns an object array. So I can then do something like: $data['x'][0]->date_create ...

Update: my latest attempt to clone the array looks something like this:

   $data['x'] = $this->x->getResults();     
   $data['y'] = $data['y'];
   foreach($data['x'] as $key=>$row) {
       $data['y'][$key]->some_attr = clone $row->some_attr;
   }

Am I way off here? I keep getting a "__clone method called on non-object" error. From reading the responses it seems like my best option is to iterate over each element and clone it (which is what I was trying to do with that code..).

UPDATE: Just solved it!: inside the foreach loop I just needed to change the line to:

$data['y'][$key] = clone $row;

And it works! Thanks to everyone for the help.

like image 520
oym Avatar asked Jul 27 '09 19:07

oym


People also ask

Does PHP pass arrays by reference or value?

With regards to your first question, the array is passed by reference UNLESS it is modified within the method / function you're calling. If you attempt to modify the array within the method / function, a copy of it is made first, and then only the copy is modified.

How do I copy values from one array to another in PHP?

The getArrayCopy() function of the ArrayObject class in PHP is used to create a copy of this ArrayObject. This function returns the copy of the array present in this ArrayObject.

Is there a function to make a copy of a PHP array to another?

1 Expert Answer Just assign the array to a variable. $array2 = $array1; If you want them to reference each other (So the change in one array will affect the other) use the & character before the variable.

Which function is used to copy elements of an array into variable?

arraycopy() Java's System class has a method called “ArrayCOpy” that allows you to copy elements of one array to another array.


1 Answers

You can take advantage of the fact that PHP will dereference the results of a function call.

Here's some example code I whipped up:

$x = 'x';
$y = 'y';
$arr = array(&$x,&$y);
print_r($arr);

echo "<br/>";
$arr2 = $arr;
$arr2[0] = 'zzz';
print_r($arr);
print_r($arr2);

echo "<br/>";
$arr2 = array_flip(array_flip($arr));
$arr2[0] = '123';
print_r($arr);
print_r($arr2);

The results look like this:

Array ( [0] => x [1] => y )
Array ( [0] => zzz [1] => y ) Array ( [0] => zzz [1] => y )
Array ( [0] => zzz [1] => y ) Array ( [0] => 123 [1] => y ) 

You can see that the results of using array_flip() during the assigment of $arr to $arr2 results in differences in the subsequent changes to $arr2, as the array_flip() calls forces a dereference.

It doesn't seem terribly efficient, but it might work for you if $this->x->getResults() is returning an array:

$data['x'] = array_flip(array_flip($this->x->getResults()));
$data['y'] = $data['x'];

See this (unanswered) thread for another example.

If everything in your returned array is an object however, then the only way to copy an object is to use clone(), and you would have to iterate through $data['x'] and clone each element into $data['y'].

Example:

$data['x'] = $this->x->getResults();
$data['y'] = array();
foreach($data['x'] as $key => $obj) {
    $data['y'][$key] = clone $obj;
}
like image 191
zombat Avatar answered Sep 19 '22 12:09

zombat