【问题标题】:Stop PHP Object behaving like reference停止 PHP 对象的行为类似于参考
【发布时间】:2018-10-20 19:08:57
【问题描述】:

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

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

我想在子项中添加一个名为“已处理”的键,在对象数组结构中,所有子项都在更新,但我只想更新特定项,如基于数组的示例。请参阅示例以进一步理解我的意思。

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
                                    )

                            )

                    )

            )
            >

【问题讨论】:

标签: php arrays object


【解决方案1】:

您需要克隆$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

【讨论】:

  • 我确实克隆了主数组,但还不足以解决。现在我也按照你说的克隆子项目并解决了我的问题。这是非常有趣且难以看到的。非常感谢!
  • @empax 没问题。克隆数组不会产生任何有意义的影响,因为它们不是以相同的方式通过引用来保存的。事实上,如果你这样做了,我很惊讶你没有收到一个错误说你不能克隆一个非对象?
  • 对不起我的错误,它是主数组中的一个对象。是的,你是对的,数组克隆给出了异常“__clone method called on non-object”:) 再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-07
  • 2021-09-03
  • 2023-01-09
  • 1970-01-01
  • 2011-06-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多