查询构造器防sql注入靠pdo预处理实现物理隔离,where等方法天然安全;whereraw需手动绑定,表名列名等标识符必须白名单校验。

查询构造器防 SQL 注入,靠的不是“过滤”,而是让数据库压根不把用户输入当 SQL 代码解析——只要用对方法,where()、whereIn()、update() 这些调用天然安全。
where() 等标准方法为什么不用手动绑定?
因为底层走的是 PDO 预处理:SQL 模板(如 SELECT * FROM users WHERE id = ?)先发给数据库编译,参数值(如 $id)后传,两者物理隔离。数据库执行时,$id 只进内存槽位,不经过 SQL 解析器。
-
User::where('email', $request->email)->first()—— 即使$request->email是"admin' -- ",也只会查邮箱字段等于这个完整字符串的记录 -
DB::table('orders')->whereIn('status', $statuses)——$statuses是数组也没问题,框架自动展开为IN (?, ?, ?)并一一绑定 - 模糊匹配也一样:
where('name', 'like', "%{$search}%")中的%是 PHP 字符串拼接,$search本身仍被参数化
whereRaw() 是唯一需要你动手的地方
whereRaw() 绕过自动绑定,等于把 SQL 构造权交给你。不绑定,就等于裸奔。
PHP中文网提供Laravel 13.2.0版本下载,Laravel框架 是基于 PHP 8.3+ 的高性能框架,官方推荐通过 Composer 安装。它内置 AI SDK、JSON:API Resources 及原生向量搜索,支持属性驱动开发与队列路由,大幅提升开发效率。相比旧版,13.2.0 优化了缓存 TTL 管理与实时通信,无需 Redis 即可横向扩展。作为现代 Web 开发首选,它兼顾安全与极速体验,助您快速构建企业级应用。
- 危险写法:
whereRaw("email LIKE '%{$q}%'")——$q里的单引号、括号、UNION全部被数据库当作语法执行 - 安全写法一(位置占位):
whereRaw("email LIKE ?", ['%' . $q . '%']) - 安全写法二(命名绑定):
whereRaw("email LIKE :pattern", ['pattern' => '%' . $q . '%']) - 更推荐:直接用
where('email', 'like', "%{$q}%"),语义清晰,零风险,还少写 raw
表名、列名、排序字段无法参数化,必须白名单校验
占位符 ? 只能绑值(values),不能绑标识符(identifiers)。所以 DB::table($table)、orderBy($field)、select("col_{$suffix}") 这类操作,变量必须提前验证。
- 错误示例:
DB::table('products')->select("product_varient_{$variant_id}")—— 若$variant_id是"1 UNION SELECT password FROM users--",可能触发列名注入 - 请求级验证(首选):
'variant_id' => 'required|in:1,2,3',Laravel 自动转整型并拦截非法值 - 运行时校验:
in_array($variant_id, [1, 2, 3], true),适用于非 HTTP 上下文(如队列任务) - 不要只靠
(int)$variant_id:强转后是整数,但若该变量后续用于日志、缓存 key 或其他拼接场景,仍有隐患
真正容易被忽略的点在于:安全不是“用了查询构造器就万事大吉”,而是要清楚哪里自动防护、哪里必须人工设防——whereRaw 的参数绑定和标识符的白名单校验,这两处一旦漏掉,前面所有自动防护都归零。










