我有一个问题可能有点傻。我正在尝试复制模型实例并将其存储在变量中以调用该loadMissing
方法。loadMissing
这个想法是在不受原始模型影响的情况下调用方法。让我解释。
我的User
模型中有以下方法:
class User extends Authenticatable
{
...
public function myCustomMethod()
{
$cloned = $this->replicate()
->loadMissing(['roles', 'roles.permissions'])
->getAttribute('roles')
->flatMap(function ($role) {
return $role->permissions
});
return $cloned;
}
问题是,以这种方式,原始模型实例受到影响,并且它在原始实例中加载了我仅在此方法中加载的所有关系。我的问题是:有没有办法在模型实例的副本中加载和隔离关系而不影响原始模型?
提前致谢。
编辑 1
我也尝试过克隆实例并尝试loadMissing
在克隆实例上使用该方法,但原始实例也受到影响。例如:
class User extends Authenticatable
{
...
public function myCustomMethod()
{
$original = $this;
$cloned = clone $original;
$cloned->loadMissing('roles.permissions');
dump($original);
dump($cloned);
die();
}
但是通过这种方式,我得到了以下结果。请注意,当我试图在克隆实例中加载关系时,原始实例和克隆实例都在加载关系:
$original
$cloned
我想知道这是否是正常行为。如果这是正常行为,我想不是,我想知道是否有任何方法可以在loadMissing
不修改原始实例的情况下在实例的副本、副本或克隆上使用该方法。非常感谢您提前。
编辑 2
我的控制器看起来像这样简单:
class HomeController extends Controller
{
public function index()
{
dd(User::find(1)->myCustomMethod());
}
}
解决方案
经过几天寻找文档,进行测试并稍微拉扯一下头发,我找到了解决问题的方法并分享它,以防将来有人来这里寻找类似的信息。
基本上,帮助我找到正确方法的答案是:
https://stackoverflow.com/a/29787693/13066106
官方 PHP 文档中记录了这一点:
https://www.php.net/manual/en/language.oop5.cloning.php
我在这里逐字复制并粘贴最相关的内容:
当一个对象被克隆时,PHP 将对该对象的所有属性执行一个浅拷贝。任何引用其他变量的属性都将保持引用。
当我到达这一点时,我明白它为什么不起作用......我正在克隆一个类型的集合,Illuminate\Database\Eloquent\Collection
这个集合包含多个类型的对象Role
,但根据文档,当我修改任何属性时,这是正常行为在克隆实例中,更改将在原始实例中反映给我。
从这里,我查找了有关它的更多文档,并找到了一篇绝对帮助我解决问题的文章:
这篇文章的描述性很强,基本上它的作用是建议使用包DeepCopy
幸运的是,这个包默认已经是 Laravel 的依赖了,所以我不必用 composer 安装它。我只是使用该deep_copy
方法克隆实例。
非常感谢所有以某种方式帮助过我的人。我希望我分享的文档链接对那些来这里寻找类似信息的人有用。