2013-08-29 25 views
4

我有以下PHP代码来为每个帖子设置parentId。 每个数据的parentId全部成为最后的帖子ID。 我的逻辑有什么问题?PHP循环通过对象数组得到意想不到的结果

顺便说一句,如果我将它改为数组,一切都会变好。请帮忙!

$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; 

结果:

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 
         ) 

       ) 

     ) 

) 
+0

试试这个http://phpfiddle.org/main/code/yq2-jv3 – 2013-08-29 08:25:34

回答

5

所有的事情考虑,这里的真正的问题是,在你的代码的第二一目了然,以后的路你设置data财产。自PHP5以来,对象默认通过/分配,引用为。记得PHP4的日子? ($newInstance = &new SomeClass();),PHP5现在使用对象的引用,所以当你:

$data = array(
    (object)array('name' => 'myname')//create object 
); 

然后,所有的三个对象被分配相同的对象(通过参考!),所以如果你改变它的第一次在所有三个实例中,都会反映相同的变化!

I've recently posted a lengthy answer on references in loops here,这可能值得一看,因为通过引用循环并不是开展业务的最佳方式。

一些代码审查:
不建立所有这些阵列,并将它们分别转换为对象,我只是这样做:

$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); 

起初,这似乎没有效率的json_encode一些东西,只是json_decode它,但json_decode返回对象,而不是默认关联数组。我已经跑了几个测试脚本不久,因为它发现:编码解码方法实际上比铸造每个关联数组更快......

+1

这是非常翔实的 –

3

好吧,我误解你的问题,因为你重复使用的数据对象,你最终有一个参考的问题的事实,这可以通过使用克隆避免,因为看到下面

<?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); 
+2

你错了,他通过引用传递,因此他正在处理数组中的数据 – Soundz

+0

这是错误的答案。看到这里http://codepad.org/r6u0Ijeh –

+1

而不是克隆,不使用对象,直到数据属性被赋值后,它的值是_way_更高性能,也更容易, –