4

Somehow $this->processes->data gets expanded everytime I call $this->load_operations(). I do not really understand why that object changes when my code clearly does not modify it.

Am I missing something?

If I cast $process (in the foreach) to array and then back to object $this->processes->data does not get expanded.

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

The result of the two print_r should be the same.

miken32
  • 42,008
  • 16
  • 111
  • 154
  • Please take the [tour] to learn how Stack Overflow works and read [ask] on how to improve the quality of your question. Then [edit] your question to include your full source code you have as a [mcve], which can be tested by others. – Progman Nov 16 '19 at 16:41
  • 2
    @Progman this seems to me to be an excellent example of a [mcve]. Only thing missing is instantiation of the object, which I've added. – miken32 Nov 16 '19 at 17:03

1 Answers1

5

Your problem is that objects are, roughly speaking, passed by reference. The details can be found in the documentation.

In your first foreach loop, you are assigning a reference to $this->processes->data->3 to $this->operations->processes->3

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

In the next loop, you are appending to the data property of $this->operations->processes->3 which you just established as a reference to $this->processes->data->3.

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

To get around this behaviour, you might try using the clone operator during assignment in the first loop (see here for more details) or simply use associative arrays.

miken32
  • 42,008
  • 16
  • 111
  • 154