我想根据我从json对象收集的搜索参数构造一系列雄辩的WHERE子句。
像这样的东西(不要介意对象的语法,它只是一种解释来演示):
$searchmap = "
{
"color": "red",
"height": "1",
"width": "2",
"weight": "",
"size": "",
}";
然后我接受对象并解码以获得搜索数组...
$search = json_decode($searchmap, true);
如果我的体重和体型被设置为空或者是一个空字符串'我会有像这样的雄辩代码..
$gadgets = Gadget::where('color', '=', $search['color'])
->where('height', '=', $search['height'])
->where('width', '=', $search['width'])
->paginate(9);
如果他们有价值,那么雄辩的代码就像这样......
$gadgets = Gadget::where('color', '=', $search['color'])
->where('height', '=', $search['height'])
->where('width', '=', $search['width'])
->where('weight', '=', $search['weight'])
->where('size', '=', $search['size'])
->paginate(9);
有没有办法动态完成此任务。
我认为这个问题应该是在哪里根据给定的参数动态链接句子?
在伪上下文中,我希望做这样的事情
$gadgets = Gadget::
foreach ($search as $key => $parameter) {
if ( $parameter <> '' ) {
->where($key, '=', $parameter)
}
}
->paginate(9);
可以用类似的方式链接where子句吗?
感谢您抽出宝贵时间来看看这个!
更新
我也想出了类似的东西似乎运作良好但我想欢迎建议,如果改进是一个好主意。
$gadgets = New Gadget();
foreach ($search as $key => $parameter) {
if($parameter != ''){
$gadgets = $gadgets->where($key, '=', $parameter);
}
}
$gadgets = $gadgets->paginate(9);
FINAL
感谢下面的@lukasgeiter,我想我会选择这个
$gadgets = Gadget::whereNested(function($query) use ($search) {
foreach ($search as $key => $value)
{
if($value != ''){
$query->where($key, '=', $value);
}
}
}, 'and');
$gadgets = $gadgets->paginate(9);
答案 0 :(得分:7)
这很容易。 Laravel的where
函数允许您传入一组键值对。
$searchmap = array(
'color' => 'red',
'height' => '1'
// etc
);
$gadgets = Gadget::where($searchmap)->paginate(9);
如果您感到好奇,那就是来源(\Illuminate\Database\Query\Builder
)
public function where($column, $operator = null, $value = null, $boolean = 'and')
{
// If the column is an array, we will assume it is an array of key-value pairs
// and can add them each as a where clause. We will maintain the boolean we
// received when the method was called and pass it into the nested where.
if (is_array($column))
{
return $this->whereNested(function($query) use ($column)
{
foreach ($column as $key => $value)
{
$query->where($key, '=', $value);
}
}, $boolean);
}
// many more lines of code....
}
要对它进行更多控制(例如将“=”更改为另一个比较运算符),请尝试使用laravel直接在内部使用的代码:
$gadgets = Gadget::whereNested(function($query) use ($searchmap)
{
foreach ($searchmap as $key => $value)
{
if($value != ''){
$query->where($key, '=', $value);
}
}
}, 'and')->paginate(9);
答案 1 :(得分:1)
对于任何需要它的人来说,这里是lukasgeiter的一个修改版本的答案,它解决了可变数量的问题&#39;问题同时还允许(1)每个where
子句的不同运算符和(2)当你的一个&#34; whebe&#34;时也使用whereIn
的能力。必须能够匹配多个值中的一个(下面的函数检测何时传递值数组,因此使用whereIn
而不是where
)。
开头(下面)的$paramSets
变量赋值实质上描述了如何使用它。
$paramSets = [
"size"=>["op"=>"=","values"=>"large"],
"production_date"=>["op"=>">=","values"=>"2015-12-31"],
"color"=>["op"=>"=","values"=>["red","blue"]],
"name"=>["op"=>"like","values"=>"M%"]
];
$items = db::table('products')
->whereNested(function($query) use ($paramSets) {
foreach ($paramSets as $k => $v)
{
if ($v != ''){
if (is_array($v["values"])){
$query->whereIn($k,$v["values"]);
}
else {
$query->where($k, $v["op"], $v["values"]);
}
}
}
}, 'and');
dd($items->get());