一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

thinkphp如何按多个字段降序排序 使用教程

时间:2026-07-21 09:26:48 编辑:袖梨 来源:一聚教程网

ThinkPHP多字段降序排序需用order()传关联数组并逐字段指定'desc',如['create_time'=>'desc','id'=>'desc'];混合排序同理,如['publish_time'=>'desc','title'=>'asc'];必须白名单校验字段与方向,关联表字段排序需避免点号写法。

ThinkPHP按多个字段降序排序,核心是用order()方法传入关联数组,并为每个字段明确指定'desc'方向。不能只写一个desc全局生效,必须逐字段声明;字符串拼接方式既不安全也不推荐,尤其在TP6/8中已明确建议弃用。

多字段都降序的写法

如果所有字段都要降序(比如按创建时间、ID、状态都从高到低排),直接在数组里统一设'desc'

  • ->order(['create_time' => 'desc', 'id' => 'desc', 'status' => 'desc'])
  • 等价于 SQL 中的 ORDER BY create_time DESC, id DESC, status DESC
  • 字段顺序决定优先级:前面的字段先比,相同时才看后面的字段

混合升序和降序的组合

实际业务中常需“主字段降序 + 次字段升序”,例如最新发布的文章优先,同一天发布的按标题字母正序排列:

  • ->order(['publish_time' => 'desc', 'title' => 'asc'])
  • 注意:不能写成['publish_time desc', 'title asc']这种字符串数组,TP6+会报错或忽略
  • 字段名不含空格、点号或反引号,TP会自动处理,无需手动加`

用户可选排序时的安全控制

前端传来的排序字段和方向不能直接拼接,必须白名单校验:

立即学习“PHP免费学习笔记(深入)”;

  • 定义允许字段:$allowFields = ['publish_time', 'title', 'id', 'status'];
  • 校验输入:$field = in_array($request->param('field'), $allowFields) ? $request->param('field') : 'publish_time';
  • 方向只认asc/desc$dir = in_array($request->param('dir'), ['asc', 'desc']) ? $request->param('dir') : 'desc';
  • 最终调用:->order([$field => $dir]),即使只排一个字段,也保持数组写法一致性

关联表字段排序要额外注意

如果涉及with('user')这类关联查询,且需按关联表字段(如user.nickname)排序,order()直接写['user.nickname' => 'desc']会失败:

  • 正确做法是改用view查询或子查询,把关联字段提前查出来再排序
  • 或在模型中定义join后,用真实字段别名(如u_nickname)参与order()
  • 字符串写法order('user.nickname desc')风险极高,字段含点号时几乎必报Column not found

热门栏目