usort()配合匿名函数可按字符串长度升序排序索引数组,返回strlen($a)-strlen($b)确保正确性;需保留键名则用uasort();注意多字节字符应使用mb_strlen()。

用 usort() 配合匿名函数按字符串长度排序
PHP 索引数组默认不支持直接按元素字符串长度排序,必须用自定义比较逻辑。usort() 是最直接、最可控的方式,它会原地修改数组并重排键名(索引从 0 开始连续递增)。
常见错误是误用 sort() 或 asort() —— 它们只按字典序或值大小排,完全不关心长度。
- 必须传入一个返回整数的比较函数:负数表示前者小,正数表示后者小,0 表示相等
- 别在函数里用
strlen($a) > strlen($b)直接返回布尔值——PHP 会把它转成 1/0,导致所有“相等长度”都被当成“前者更小”,排序错乱 - 推荐写法:
return strlen($a) - strlen($b);,天然支持升序;降序就反过来
$arr = ['hi', 'hello', 'a', 'world'];
usort($arr, function($a, $b) {
return strlen($a) - strlen($b);
});
// 结果:['a', 'hi', 'hello', 'world'](注意键已重置为 0,1,2,3)
要保留原始键名?用 uasort()
如果数组带语义化索引(比如 ['name' => 'Alice', 'city' => 'Beijing']),又想按值的字符串长度排,但不能丢掉键名,就得换 uasort()。
它和 usort() 的区别只有两点:保留键名关联、参数顺序一样(仍是 $a 和 $b 值参与比较)。
-
uasort()不改变键名,只重排顺序,适合配置项、映射类数据 - 如果键是数字且你希望保持原有索引(如 2=>‘foo’, 5=>‘bar’),它也能做到;而
usort()一定会变成 0,1,2… - 同样禁止返回布尔值,必须用减法或三元表达式
$data = [0 => 'cat', 2 => 'elephant', 5 => 'dog']; uasort($data, fn($a, $b) => strlen($a) - strlen($b)); // 结果:[0 => 'cat', 5 => 'dog', 2 => 'elephant'](键没变,只按长度重排)
性能和兼容性注意点
对几千个元素以内的字符串数组,usort() 和 uasort() 性能差异可忽略。但有三个实际容易踩的坑:
- PHP 7.4+ 才支持箭头函数(
fn()),老项目得用function($a,$b){} - 如果数组里混了非字符串值(
null、数字、数组),strlen()会静默转成字符串再算长度(比如strlen(123)是 3,strlen(null)是 0),可能不是你想要的行为 - 多字节字符(中文、emoji)用
strlen()会按字节算,不是字符数;真要按“字符长度”得换mb_strlen($a, 'UTF-8')
不想改原数组?先 array_values() 或 array_copy
usort() 和 uasort() 都是引用传参,直接修改原数组。如果需要保留原始顺序另存一份排序结果,得手动复制:
- 纯索引数组:用
$sorted = array_values($arr); usort($sorted, $callback); - 关联数组且要保留键:用
$sorted = $arr; uasort($sorted, $callback);(PHP 数组赋值默认浅拷贝) - 别用
clone—— 数组不是对象,clone无效
PHP 数组排序本身不难,但“按字符串长度”这个需求背后常藏着对键名是否保留、字符编码是否多字节、以及非字符串值如何处理的隐含判断——这些地方一不留神,排序结果就和预期对不上。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











