【问题标题】:Object getting mysteriously overridden对象被神秘地覆盖
【发布时间】:2020-02-29 13:53:48
【问题描述】:

每次我调用$this->load_operations() 时,$this->processes->data 都会以某种方式扩展。我真的不明白为什么当我的代码显然没有修改它时该对象会发生变化。

我错过了什么吗?

如果我将 $process(在 foreach 中)转换为数组,然后再转换回对象 $this->processes->data,则不会扩展。

$process = (array) $process;
$process = (object) $process;
class Test_library
{
    private $processes;
    private $tasks;
    private $operations;

    public function __construct()
    {
        $this->processes = (object) array(
            'data' => (object) array(
                '3' => (object) array(
                    'id' => '3',
                )
            )
        );

        $this->tasks = (object) array(
            'data' => (object) array(
                '5' => (object) array(
                    'id' => '5',
                    'processes_id' => '3',
                ),
                '6' => (object) array(
                    'id' => '6',
                    'processes_id' => '3',
                )
            )
        );

        $this->operations = (object) array(
            'processes' => (object) array(
                '3' => (object) array(
                    'id' => '3',
                    'data' => array()
                )
            )
        );

        print_r($this->processes->data);

        $this->load_operations();

        print_r($this->processes->data);
    }

    private function load_operations()
    {
        if(!empty($this->processes->data))
        {
            foreach($this->processes->data as $process)
            {
                $this->operations->processes->{$process->id} = $process;
            }
        }

        if(!empty($this->tasks->data))
        {
            foreach($this->tasks->data as $task)
            {
                $this->operations->processes->{$task->processes_id}->data[] = (object) [
                    'machine' => [],
                    'task' => $task
                ];
            }
        }
    }
}

new Test_Library;

两个print_r的结果应该是一样的。

【问题讨论】:

标签: php oop


【解决方案1】:

您的问题是,粗略地说,对象是通过引用传递的。详情可见in the documentation

在您的第一个foreach 循环中,您将对$this->processes->data->3 的引用分配给$this->operations->processes->3

        foreach($this->processes->data as $process) {
            $this->operations->processes->{$process->id} = $process;
        }

在下一个循环中,您将附加到您刚刚建立的$this->operations->processes->3data 属性作为对$this->processes->data->3 的引用。

        foreach($this->tasks->data as $task) {
            $this->operations->processes->{$task->processes_id}->data[] = (object) [
                'machine' => [],
                'task' => $task
            ];
        }

要解决此问题,您可以尝试在第一个循环的赋值期间使用clone 运算符(see here 了解更多详细信息)或简单地使用关联数组。

【讨论】:

  • 谢谢@miken32。在第一个 foreach 中添加 $process_clone = clone $process; 解决了我的问题。