Laravel怎么实现搜索功能_Laravel使用Eloquent实现模糊查询与多条件搜索【实例】

发布时间 - 2025-12-26 00:00:00    点击率:
Eloquent 模糊搜索应使用 where('field', 'like', "%{$keyword}%") 安全绑定,禁用 whereRaw 拼接;多条件搜索推荐 when() 链式调用避免嵌套。

where()like 做基础模糊搜索

直接在 Eloquent 查询中拼接 LIKE 是最常见写法,但要注意 SQL 注入风险。Laravel 提供了安全的参数绑定方式,别手写 "%{$keyword}%" 拼字符串。

比如搜索用户昵称包含 “admin”:

use App\Models\User;

$users = User::where('nickname', 'like', '%admin%')->get();

如果关键词来自请求,必须用变量绑定:

$keyword = $request->input('q', '');
$users = User::where('nickname', 'like', "%{$keyword}%")->get();
  • ⚠️ 错误示范:whereRaw("nickname LIKE '%{$keyword}%'") —— 无过滤时极易被注入
  • ✅ 正确做法:用 like 操作符 + 双引号包裹带百分号的变量,Laravel 自动转义
  • ? 区分大小写取决于数据库配置(如 MySQL 默认不区分,PostgreSQL 区分),需要统一可用 ilike(PostgreSQL)或 LOWER() 函数

组合多个搜索条件用 when() 避免 if 判断嵌套

当搜索表单有「用户名」「邮箱」「状态」「创建时间范围」等多个可选字段时,硬写一堆 if 会让查询构建逻辑混乱且难维护。when() 是 Laravel 专为这种场景设计的链式条件方法。

$users = User::when($request->filled('name'), function ($query) use ($request) {
    return $query->where('name', 'like', "%{$request->name}%");
})
->when($request->filled('email'), function ($query) use ($request) {
    return $query->where('email', 'like', "%{$request->email}%");
})
->when($request->filled('status'), function ($query) use ($request) {
    return $query->where('status', $request->status);
})
->when($request->filled('start_date'), function ($query) use ($request) {
    return $query->whereDate('created_at', '>=', $request->start_date);
})
->when($request->filled('end_date'), function ($query) use ($request) {
    return $query->whereDate('created_at', '<=', $request->end_date);
})
->paginate(15);
  • filled()has() 更稳妥:它排除空字符串、null0 等“假值”,避免意外匹配
  • ⚠️ 注意日期范围查询:用 whereDate() 而非 where(),否则可能因时间部分不匹配漏数据
  • ? 如果某些字段需精确匹配(如 status)、某些需模糊(如 name),混用 wherewhere(..., 'like', ...) 完全没问题,when() 只是控制是否执行那段逻辑

全文搜索替代方案:MySQL FULLTEXT 或 PostgreSQL tsvector

当数据量上万、模糊查询变慢,或需要支持“相关度排序”“同义词”“中文分词”时,纯 LIKE 就力不从心了。Laravel 本身不封装全文索引,但可调用底层能力。

MySQL 示例(需提前建 FULLTEXT 索引):

ALTER TABLE users ADD FULLTEXT(name, email);

然后在查询中用:

$keyword = $request->q;
$users = User::whereRaw("MATCH(name, email) AGAINST(? IN NATURAL LANGUAGE MODE)", [$keyword])
    ->orderByRaw("MATCH(name, email) AGAINST(?) DESC", [$keyword])
    ->get();
  • ⚠️ 中文支持弱:MySQL 原生 FULLTEXT 对中文按字切分效果差,需配合 ngram 插件或改用 Elasticsearch
  • ✅ PostgreSQL 的 to_tsvector + to_tsquery 对中文更友好(配合 zhparser 扩展)
  • ? Laravel Scout 是官方推荐的扩展方案,但它是独立服务(Algolia / Meilisearch / TNTSearch),不是“开箱即用”的 Eloquent 方法,上线前得权衡部署成本

搜索结果分页时保留查询参数

paginate() 后点击第2页,URL 里搜索关键词丢了——这是新手最常踩的坑。Laravel 的 appends() 就是干这个的。

$users = User::when(...)->paginate(15);

// 在 Blade 中渲染分页时:
{{ $users->appends(request()->query())->links() }}

