ThinkPHP升序排序新手教程
作者:技术拾光时间:2026-07-15 19:32:06浏览:115
在ThinkPHP框架中,升序排序通过调用order()方法并指定字段及asc关键字实现。处理用户输入时,必须使用白名单过滤字段和排序方向,以防止SQL注入风险。多字段排序需使用关联数组定义规则,模型默认排序可通过设置$order属性完成。
ThinkPHP 里的升序排序,本质是调用 order() 方法指定字段和排序方向。新手常犯的错误是直接拼接用户传入的参数,导致报错甚至 SQL 注入。本文拆解常见场景,并提供安全写法。
基础写法:使用 order() 指定字段和 asc
最直接的方式是调用 order() 方法,传入字段名加 "asc"(表示升序)。例如:
User::order('id asc')->select();→ 按 id 升序查询用户列表Article::order('create_time asc')->limit(10)->select();→ 按发布时间从早到晚取前 10 条- 字段名可以是模型属性,也可以是数据库中的真实字段名,如
'status'、'title'
这种写法适用于排序字段和方向在代码中写死的场景。一旦涉及用户输入,需要改用安全写法。

安全写法:动态排序必须校验字段和方向
若排序字段或方向来自 URL 参数,例如 field=name&dir=asc,切勿直接拼接字符串。正确的做法是使用白名单过滤:
- 先定义允许的字段列表:
$allowedFields = ['id', 'name', 'create_time', 'score']; - 再定义允许的方向列表:
$allowedDirs = ['asc', 'desc']; - 取值后校验,若不在白名单中则 fallback 到默认值:
$field = in_array($request->param('field'), $allowedFields) ? $request->param('field') : 'id'; - 最后使用数组语法传参:
User::order([$field => $dir])->select();——ThinkPHP 会自动转义,SQL 注入风险基本为零
这一步容易被忽略,但项目上线后许多问题都源于此。
多字段升序:使用数组一次定义多个规则
需要先按 A 升序,A 相同时再按 B 升序?关联数组写法最清晰:
User::order(['status' => 'asc', 'create_time' => 'asc'])->select();- 等价于 SQL 中的
ORDER BY status ASC, create_time ASC - 注意:避免混用字符串和数组写法。例如
['name asc', 'age desc']是旧式写法,现在推荐键值对格式,更规范也更安全
模型默认升序:设置 protected $order 属性
如果某个模型每次查询都想自动按固定字段升序,无需重复写 order(),直接在模型类中声明即可:
- TP6 写法:
protected $order = 'sort asc'; - TP5 写法:
protected $resultSetType = 'collection'; protected $order = 'sort asc'; - 这样调用
User::select()会自动带升序,简化代码 - 若需临时覆盖,后续再调用一次
order()即可替换默认排序
升序排序本身不难,难点在于根据不同场景选择正确写法并规避风险。以上几种方式覆盖了日常开发中的大部分需求,按此操作基本不会出问题。
