
当用户提交空搜索关键词时,Laravel 应返回全部商品列表而非空响应;本文介绍两种优雅方案:使用 when() 条件查询构建器或手动链式条件判断,确保搜索接口健壮且符合 RESTful 设计原则。
当用户提交空搜索关键词时,laravel 应返回全部商品列表而非空响应;本文介绍两种优雅方案:使用 `when()` 条件查询构建器或手动链式条件判断,确保搜索接口健壮且符合 restful 设计原则。
在 Laravel 9 构建搜索 API 时,一个常见误区是将空查询视为无效输入而直接跳过逻辑,导致接口对空字符串(如 /products/search/ 或 /products/search/?title=)返回空结果集。这不仅违背用户直觉(空搜索通常应表示“查看所有”),也影响 API 的可用性与兼容性。
正确的做法是将空查询视为无筛选条件,即退化为全量分页查询。以下是两种推荐实现方式:
✅ 方案一:使用 when() 条件查询(推荐)
Laravel 内置的 when() 方法专为动态条件设计,语义清晰、链式流畅,且自动忽略 false/null/空字符串等 falsy 值:
public function searchTitle(Request $request, string $title = '')
{
$pageSize = $request->input('page_size', 10);
return Product::when(!empty(trim($title)), function ($query) use ($title) {
return $query->where('title', 'LIKE', '%' . trim($title) . '%');
})->paginate($pageSize);
}
? 注意:我们使用
trim($title)防止前后空格导致误判,并用!empty()确保严格校验(避免" "被当作有效关键词)。
✅ 方案二:显式构建查询实例
适用于逻辑更复杂或需复用查询对象的场景:
public function searchTitle(Request $request, string $title = '')
{
$pageSize = $request->input('page_size', 10);
$query = Product::query();
if (!empty(trim($title))) {
$query->where('title', 'LIKE', '%' . trim($title) . '%');
}
return $query->paginate($pageSize);
}
⚠️ 补充注意事项
-
路由参数 vs 查询参数:当前路由
/{title?}将关键词作为路径段,易受 URL 编码和空格影响。更规范的做法是改用查询参数:// 路由改为 Route::get('/products/search', [ProductController::class, 'searchTitle']); // 请求示例:/products/search?title=phone&page_size=20对应方法签名调整为
public function searchTitle(Request $request),从$request->query('title')获取值。 SQL 注入防护:
LIKE查询中已通过字符串拼接%...%,但务必确保$title已过滤(trim()+htmlspecialchars()非必需,因LIKE不执行 SQL 代码;但建议对前端传入做基础验证)。性能提示:若数据量大,应对
title字段添加数据库索引(如 MySQL 的FULLTEXT或常规 B-tree 索引),并考虑引入 Scout 实现全文检索。
综上,无论选择 when() 还是显式构建,核心原则是:空搜索 ≠ 错误,而是无筛选的默认视图。遵循此逻辑,你的 Laravel 搜索接口将更健壮、可维护且用户体验更佳。











