ThinkPHP 3.1 查询语言详解:从基础到高级用法
ThinkPHP 框架提供了灵活的查询语言,通过连贯操作简化复杂的业务逻辑需求。本文详细讲解如何通过字符串、数组和对象构建 WHERE 条件,使用表达式、快捷、区间及组合查询实现多样化筛选,并结合统计、动态及子查询方法,全面掌握该版本的 ORM 数据操作技巧。
查询条件的基本构建方式
ThinkPHP 的查询语言核心在于 where 方法等连贯操作。虽然底层支持原生 SQL,但框架封装了多种条件传入方式,既保证了安全性,又提升了开发效率。主要支持以下三种输入格式:
第1步:使用字符串作为查询条件
目的:最传统的方式,适用于简单且确定的固定条件。
动作直接将 SQL 片段传入 where。
$User = M("User");
$User->where('type=1 AND status=1')->select();
生成结果:SELECT * FROM think_user WHERE type=1 AND status=1。
注意:此方式存在 SQL 注入风险,若需使用字符串,建议配合预处理机制或白名单过滤。
第2步:使用索引数组作为查询条件(推荐)
目的:利用框架自动转义字段值,提高安全性,这是最常用的方式。
动作构建键值对数组,默认逻辑为 AND。
$User = M("User");
$condition['name'] = 'thinkphp';
$condition['status'] = 1;
$User->where($condition)->select();
生成结果:SELECT * FROM think_user WHERE `name`='thinkphp' AND status=1。
扩展参数:可通过 _logic 键定义逻辑关系。
$condition['_logic'] = 'OR'; // 将默认的 AND 改为 OR
第3步:使用对象方式查询
目的:兼容部分特定场景,效果与数组查询相同。
$condition = new stdClass();
$condition->name = 'thinkphp';
$condition->status = 1;
$User->where($condition)->select();
尽管可用,但在大多数情况下建议使用数组方式,因其更高效且易于维护。
表达式查询与进阶操作
当简单的相等判断无法满足需求时,可使用 TP 特有的表达式语法:$map['字段名'] = array('表达式', '查询条件');。表达式不区分大小写。
常用表达式对照
- EQT / NEQ / GT / EGT / LT / ELT:分别对应等于(=)、不等于(<>)、大于(>)、大于等于(>=)、小于(<)、小于等于(<=)。
- LIKE / NOT LIKE:模糊查询。支持通配符
%。 - BETWEEN / NOT BETWEEN:区间查询,支持字符串
'1,8'或数组array('1','8')。 - IN / NOT IN:集合查询,支持逗号分隔字符串或数组。
- EXP:表达式查询,允许执行原生 SQL 片段(如函数调用),
$data['score'] = array('exp', 'score+1');。
快捷查询简化代码
通过分隔符在一次操作中完成多字段匹配:
不同字段相同条件(| 代表 OR):$map['name|title'] = 'thinkphp'; 生成 name = ... OR title = ...。
不同字段不同条件(& 代表 AND):$map['status&title'] = array('1', 'thinkphp', '_multi' => true); 生成 status = 1 AND title = ...。
注意:在同一查询中,| 和 & 不能混用。
区间查询(Zone Query)
针对同一个字段的多个条件组合:
// 大于3 且 小于10 (默认AND)
$map['id'] = array(array('gt', 3), array('lt', 10));
// 可追加第三个参数指定逻辑: array('gt', 1), array('lt', 10), 'or'
组合查询(Complex Query)
混合多种查询模式:
- _string:强制插入字符串条件,如
$map['_string'] = 'status=1 AND score>10';。 - _complex:嵌套子数组作为完整条件组,适合组装复杂子句。
- _query:类似 URL 参数形式,如
$map['_query'] = 'status=1&score=100';。
聚合统计与原生 SQL 操作
统计查询
TP 提供了专用的聚合方法,均支持连贯操作链:
$count = $Model->count(); // 记录总数
$maxScore = $Model->max('score'); // 最大值
$avgScore = $Model->avg('score'); // 平均值
原生 SQL 接口
对于极度复杂的查询,TP 保留了两个直接执行原生命令的方法:
query():仅用于读操作,返回数据集。例如:$Model->query(
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









