ThinkPHP按名称排序核心是order()方法,需注意字段安全、中文首字母处理及多字段组合排序。基础用法为->order('name', 'asc/desc')或数组形式;中文需提取拼音首字母并映射;用户输入字段须白名单校验;多字段排序推荐数组方式->order(['name'=>'asc','id'=>'desc'])。

ThinkPHP 按名称排序,核心是用 order() 方法指定字段和方向,但新手容易忽略字段安全、中文首字母处理、多字段组合等细节。下面分几种常见场景讲清楚。
基础按 name 字段升序或降序
最常用也最直接的方式:查数据时加 order()。
- 升序(A→Z):
->order('name', 'asc')或简写为->order('name')(默认就是 asc) - 降序(Z→A):
->order('name', 'desc') - 推荐用数组写法(尤其 TP6/8),更安全清晰:
->order(['name' => 'asc'])
中文姓名按首字母分组排序
数据库里存的是“张三”“李四”,想按拼音首字母 A/B/C… 分组展示,不能直接 order('name'),得先提取首字母再排序。
- 写一个辅助方法获取首字母(支持 UTF-8 中文):
public function getFirstChar($str) {
if (empty($str)) return '#';
$first = mb_substr($str, 0, 1, 'UTF-8');
if (ord($first) > 127) { // 是汉字
$arr = ['啊'=> 'A','八'=> 'B','擦'=> 'C','搭'=> 'D','婀'=> 'E','发'=> 'F','噶'=> 'G','哈'=> 'H','击'=> 'J','咔'=> 'K','啦'=> 'L','妈'=> 'M','拿'=> 'N','哦'=> 'O','啪'=> 'P','期'=> 'Q','然'=> 'R','撒'=> 'S','塌'=> 'T','挖'=> 'W','昔'=> 'X','压'=> 'Y','匝'=> 'Z'];
$py = @file_get_contents("https://unpkg.com/pinyin-pro@3.14.0/dist/pinyin-pro.min.js"); // 实际项目建议用服务端拼音库或缓存映射表
// 更稳妥做法:用 mb_substr + 静态映射表或调用系统 iconv + ord 计算(见知识库中的 GB2312 映射逻辑)
return $arr[$first] ?? 'A';
} else {
return strtoupper($first);
}
}
立即学习“PHP免费学习笔记(深入)”;
- 查询后在 PHP 层添加首字母字段,再用
usort()排序,或查出全部后用array_multisort()按首字母键排序 - 如果数据量大,建议在数据库加虚拟列(MySQL 5.7+)或预存拼音首字母字段,避免每次 PHP 处理
用户可选排序字段(比如点击表头切换 name / id / create_time)
前端传过来的字段名不能直接拼进 SQL,否则有注入风险。
- 定义白名单:
$allowFields = ['name', 'id', 'create_time', 'status']; - 接收并校验:
$field = input('sort_field', 'id'); $dir = in_array(input('sort_type'), ['asc', 'desc']) ? input('sort_type') : 'desc'; - 只允许白名单字段:
if (!in_array($field, $allowFields)) { $field = 'id'; } - 安全传参:
->order([$field => $dir])
多字段组合排序(如先按 name 升序,同名再按 id 降序)
一条语句搞定,顺序很重要 —— 前面的优先级更高。
- 数组方式(TP6/8 推荐):
->order(['name' => 'asc', 'id' => 'desc']) - 字符串方式(TP5 兼容,但不推荐用于用户输入):
->order('name asc, id desc') - 注意:字段含点号(如
user.name)或反引号时,数组方式自动加转义,字符串方式需手动写`user`.`name`



















