I am looping through an object and i try to duplicate one of the items while changing one of it's variables.
But when i copy the original and then change the title in the new one, the old one changes along with it. Which it shouldn't, since i did not initialised it as a reference.
$calendar = array(
(object)[
'id' => 1,
'title' => 'original 1',
],
(object)[
'id' => 2,
'title' => 'original 2',
],
(object)[
'id' => 3,
'title' => 'original 3',
],
);
foreach ($calendar AS $key => $item){
if($item->id == 2){
$item->title = 'new 2';
array_splice($calendar, $key, 0, [1]);
$calendar[$key] = $item;
}
}
echo "<pre>";
print_r($calendar);
die();
I would expect the output of this to keep original 2
intact. But it changes it along with it.
(
[0] => stdClass Object
(
[id] => 1
[title] => original 1
)
[1] => stdClass Object
(
[id] => 2
[title] => new 2
)
[2] => stdClass Object
(
[id] => 2
[title] => new 2
)
[3] => stdClass Object
(
[id] => 3
[title] => original 3
)
)
Even if i make a new object and use that one to make the changes, it still changes the orignial.
foreach ($calendar AS $key => $item){
if($item->id == 2){
$new_item = $item;
$new_item->title = 'new 2';
array_splice($calendar, $key, 0, [1]);
$calendar[$key] = $new_item;
}
}
Now i could probably fix this by just making a new object from scratch and copy the values one by one in it. But where's the fun in that?
So my question is...Why does this happen? Even though i didn't cast $item
as &$item
CodePudding user response:
$new_item = $item;
doesn't create a new object.
In the following example, $a
and $b
are the same object.
$a = new stdclass;
$a->b = 2;
$b = $a;
var_dump($a,$b);
and output:
object(stdClass)#1 (1) {...} // same object #1
object(stdClass)#1 (1) {...} // same object #1
You could use clone
to create a new instance:
$a = new stdclass;
$a->b = 2;
$b = clone $a; // Clone the object
var_dump($a,$b);
Output:
object(stdClass)#1 (1) {...} // object #1
object(stdClass)#2 (1) {...} // new object #2
So, in your case, you could use:
if ($item->id == 2) {
$clone = clone $item;
$clone->title = 'new 2';
array_splice($calendar, $key, 0, [1]);
$calendar[$key] = $clone;
}
CodePudding user response:
As simple PHP Object assignment does not create a new object. It simply creates a new pointer to the same object.
I think you want to use the clone
keyword:
foreach ($calendar AS $key => $item){
if($item->id == 2){
$new_item = clone $item;
$new_item->title = 'new 2';
array_splice($calendar, $key, 0, [1]);
$calendar[$key] = $new_item;
}
}