制作Laravel系列的副本

Dja*_*ave 2 php laravel

我正在尝试将一个集合的副本提供users给一个雄辩的模型jobs.所以我有效地拥有:

jobs : [
    1 : {
        users : {
            1: {}
            2: {}
            3: {}
        }
    }
    2 : {
        users : {
            1: {}
            2: {}
            3: {}
        }
    }
]
Run Code Online (Sandbox Code Playgroud)

一旦我得到这个,我将从另一个查询中总结一些数字,基本上为每个工作的每个用户提供一个总数,所以上面可能看起来像这样:

jobs : [
    1 : {
        users : {
            1: {
                total: 120
            }
            2: {
                total: 45
            }
            3: {
                total: 12
            }
        }
    }
    2 : {
        users : {
            1: {
                total: 32
            }
            2: {
                total: 4
            }
            3: {
                total: 17
            }
        }
    }
]
Run Code Online (Sandbox Code Playgroud)

除了我似乎无法克隆这个用户列表,我实际上最终所有的总数是相同的:

{  
   1:{  
      id:1,
      users:{  
         1:{  
            id:1,
            total:807
         },
         2:{  
            id:2,
            total:9
         }
      }
   },
   2:{  
      id:2,
      users:{  
         1:{  
            id:1,
            total:807
         },
         2:{  
            id:2,
            total:9
         }
      }
   },
   3:{  
      id:3,
      users:{  
         1:{  
            id:1,
            total:807
         },
         2:{  
            id:2,
            total:9
         }
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

这是我在做的事情:

public function summary()
{
    $jobs = Job::all()->keyBy('id');
    $users = User::with('closed_time_chunks')->get();

    $users_list = User::all(['id'])->keyBy('id');

    // I think this is the problem statement:
    foreach ($jobs as $job):
        $job->users = clone $users_list;
    endforeach;

    Log::info('Starting');


    foreach ($users as $user):
        foreach ($user->closed_time_chunks as $chunk):

            Log::info('Adding ' . ($chunk->stop_time - $chunk->start_time) . ' to job: ' . $chunk->job_id);
            $jobs[$chunk->job_id]->users[$chunk->user_id]['total'] += $chunk->stop_time - $chunk->start_time;

        endforeach;
    endforeach;
}
Run Code Online (Sandbox Code Playgroud)

我的猜测是,我实际上只是创建了对同一个东西的引用,并且任何添加实际上只是添加到'master'集合.如何成功克隆用户以使总计在作业中唯一?

编辑

使用数组(如Matheos推荐的那样)会导致一个非常奇怪的错误:

ErrorException(E_NOTICE)

间接修改重载属性Job :: $ users无效

小智 11

你的问题是,你是克隆的$users_list,但是这是一个CollectionUser对象.在PHP中,当您克隆对象时,任何引用对象的属性仍然是对这些对象的引用,换句话说,这些子对象本身不会被克隆.见__clone

由于您的代码是动态地向其中的每个User实例添加"总计"属性Collection,因此它实际上会更改该特定实例的所有实例的总值User,因为它们都是对自身的引用.你需要做的是克隆你的每个子成员(User)Collection以及Collection它自己.

foreach ($jobs as $job):
    $job->users = clone $users_list;
    $job->users->transform(function($user) { return clone $user; });
endforeach;
Run Code Online (Sandbox Code Playgroud)

可能有更好的方法来做你正在尝试做的事情,但这应该让你去,并希望回答你的原因问题.