
本文详解如何在 laravel 中根据用户请求参数动态添加 where 条件,避免拼接 sql 字符串,安全高效地构建可扩展查询。
本文详解如何在 laravel 中根据用户请求参数动态添加 where 条件,避免拼接 sql 字符串,安全高效地构建可扩展查询。
在 Laravel 开发中,常需根据表单提交的筛选字段(如地址、状态、年龄等)动态向查询中追加 WHERE 条件。与原生 PHP 拼接 SQL 字符串(如 .$insert1." ".$insert2)不同,Laravel 的查询构造器支持链式、条件式构建,既防止 SQL 注入,又保持代码清晰可维护。
✅ 正确做法:链式调用 where() + 条件判断
以问题中的场景为例——需根据 $request 中是否存在 add_1、add_2 等字段,动态添加非空校验( ''),可改写为:
use Illuminate\Support\Facades\DB;
$query = DB::table('users')
->join('user_infos', 'user_infos.user_id', '=', 'users.id')
->where('users.ustatus', '=', 1) // 原固定条件
->select('users.*', 'user_infos.add1', 'user_infos.add3');
// 动态添加条件:仅当请求中存在且非空时生效
if ($request->filled('add_1')) {
$query->where('user_infos.add1', '<>', '');
}
if ($request->filled('add_2')) {
$query->where('user_infos.add2', '<>', '');
}
if ($request->filled('name')) {
$query->where('users.name', 'like', "%{$request->name}%");
}
$baseUsers = $query->paginate(3);? filled() 方法比 has() 更精准:它同时检查键是否存在 且值非空(排除 null、''、[]、0 等 falsy 值),天然适配“非空校验”需求;而 has() 仅判断键是否存在(包括空字符串)。
? 进阶技巧:批量条件处理与复用
若筛选字段较多,可封装为循环逻辑提升可读性:
$dynamicFields = [
'add1' => 'user_infos.add1',
'add2' => 'user_infos.add2',
'city' => 'user_infos.city',
'status' => 'users.status',
];
foreach ($dynamicFields as $inputKey => $dbColumn) {
if ($request->filled($inputKey)) {
$query->where($dbColumn, '<>', '');
}
}如需支持多类型条件(等于、范围、模糊搜索),可进一步扩展为映射数组:
$filters = [
'name' => ['column' => 'users.name', 'operator' => 'like', 'value' => "%{$request->name}%"],
'min_age' => ['column' => 'users.age', 'operator' => '>=', 'value' => $request->min_age],
'add1' => ['column' => 'user_infos.add1','operator' => '<>', 'value' => ''],
];
foreach ($filters as $key => $config) {
if ($request->filled($key) && isset($config['value'])) {
$query->where($config['column'], $config['operator'], $config['value']);
}
}⚠️ 注意事项与最佳实践
永远避免字符串拼接 SQL:手动拼接 $insert1 易引发 SQL 注入与语法错误,Laravel 查询构造器自动参数绑定,从根本上杜绝风险。
慎用 whereRaw():仅在必须写原生表达式时使用,并确保参数经 ? 占位符绑定,例如:
->whereRaw('TRIM(user_infos.add1) != ?', [''])分页前完成所有条件添加:paginate() 会触发查询执行,条件必须在调用前全部注册。
-
考虑使用 Eloquent 替代 Query Builder:若模型已定义关联(如 User::with('userInfo')),结合 when() 方法更优雅:
$users = User::where('ustatus', 1) ->with('userInfo:id,user_id,add1,add3') ->when($request->filled('add_1'), function ($q) { return $q->whereHas('userInfo', fn ($sub) => $sub->where('add1', '<>', '')); }) ->paginate(3);
通过合理运用 where()、filled()、when() 等方法,你不仅能安全、灵活地实现动态查询,还能让代码具备良好的可测试性与可维护性。记住:Laravel 的核心优势之一,正是将复杂 SQL 构建转化为语义化、面向对象的操作。

















