I have the following PHP code to set parentId for each post. The parentId of each data all become the last post ID. What's wrong with my logic?
btw, if I change it to array, everythings becomes ok. Please help!
$data = array(
(object)array('name' => 'myname')
);
$posts = array(
(object)array('ID' => 1, 'data'=>$data),
(object)array('ID' => 2, 'data'=>$data),
(object)array('ID' => 3, 'data'=>$data)
);
foreach($posts as &$post){
$post->data[0]->parentId = $post->ID;
}
print '<pre>';print_r($posts);die;
die;
Results:
Array
(
[0] => stdClass Object
(
[ID] => 1
[data] => Array
(
[0] => stdClass Object
(
[name] => myname
[parentId] => 3 // expect to be 1
)
)
)
[1] => stdClass Object
(
[ID] => 2
[data] => Array
(
[0] => stdClass Object
(
[name] => myname
[parentId] => 3 // expect to be 2 !!!
)
)
)
[2] => stdClass Object
(
[ID] => 3
[data] => Array
(
[0] => stdClass Object
(
[name] => myname
[parentId] => 3
)
)
)
)
All things considered, the real issue here is, after a second glance at your code, the way you're setting the data
property. Since PHP5, objects are passed/assigned by reference by default. Remember the PHP4 days? ($newInstance = &new SomeClass();
), PHP5 uses references for objects now, so when you do:
$data = array(
(object)array('name' => 'myname')//create object
);
Then, all three objects are assigned the same object (By reference!), so if you change it for the first time around, all three instances will reflect the same change!
I've recently posted a lengthy answer on references in loops here, it might be worth a look, because looping by reference isn't the best way to go about your business.
Some code-review:
Instead of constructing all these arrays, and cast them to objects individually, I'd just do this:
$data = array(
array('name' => 'myname')
);
$posts = array(
array('ID' => 1, 'data'=>$data),
array('ID' => 2, 'data'=>$data),
array('ID' => 3, 'data'=>$data)
);
foreach($posts as $k => $post)
{
$posts[$k]['data'][0]['parentId'] = $posts[$k]['ID'];
}
$posts = json_decode(json_encode($posts));//turns everything into objects
print_r($posts);
At first, it might seem inefficient to json_encode
something, just to json_decode
it, but json_decode
returns objects, instead of associative arrays by default. I've ran a few tests scripts not too long ago, as it turned out: the encode-decode approach was actually faster than casting each associative array...
Okay, i misunderstood your problem, due to the fact that you reuse the data object you end up with a reference problem, this can be avoided by using clone, as seen below
<?php
$data = (object) array('name' => 'myname');
$posts = array(
(object) array('ID' => 1, 'data'=> array(clone $data)),
(object) array('ID' => 2, 'data'=> array(clone $data)),
(object) array('ID' => 3, 'data'=> array(clone $data))
);
foreach($posts as $postKey => $post){
$posts[$postKey]->data[0]->parentId = $posts[$postKey]->ID;
}
print '<pre>';
print_r($posts);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With