Laravel 5.5中Model查询对象赋值后条件叠加问题求助
解决Laravel查询构建器实例赋值后条件叠加的问题
嗨,这个问题我之前也碰到过!核心原因是Laravel的查询构建器对象在PHP中是引用传递的——你执行$obj2 = $obj1时,并没有创建一个全新的查询构建器实例,只是让$obj2指向了和$obj1同一个内存地址的对象。所以后续对其中一个添加的where条件,会同时作用在另一个对象上,最终导致两个条件叠加在一起。
下面给你两种简单的解决方法:
方法1:使用clone关键字克隆查询实例
在赋值的时候用clone关键字,直接复制出一个独立的查询构建器实例,这样两个变量就互不影响了:
$obj1 = Celebrity::select('*'); $obj2 = clone $obj1; // 关键:克隆出全新的实例 $obj1 = $obj1->where('status', 1); $obj2 = $obj2->where('status', 2); // 此时$obj2->toSQL()会输出预期的:SELECT * FROM celebrity WHERE status = 2
方法2:复用基础查询逻辑(适合复杂场景)
如果你的基础查询(比如select('*')之外还有其他通用条件)比较复杂,可以把基础查询封装成一个方法,每次调用都返回新的查询实例:
// 可以放在模型里或者控制器里 private function getBaseCelebrityQuery() { return Celebrity::select('*'); // 这里可以添加更多通用条件,比如where('is_deleted', 0) } // 调用时 $obj1 = $this->getBaseCelebrityQuery()->where('status', 1); $obj2 = $this->getBaseCelebrityQuery()->where('status', 2);
当然如果基础查询很简单,直接分别初始化两个查询实例也完全没问题:
$obj1 = Celebrity::select('*')->where('status', 1); $obj2 = Celebrity::select('*')->where('status', 2);
补充说明
PHP中对象类型的变量默认都是引用传递,这和普通的字符串、数字等值类型的赋值逻辑不一样。所以在处理Laravel查询构建器这类对象时,一定要注意如果需要独立的查询实例,必须主动克隆或者重新创建,而不是直接赋值。
内容的提问来源于stack exchange,提问作者user
相关产品推荐
相关产品推荐

