ThinkPHP5.0链式查询安全关键在于动态条件须先校验再拼接:字符串用isset+strlen,数字用is_numeric,时间需非空再组合between;优先数组传参where(),复杂逻辑用闭包分组确保AND/OR优先级,严禁字符串拼接SQL。

ThinkPHP5.0链式查询拼接参数,关键不是“能不能链”,而是“链之前有没有把数据筛干净”。直接把用户输入往where()里塞,哪怕用了链式,照样可能查错、漏查,甚至埋下SQL注入隐患。
动态条件必须先过滤再拼接
用户搜索表单里字段常为空或为零值,比如状态选了“0”、时间范围没填、关键词留空——这些值若不加判断就进`where()`,会变成真实SQL条件。 例如: - `->where('status', $params['status'])` 遇到 `$params['status'] = 0`,`!empty(0)` 为 false,条件被跳过 → 查不到 status=0 的数据; - `->where('title', $params['title'])` 遇到 `$params['title'] = ''`,实际执行 `WHERE title = ''` → 返回一堆空标题记录,非预期结果。正确做法是显式校验:
- 字符串字段用
isset($v) && strlen($v) > 0(兼容'0'); - 数字字段用
is_numeric($v)或in_array($v, [0,1,2], true); - 时间范围类用
!empty($start) && !empty($end)再组合between time; - 最后统一用
array_filter($where, function($v) { return $v !== null && $v !== '' && $v !== []; })清理无效项。
优先用数组传参,少用链式拼字段
简单等值查询(如 status=1、type='admin'、deleted_at=null),直接构造关联数组传给 `where()` 更安全、更清晰: ```php $where = []; if (isset($params['status']) && is_numeric($params['status'])) { $where['status'] = $params['status']; } if (!empty($params['keyword'])) { $where['title'] = ['like', "%{$params['keyword']}%"]; } $list = Db::name('article')->where($where)->select(); ``` 这种方式天然规避了链式中“同字段重复覆盖”问题(如连续两次 `->where('id', 1)->where('id', 2)` 只生效后者),也避免循环中因条件缺失导致整条查询失效。复杂逻辑才用链式,且需注意OR与括号
含 `OR`、闭包嵌套、`IN`、`BETWEEN`、`NULL` 判断等场景,链式更灵活: ```php $query = Db::name('user'); if ($hasRole) { $query->where('role', 'in', $roles); } if ($isLocked) { $query->whereOr('status', 0)->whereOr('locked', 1); // 注意:这会生成 OR 关系,但无括号包裹 } // 更稳妥写法(显式分组): $query->where(function ($q) use ($roles) { $q->where('role', 'in', $roles)->whereOr('type', 'vip'); }); ``` ThinkPHP5.0对 `whereOr` 的括号自动包裹有局限,多条件混用 `AND`/`OR` 时,务必用闭包明确逻辑分组,否则 SQL 优先级错乱,结果不可控。杜绝字符串拼接,坚持参数绑定
任何情况下都不要这样写: ```php // ❌ 危险!可能被注入 Db::query("SELECT * FROM user WHERE name = '" . input('name') . "'"); ``` 即使要写原生SQL,也必须用参数绑定: ```php // ✅ 安全 Db::query("SELECT * FROM user WHERE name = ? AND status = ?", [input('name'), 1]); ``` 框架的 `where()`、`whereRaw()`(配合参数数组)、`value()` 等方法底层均走PDO预处理,只要不手动拼SQL,数据与指令就天然分离。不复杂但容易忽略。



















