4

我有以下 PHP 代码来为每个帖子设置 parentId。每个数据的parentId都成为最后一个post ID。我的逻辑有什么问题?

顺便说一句,如果我将其更改为数组,一切都会好起来的。请帮忙!

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

                )

        )

)
4

2 回答 2

5

考虑到所有因素,这里的真正问题是,在再次查看您的代码之后,您设置data属性的方式。从 PHP5 开始,对象默认通过引用传递/分配。还记得 PHP4 的日子吗?( $newInstance = &new SomeClass();),PHP5 现在使用对象的引用,所以当你这样做时:

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

然后,所有三个对象都被分配了同一个对象(通过引用!),所以如果您第一次更改它,所有三个实例都将反映相同的更改!

我最近在此处发布了关于循环引用的冗长答案,可能值得一看,因为按引用循环并不是开展业务的最佳方式。

一些代码审查:
而不是构造所有这些数组,并将它们单独转换为对象,我只是这样做:

$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默认情况下返回对象,而不是关联数组。不久前我运行了一些测试脚本,结果证明:编码解码方法实际上比强制转换每个关联数组要快......

于 2013-08-29T07:35:09.583 回答
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); 
于 2013-08-29T07:34:28.703 回答