thinkphp6搜索器是将字段查询逻辑从控制器移入模型的规范机制,需定义为public方法且命名严格为search+字段驼峰名+attr,通过withsearch显式调用,支持链式分页排序。

ThinkPHP6 的搜索器不是语法糖,而是把字段查询逻辑从控制器里“请”进模型的规范机制。它让多条件搜索变得可维护、可复用,也避免了控制器里堆砌 where 条件。
搜索器怎么写:命名和结构必须严格
每个搜索器对应一个 public 方法,方法名格式固定为 search + 字段驼峰名 + Attr。比如数据库字段是 goods_cate_id,那方法名就是 searchGoodsCateIdAttr,不能少 Attr,不能写成 searchGoodsCateIDAttr 或 searchGoodsCateAttr。
方法接收两个核心参数:$query(当前查询对象)和 $value(传入的搜索值)。你可以根据业务需要决定如何拼条件:
- 精确匹配:
$query->where('status', $value); - 模糊查询:
$query->where('title', 'like', '%'.$value.'%'); - IN 查询:
$query->where('class_tree_id', 'in', $value); - 空值安全处理(如搜索值为空时跳过):
if (!empty($value)) { $query->where(...); }
搜索器怎么用:withSearch 是唯一入口
搜索器不会自动运行,必须显式调用 withSearch() 才会触发。它接收两个参数:字段名数组(对应搜索器前缀)和实际搜索值数组。
例如控制器中这样写:
$list = Books::withSearch(['title', 'status'], [<br> 'title' => $this->request->param('title', ''),<br> 'status' => $this->request->param('status', '')<br>])->paginate(15);
框架会自动查找 searchTitleAttr 和 searchStatusAttr 方法,并把对应值传进去执行。没传的字段不触发,值为空时由你在搜索器里控制是否忽略。
结合分页与排序:链式调用很自然
搜索器本身只管加 where 条件,其他查询行为(排序、分页、关联预载)可以无缝接在后面:
- 按创建时间倒序:
->order('create_time', 'desc') - 再按排序字段升序:
->order('sort', 'asc') - 分页取 10 条:
->paginate(10) - 关联查分类名称:
->with(['category' => function ($q) { $q->field('id,name'); }])
整个链式调用清晰表达了“先筛选、再组织、最后分页”的数据获取流程,逻辑一目了然。
常见陷阱与建议
新手容易踩的坑集中在命名和触发时机上:
- 方法不是 public?—— 搜索器直接失效
- 字段名用了下划线但驼峰写错(如
user_name写成searchUserNameAttr而不是searchUserNameAttr)?—— 方法找不到 - 忘了调用
withSearch,只写了where?—— 搜索器完全不运行 - 搜索值为 null 或空字符串却没判断就直接拼 SQL?—— 可能查出意外结果或报错
建议在每个搜索器开头加 if (is_null($value) || $value === '') return;,保证健壮性。调试时可用 getLastSql() 查看最终生成的 SQL,确认条件是否如预期加入。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











