thinkphp查询表达式是绕过自动类型转换直插sql的底层通道,需用数组表达式如['id'=>['eq',100]]控制运算符,exp允许原生sql但有注入风险,not in等须用下划线命名如['id'=>['not_in',[1,2,3]]]。

ThinkPHP 的查询表达式不是语法糖,而是绕过自动类型转换、直插 SQL 条件的底层通道——用错地方会静默失效,用对了才能写复杂条件。
where() 里传数组表达式怎么写才生效
ThinkPHP 的 where() 支持三种传参形式,但只有数组表达式能明确控制 SQL 运算符。常见错误是把 ['status' => 1] 当成“等于”,其实它等价于 where('status', '=', 1),而数据库字段类型不匹配时(比如 status 是 TINYINT,却传字符串 '1'),PDO 可能直接跳过该条件。
- 必须显式写出表达式键值对:
['id' => ['eq', 100]]或['score' => ['gt', 80]] - 表达式名不区分大小写:
'EQ'、'eq'、'Eq'都行 - 字符串类表达式(如
like)要自己补%:['name' => ['like', '%admin%']],写成'admin'就是全匹配 -
between和in支持字符串或数组:['id' => ['between', '1,10']]和['id' => ['between', [1,10]]]效果一样
EXP 表达式为什么不能随便用
EXP 是唯一允许你手写原生 SQL 片段的表达式,但它不经过任何参数绑定和转义,拼错就直接报错或被注入。它适合字段运算、函数调用这类无法用常规表达式覆盖的场景,比如 score + 1、DATE(created_at)。
- 写法是:
['score' => ['exp', 'score + 1']],注意右侧是字符串,不是 PHP 表达式 - 别在
EXP里拼用户输入:['name' => ['exp', "LIKE '%{$_GET['q']}%'"]]是高危写法 - 它也支持用于更新:
$data['score'] = ['exp', 'score + 1']; $user->save($data); - 如果只是想查
IS NULL,别用['email' => ['exp', 'IS NULL']],直接用whereNull('email')更安全
NOT IN / BETWEEN 这些带空格的表达式怎么写
ThinkPHP 把带空格的 SQL 关键字(如 NOT IN、NOT BETWEEN)统一处理为下划线命名,这是硬编码规则,不是配置项。写错格式会导致条件被忽略,且无报错提示。
- 正确写法:
['id' => ['not_in', [1,2,3]]]、['age' => ['not_between', [18,60]]] - 错误写法:
['id' => ['NOT IN', [1,2,3]]](大写+空格)、['id' => ['not in', [1,2,3]]](空格没换下划线) -
['status' => ['null']]等价于IS NULL,但推荐用whereNull(),语义更清晰 - 所有表达式最终生成的 SQL 都是小写,所以不用纠结大小写,但关键字连接符(
_)不能省
真正容易被忽略的是:表达式只影响 WHERE 子句的生成逻辑,它不改变字段类型映射,也不触发模型事件。如果你发现条件没进 SQL,先检查是不是表达式名拼错了下划线,而不是急着加日志或换 ORM。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











