Laravel 框架中 一个搜索框搜多个字段解决方案优化(whereRaw like 参数绑定)
Laravel 框架中 一个搜索框搜多个字段解决方案优化(whereRaw like 参数绑定)
1.缘由
业务需要一个输入框框搜多个字段引起
- name,phone,status 为示例字段
一般情况下,下方写法可满足要求(谢谢下方评论提示,一开始我也是这样写的)demo1:
$list = $list->where(function($query)use($keyword){
$query->where('name', 'like', '%'.$keyword.'%');
$query->orWhere('phone', 'like', '%'.$keyword.'%');
});
但我们的需求中,存储为int数值的字段,在模糊查询时,也要查出来
- 例:状态status字段,数据库中存储为tinyint类型,值为1/2等,表示为‘开始/关闭’,在输入‘关闭’后,也可以查出来
故调整为下方写法demo2:
$list->whereRaw("concat(name,phone, (CASE
WHEN status = ".Model::is_open_no." THEN
'关闭'
WHEN status = ".Model::is_open_yes." THEN
'开启'
END),) like '%".$keywords."%'");
- 为提高文章的可读性,CASE 部分代码在下方demo中不再出现
2.问题
使用demo2实现,没有对sql注入做任何处理,仅输入 like ‘ 或 ‘ 就会报错
,要使用类似于 PDO 参数绑定进行传参,以避免 SQL 注入的风险
3.解决
Laravel 中 whereRaw 方法默认传参为1个参数,查看底层实现如下
public function whereRaw($sql, $bindings = [], $boolean = 'and')
{
$this->wheres[] = ['type' => 'raw', 'sql' => $sql, 'boolean' => $boolean];
$this->addBinding((array) $bindings, 'where');
return $this;
}
第二参数为要绑定的参数。同时在社区wiki中,summer大佬指出要避免sql注入和第二参数的使用方式
3.1 遇到的问题一:参数绑定不生效
对于like模糊查询,按社区wiki中写的如下代码,不生效(打印查看sql应该是没解析成功):失败demo1:
$list = $list->whereRaw("concat(name,phone) like '%?%'",[$keywords]);
在查看PHP PDO之MySQL参数绑定后,实现如下:成功demo1:
$list = $list->whereRaw("concat(name,phone) like ?",["%$keywords%"]);
3.2 遇到的问题二:数据中的某个字段为null时搜索不生效
按demo1实现,在测试过程中发现:如果遇到一条数据某个字段为null的情况下,搜该条数据其他字段,会出现搜不到的情况
示例:[name=’王三’,phone=’’],输入‘王三’时搜不到该条数据
处理:判断字段是否为 null,实现如下:最终demo2:
$list = $list->whereRaw("concat(IFNULL(name,''),IFNULL(phone,'')) like ?",["%$keywords%"]);
4.总结
还是自己对基础掌握不牢,虽然之前都学过,但慢慢的不用也就忘了。
从使用框架的东西后,一些框架封装好的东西直接上手用,但底层的实现都没注意过
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: