制作 Laravel 集合的副本

2024-01-04

我正在尝试提供一份集合的副本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;
}

我的猜测是,我实际上只是创建对同一事物的引用,任何添加实际上只是添加到“主”集合中。如何成功克隆用户以使总数在作业中是唯一的?

Edit

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

错误异常(E_NOTICE)

间接修改重载属性 Job::$users 没有效果


你的问题是你正在克隆你的$users_list,但那是一个Collection of User对象。在 PHP 中,当您克隆一个对象时,它的任何引用对象的属性仍然是对这些对象的引用,换句话说,这些子对象本身不会被克隆。看__clone http://php.net/__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;

可能有更好的方法来完成您想要做的事情,但这应该可以帮助您继续前进,并希望也能回答您的“为什么”问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

制作 Laravel 集合的副本 的相关文章

随机推荐