我正在尝试将一个users
集合的副本提供给一个雄辩的模型jobs
。所以我实际上有:
jobs : [
1 : {
users : {
1: {}
2: {}
3: {}
}
}
2 : {
users : {
1: {}
2: {}
3: {}
}
}
]
一旦我得到这个,我将从另一个查询中总结一些数字,基本上为每个工作的每个用户提供一个总数,所以上面的结果可能最终看起来像这样:
jobs : [
1 : {
users : {
1: {
total: 120
}
2: {
total: 45
}
3: {
total: 12
}
}
}
2 : {
users : {
1: {
total: 32
}
2: {
total: 4
}
3: {
total: 17
}
}
}
]
除非我似乎无法克隆此用户列表,并且我实际上最终会使所有总计彼此相同:
{
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
}
}
}
}
这是我正在做的事情:
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;
}
我的猜测是,我实际上只是创建对同一事物的引用,而实际上只是添加到'master'集合中。如何成功克隆用户以使总计在作业中唯一?
使用数组(如Matheos推荐的那样)会导致一个非常奇怪的错误:
ErrorException(E_NOTICE)
间接修改重载属性Job :: $ users无效
答案 0 :(得分:8)
您的问题是您正在克隆$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;
可能有更好的方法来做你正在尝试做的事情,但这应该让你去,并希望回答你为什么这样做的问题。
答案 1 :(得分:0)
而不是雄辩的集合尝试使用数组:
$users_list = User::all(['id'])->keyBy('id')->toArray();
您可能还想为“总计”设置初始值
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);
if (! isset($jobs[$chunk->job_id]->users[$chunk->user_id]['total'])) {
$jobs[$chunk->job_id]->users[$chunk->user_id]['total'] = 0;
}
$jobs[$chunk->job_id]->users[$chunk->user_id]['total'] += $chunk->stop_time - $chunk->start_time;
}
}