我正在尝试将一个集合的副本提供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,但是这是一个Collection的User对象.在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)
可能有更好的方法来做你正在尝试做的事情,但这应该让你去,并希望回答你的原因问题.