sort($array) сортирует массив по возрастанию, на месте. Функция меняет переданную переменную и возвращает true, поэтому её вызывают отдельной строкой, а потом используют массив. rsort() сортирует по убыванию.
В PHP есть функция сортировки для каждого сочетания "по значению или по ключу", "по возрастанию или по убыванию" и "сохранять ключи или нет":
| Функция | Сортирует по | Порядок | Ключи |
|---|---|---|---|
sort | значению | по возрастанию | перенумерованы 0, 1, 2 |
rsort | значению | по убыванию | перенумерованы |
asort | значению | по возрастанию | сохранены |
arsort | значению | по убыванию | сохранены |
ksort | ключу | по возрастанию | сохранены |
krsort | ключу | по убыванию | сохранены |
usort | вашей функции | на ваш выбор | перенумерованы |
uasort | вашей функции | на ваш выбор | сохранены |
uksort | вашей функции по ключам | на ваш выбор | сохранены |
Сортировка ассоциативного массива по значению
sort() для ассоциативного массива выбрасывает ключи. Используйте asort(), чтобы сортировать по значению и оставить каждый ключ при его значении, или arsort(), чтобы наибольшие шли первыми.
Сортировка массива по ключу через ksort
ksort() упорядочивает по ключу, krsort() по ключу в обратном порядке. Это удобно перед выводом настроек или сборкой строки запроса в стабильном порядке.
Свой порядок через usort и оператор spaceship
usort($array, $callback) позволяет самим задать порядок. Колбэк получает два элемента и возвращает отрицательное число, если первый должен идти раньше, положительное, если раньше второй, и 0, если они равны. Оператор spaceship <=> возвращает ровно это.
У banana и cherry одинаковая длина, поэтому колбэк возвращает для них 0, и они остаются в прежнем порядке. Сортировка в PHP стабильна начиная с PHP 8.0: равные элементы сохраняют прежний порядок.
Сортировка многомерного массива по значению
Чтобы отсортировать список строк по одному полю, сравнивайте это поле в usort. Чтобы сортировать по двум полям, сравнивайте массивы: <=> сравнивает их поэлементно, поэтому второе поле решает только при равенстве первого.
Во втором сравнении $b["age"] стоит слева, а $a["age"] справа, и это переворачивает только порядок по возрасту. array_multisort(array_column($people, 'city'), SORT_ASC, array_column($people, 'age'), SORT_DESC, $people) даёт тот же порядок без колбэка: функция сортирует по извлечённым столбцам и переставляет $people соответственно.
Естественный порядок и флаги сортировки
По умолчанию PHP сравнивает числа как числа, а строки как строки. Имена файлов с числами сортируются неожиданно для людей: img10 идёт раньше img2, а все имена в верхнем регистре раньше всех имён в нижнем. Флаги меняют способ сравнения значений.
SORT_NATURAL читает последовательности цифр как числа, SORT_FLAG_CASE не учитывает регистр, а SORT_STRING принудительно сравнивает посимвольно даже числовые строки. natsort() и natcasesort() работают по той же идее, но сохраняют ключи.
Частая ошибка: присваивание результата sort
Каждая функция сортировки возвращает true и меняет переданный массив. Присваивание возвращаемого значения теряет массив:
Если нужна отсортированная копия, а оригинал надо сохранить, сначала скопируйте массив в новую переменную и сортируйте копию, как в примере с asort выше делается с $copy.
Часто задаваемые вопросы
Почему sort() возвращает true, а не отсортированный массив?
Функции сортировки PHP сортируют массив на месте, через ссылку, и возвращают true. Вызывайте sort($arr); отдельной строкой и потом используйте $arr. Запись $arr = sort($arr); заменит ваш массив на true.
Как отсортировать ассоциативный массив по значению и сохранить ключи?
Используйте asort($arr) для сортировки по возрастанию или arsort($arr) по убыванию. sort() и rsort() тоже сортируют по значению, но выбрасывают ключи и нумеруют заново с 0.
Как отсортировать многомерный массив по значению в PHP?
Используйте usort с оператором spaceship по нужному полю: usort($rows, fn($a, $b) => $a['age'] <=> $b['age']);. Поменяйте $a и $b местами для сортировки по убыванию, а для сортировки по двум полям сравнивайте массивы, например [$a['city'], $a['age']] <=> [$b['city'], $b['age']].
Стабильна ли сортировка в PHP?
Да, начиная с PHP 8.0 все функции сортировки стабильны: элементы, которые при сравнении равны, сохраняют порядок, который был до сортировки. Именно поэтому сортировка сначала по одному полю, а потом по другому работает так, как ожидается.
Как отсортировать строки с числами в естественном порядке?
Используйте natsort($arr) или sort($arr, SORT_NATURAL), они ставят img2 перед img10. Добавьте SORT_FLAG_CASE (SORT_NATURAL | SORT_FLAG_CASE) или используйте natcasesort, чтобы не учитывать регистр.