Сортировка массива в PHP — это переупорядочение элементов по значению или по ключу с помощью встроенных функций (sort, asort, ksort и родственных). Все они меняют массив на месте и возвращают true, а различаются в двух вещах: по чему сортируют (значение или ключ) и сохраняют ли связку «ключ-значение». Ниже — минимальный рабочий пример, таблица всех функций, свои компараторы через usort и оператор <=>, сортировка по полю и вопрос стабильности. Ориентир по версии — PHP 8.4.
Содержание
- Минимальный пример: sort
- Все функции сортировки в таблице
- Сохранять ключи или нет: asort и ksort
- Флаги сравнения и естественная сортировка
- Свой компаратор: usort и оператор spaceship
- Частая ошибка: sort возвращает не массив
- Стабильность сортировки в PHP 8
- Выводы
- Где применяется / связь с практикой
- FAQ
Минимальный пример: sort
Начнем с самой частой задачи — отсортировать список чисел по возрастанию.
<?php
$nums = [5, 3, 8, 1];
sort($nums);
print_r($nums);
Вывод:
Array
(
[0] => 1
[1] => 3
[2] => 5
[3] => 8
)
Функция sort() отсортировала значения по возрастанию и заново пронумеровала ключи от нуля. Прежние ключи потеряны — для простого списка это обычно и нужно. Обратная сортировка — rsort(), она даст 8, 5, 3, 1.
Все функции сортировки в таблице
В PHP один набор функций закрывает почти все случаи. Чтобы выбрать нужную, держите в голове две оси: сортируем по значению или по ключу и сохраняем ли ключи.
| Функция | Сортирует по | Направление | Сохраняет ключи |
|---|---|---|---|
sort |
значению | по возрастанию | нет (ключи 0..n) |
rsort |
значению | по убыванию | нет |
asort |
значению | по возрастанию | да |
arsort |
значению | по убыванию | да |
ksort |
ключу | по возрастанию | да |
krsort |
ключу | по убыванию | да |
usort |
значению, свой компаратор | задает компаратор | нет |
uasort |
значению, свой компаратор | задает компаратор | да |
uksort |
ключу, свой компаратор | задает компаратор | да |
natsort |
значению, «естественно» | по возрастанию | да |
Мнемоника по префиксам: a — associative (сохраняет ключи), r — reverse (по убыванию), k — key (по ключу), u — user (пользовательский компаратор). Отсюда arsort читается как «сохранить ключи + по убыванию», а uksort — «свой компаратор по ключам».
Сохранять ключи или нет: asort и ksort
Разница между sort и asort видна на ассоциативном массиве. asort() сортирует по значению, но оставляет исходные ключи на месте.
<?php
$fruit = ['banana' => 3, 'apple' => 1, 'cherry' => 2];
asort($fruit);
print_r($fruit);
Вывод:
Array
(
[apple] => 1
[cherry] => 2
[banana] => 3
)
Значения выстроились по возрастанию (1, 2, 3), но ключи apple, cherry, banana сохранились. Если бы мы взяли sort(), ключи заменились бы на 0, 1, 2 и связь со словами потерялась. Для ассоциативных массивов, где ключ несет смысл, берите asort/arsort.
Когда нужен порядок именно по ключу, работают ksort и krsort:
<?php
$data = [3 => 'c', 1 => 'a', 2 => 'b'];
ksort($data);
print_r($data);
Вывод:
Array
(
[1] => a
[2] => b
[3] => c
)
Ключи выстроились по возрастанию, значения поехали вместе с ними. Это удобно, например, когда массив собран по числовым идентификаторам вразнобой и его надо привести к порядку.
Флаги сравнения и естественная сортировка
По умолчанию функции используют флаг SORT_REGULAR — PHP сам решает, сравнивать как числа или как строки. С числовыми строками это иногда дает неожиданный порядок, поэтому флаг стоит задавать явно.
<?php
$v = ['10', '9', '2', '1'];
sort($v, SORT_STRING);
print_r($v);
Вывод:
Array
(
[0] => 1
[1] => 10
[2] => 2
[3] => 9
)
При SORT_STRING строки сравниваются посимвольно, поэтому '10' встает раньше '2' (первый символ 1 меньше 2). Если те же значения отсортировать с флагом SORT_NUMERIC, порядок станет числовым: 1, 2, 9, 10. Выбор флага — это выбор смысла: код артикула сортируем как строку, количество — как число.
Отдельный случай — имена вида img2, img10. «Естественный» порядок дает natsort():
<?php
$files = ['img12.png', 'img10.png', 'img2.png', 'img1.png'];
natsort($files);
print_r($files);
Вывод:
Array
(
[3] => img1.png
[2] => img2.png
[1] => img10.png
[0] => img12.png
)
natsort понимает числа внутри строк, поэтому img2 идет раньше img10, а не наоборот. Ключи сохранены, поэтому в выводе они остались от исходных позиций. Для сравнения без учета регистра есть natcasesort().
Свой компаратор: usort и оператор spaceship
Когда порядок задается не самим значением, а вычислением, нужен usort() со своей функцией сравнения. Компаратор получает два элемента и должен вернуть отрицательное число, ноль или положительное — «меньше», «равно», «больше». Удобнее всего вернуть это оператором «космический корабль» <=> (доступен с PHP 7.0), который как раз выдает -1, 0 или 1.
<?php
$people = [
['name' => 'Ann', 'age' => 30],
['name' => 'Bob', 'age' => 25],
['name' => 'Cy', 'age' => 40],
];
usort($people, fn($a, $b) => $a['age'] <=> $b['age']);
print_r(array_column($people, 'age'));
Вывод:
Array
(
[0] => 25
[1] => 30
[2] => 40
)
Массив отсортирован по полю age по возрастанию. Чтобы получить убывание, достаточно поменять аргументы местами: $b['age'] <=> $a['age']. Как и sort, функция usort не сохраняет исходные ключи. Если ключи важны, берите uasort (свой компаратор + сохранение ключей) или uksort (свой компаратор по ключам).
Сортировка по нескольким полям сразу тоже делается через <=>, если сравнивать массивы: PHP сравнивает их поэлементно, слева направо.
<?php
$rows = [
['dept' => 'B', 'name' => 'Ann'],
['dept' => 'A', 'name' => 'Zoe'],
['dept' => 'A', 'name' => 'Bob'],
];
usort($rows, fn($a, $b) => [$a['dept'], $a['name']] <=> [$b['dept'], $b['name']]);
print_r(array_column($rows, 'name'));
Вывод:
Array
(
[0] => Bob
[1] => Zoe
[2] => Ann
)
Сначала сравнивается dept (сотрудники отдела A идут раньше B), при равном отделе — name. Так получается сортировка «сначала по отделу, потом по имени» без вложенных условий.
Частая ошибка: sort возвращает не массив
Легко забыть, что функции сортировки меняют массив на месте, а возвращают true/false, а не отсортированные данные. Отсюда типовой промах новичка.
Неверный код:
<?php
$nums = [5, 3, 8, 1];
$sorted = sort($nums);
print_r($sorted);
Фактический результат:
1
В $sorted попало логическое true, которое print_r печатает как 1. Отсортированный массив — это сам $nums, а не то, что вернула функция.
Исправление:
<?php
$nums = [5, 3, 8, 1];
sort($nums); // массив меняется на месте
print_r($nums); // сюда и смотрим
Второй скрытый промах — компаратор, возвращающий булево значение: fn($a, $b) => $a > $b. Он различает только «больше» и «не больше», а случаи «меньше» и «равно» схлопываются в false, и порядок получается неверным. Возвращайте разность через <=>, а не сравнение через >.
Стабильность сортировки в PHP 8
Сортировка называется стабильной, если равные по компаратору элементы сохраняют исходный взаимный порядок. С PHP 8.0 все перечисленные функции стабильны — это гарантия языка. До PHP 8.0 порядок равных элементов был не определен и мог отличаться между версиями и платформами, поэтому в старом коде на это полагаться было нельзя. На PHP 8.4 стабильность действует по умолчанию, дополнительных флагов не требуется.
Выводы
- Две оси выбора функции: сортируем по значению или по ключу и сохраняем ли ключи; отсюда пары
sort/asort,rsort/arsort,ksort/krsort. - Все функции меняют массив на месте и возвращают
true, а не отсортированный массив — не присваивайте результатsort()переменной как данные. - Флаг сравнения (
SORT_STRING/SORT_NUMERIC) иnatsortрешают проблему числовых строк и имен видаimg2/img10. - Произвольный порядок задают
usort/uasort/uksortс компаратором на операторе<=>; для нескольких полей сравнивайте массивы поэлементно. - С PHP 8.0 сортировка стабильна: равные элементы держат исходный порядок; в коде под старые версии на это не рассчитывайте.
Где применяется / связь с практикой
Сортировка массивов — ежедневная работа бэкенд-разработчика: вывести список товаров по цене, отчет по дате, пользователей по нескольким полям сразу. Разобравшись с usort и оператором <=>, вы закрываете почти любой порядок вывода без внешних библиотек, а знание про сохранение ключей избавляет от «съехавших» ассоциативных массивов. Эти же приемы дальше ложатся на работу с коллекциями во фреймворках и на сортировку на стороне базы данных.
Освойте тему на практике
Системно язык и его стандартную библиотеку разбирают на курсе PHP-разработчик: от массивов и функций до ООП, баз данных и промышленных практик. Посмотреть формат и уровень подачи можно на открытых уроках — это бесплатные вебинары с разбором конкретных тем.
FAQ
Чем отличается usort от uasort и uksort?
Все три принимают свой компаратор. usort сортирует по значению и сбрасывает ключи в 0..n, uasort сортирует по значению и сохраняет ключи, uksort сортирует по ключам. Выбор зависит от того, что для вас порядок — значение или ключ — и нужны ли исходные ключи.
Как отсортировать массив по убыванию со своим компаратором?
Поменяйте местами аргументы в <=>: вместо $a['age'] <=> $b['age'] напишите $b['age'] <=> $a['age']. Для встроенных функций убывание дают варианты с r: rsort, arsort, krsort.
Нужно ли сортировать в PHP, если данные приходят из базы?
Если можете, сортируйте в SQL через ORDER BY — это эффективнее на больших выборках. Сортировка в PHP уместна для уже загруженных в память данных, для порядка по вычисляемому полю или когда источник не база (файл, API, объединение нескольких списков).