更稳妥的做法是只追加关键搜索字段,避免把无关参数(如 _token)也带上:

{{ $users->appends(request()->only(['q', 'status', 'start_date', 'end_date']))->links() }}
  • ⚠️ 不要用 withQueryString()(Laravel 9+ 新增),它会无差别携带所有 query,可能暴露敏感参数
  • only() 显式声明要保留的键,清晰可控
  • ? 如果用了路由模型绑定或中间件修改了 request,确保 request()->only(...) 获取的是最终实际用于搜索的值
Eloquent 搜索看着简单,但多条件组合、参数透传、性能边界、中文支持这几处最容易出问题。尤其是 when() 的闭包里 use 变量和 paginate 后 appends 的配合,线上一疏忽就返回空结果还查不出原因。


# mysql  # word  # laravel  # app  # ai  # 邮箱  # red  # sql  # 中间件  # NULL  # if  # 封装  # 字符串  #   # 闭包  # elasticsearch  # postgresql  # 数据库  # 关键词  # 链式  # 绑定  # 多个  # 分页  # 多条  # 的是  # 这是  # 看着  # 切分 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 香港服务器部署网站为何提示未备案?  深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?  中国移动官方网站首页入口 中国移动官网网页登录  php结合redis实现高并发下的抢购、秒杀功能的实例  Laravel表单请求验证类怎么用_Laravel Form Request分离验证逻辑教程  浅谈Javascript中的Label语句  java中使用zxing批量生成二维码立牌  如何快速搭建高效可靠的建站解决方案?  Mybatis 中的insertOrUpdate操作  Edge浏览器提示“由你的组织管理”怎么解决_去除浏览器托管提示【修复】  html5如何设置样式_HTML5样式设置方法与CSS应用技巧【教程】  Laravel如何获取当前登录用户信息_Laravel Auth门面使用与Session用户读取【技巧】  阿里云高弹*务器配置方案|支持分布式架构与多节点部署  Gemini怎么用新功能实时问答_Gemini实时问答使用【步骤】  重庆市网站制作公司,重庆招聘网站哪个好?  Laravel如何将应用部署到生产服务器_Laravel生产环境部署流程  免费网站制作appp,免费制作app哪个平台好?  微信小程序 scroll-view组件实现列表页实例代码  Python文件操作最佳实践_稳定性说明【指导】  如何快速查询网站的真实建站时间?  如何获取PHP WAP自助建站系统源码?  Laravel任务队列怎么用_Laravel Queues异步处理任务提升应用性能  Linux虚拟化技术教程_KVMQEMU虚拟机安装与调优  Laravel如何部署到服务器_线上部署Laravel项目的完整流程与步骤  Laravel怎么集成Vue.js_Laravel Mix配置Vue开发环境  公司门户网站制作流程,华为官网怎么做?  Bootstrap整体框架之CSS12栅格系统  Laravel怎么连接多个数据库_Laravel多数据库连接配置  网站优化排名时,需要考虑哪些问题呢?  php打包exe后无法访问网络共享_共享权限设置方法【教程】  网站制作企业,网站的banner和导航栏是指什么?  如何在企业微信快速生成手机电脑官网?  高防网站服务器:DDoS防御与BGP线路的AI智能防护方案  Laravel怎么使用Blade模板引擎_Laravel模板继承与Component组件复用【手册】  Laravel如何自定义分页视图?(Pagination示例)  Google浏览器为什么这么卡 Google浏览器提速优化设置步骤【方法】  制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?  如何快速搭建二级域名独立网站?  在线制作视频的网站有哪些,电脑如何制作视频短片?  Win11怎样安装网易有道词典_Win11安装词典教程【步骤】  Win11怎么关闭专注助手 Win11关闭免打扰模式设置【操作】  怎样使用JSON进行数据交换_它有什么限制  Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】  Gemini手机端怎么发图片_Gemini手机端发图方法【步骤】  Windows10电脑怎么查看硬盘通电时间_Win10使用工具检测磁盘健康  Laravel如何使用Facades(门面)及其工作原理_Laravel门面模式与底层机制  Win11关机界面怎么改_Win11自定义关机画面设置【工具】  JavaScript数据类型有哪些_如何准确判断一个变量的类型  如何将凡科建站内容保存为本地文件?  香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南