停止PHP对象的行为类似于引用

时间:2018-05-10 13:32:04

标签: php arrays object

我有一个对象数组但在循环中它的行为类似于PHP引用。

我也在同一个结构中创建一个数组,它可以正常工作。

我想在子项中添加一个名为“processed”的键,在对象数组struct中,所有子项都在更新,但我想只更新特定的项,就像在基于数组的示例中一样。请参阅示例以进一步了解我的意思。

Click here to run this code in PHPFiddle

            // OBJECT
            $pool = [
                    1 => (Object)[
                        'id' => '1',
                        'title' => 'Pool 1'
                    ],
                    2 => (Object)[
                        'id' => '2',
                        'title' => 'Pool 2'
                    ],
                ];

            $items = [
                (Object)['id' => 1],
                (Object)['id' => 2],
            ];

            $vars = [];
            foreach ($items as $i => $item) {

                $vars[$i] = $item;
                $vars[$i]->pool = $pool;

                $vars[$i]->pool[$item->id]->processed = true;
            }


            // ARRAY
            $pool1 = [
                    1 => [
                        'id' => '1',
                        'title' => 'Pool 1'
                    ],
                    2 => [
                        'id' => '2',
                        'title' => 'Pool 2'
                    ],
                ];

            $items1 = [
                ['id' => 1],
                ['id' => 2],
            ];

            $vars1 = [];
            foreach ($items1 as $i1 => $item1) {

                $vars1[$i1] = $item1;
                $vars1[$i1]['pool'] = $pool1;

                $vars1[$i1]['pool'][$item1['id']]['processed'] = true;
            }


            ?>

            <h4>
                Object result
            </h4>
            <pre
                <?php print_r($vars); ?>
            ></pre>


            <h4>
                Array result
            </h4>
            <pre
                <?php print_r($vars1); ?>
            ></pre>

结果是

            Object result
             stdClass Object
                    (
                        [id] => 1
                        [pool] => Array
                            (
                                [1] => stdClass Object
                                    (
                                        [id] => 1
                                        [title] => Pool 1
                                        [processed] => 1
                                    )

                                [2] => stdClass Object
                                    (
                                        [id] => 2
                                        [title] => Pool 2
                                        [processed] => 1
                                    )

                            )

                    )

                [1] => stdClass Object
                    (
                        [id] => 2
                        [pool] => Array
                            (
                                [1] => stdClass Object
                                    (
                                        [id] => 1
                                        [title] => Pool 1
                                        [processed] => 1
                                    )

                                [2] => stdClass Object
                                    (
                                        [id] => 2
                                        [title] => Pool 2
                                        [processed] => 1
                                    )

                            )

                    )

            )
            >
            Array result
             Array
                    (
                        [id] => 1
                        [pool] => Array
                            (
                                [1] => Array
                                    (
                                        [id] => 1
                                        [title] => Pool 1
                                        [processed] => 1
                                    )

                                [2] => Array
                                    (
                                        [id] => 2
                                        [title] => Pool 2
                                    )

                            )

                    )

                [1] => Array
                    (
                        [id] => 2
                        [pool] => Array
                            (
                                [1] => Array
                                    (
                                        [id] => 1
                                        [title] => Pool 1
                                    )

                                [2] => Array
                                    (
                                        [id] => 2
                                        [title] => Pool 2
                                        [processed] => 1
                                    )

                            )

                    )

            )
            >

1 个答案:

答案 0 :(得分:2)

您需要克隆 $pool内的每个对象,否则在您创建的$pool的每个副本中都会保存对同一组对象的引用。它不是“表现得像引用”的数组,而是它内部的对象,它们的行为与它们应该的一样。

执行此操作将导致您想要的行为:

$vars = [];
foreach ($items as $i => $item) {

    $vars[$i] = $item;
    $vars[$i]->pool = $pool;

    //clone each of the objects
    foreach($vars[$i]->pool as $key => $obj) {
      $vars[$i]->pool[$key] = clone $obj;
    }

    $vars[$i]->pool[$item->id]->processed = true;
}

有关克隆的详细信息,请参阅http://php.net/manual/en/language.oop5.cloning.php