Обзор функций сортировки
Все функции сортировки в PHP модифицируют массив на месте (in-place) и возвращают true/false.
| Функция | По чему | Порядок | Связь ключ-значение |
|---|---|---|---|
sort() |
Значениям | Возрастание | Не сохраняется |
rsort() |
Значениям | Убывание | Не сохраняется |
asort() |
Значениям | Возрастание | Сохраняется |
arsort() |
Значениям | Убывание | Сохраняется |
ksort() |
Ключам | Возрастание | Сохраняется |
krsort() |
Ключам | Убывание | Сохраняется |
usort() |
Пользов. | Пользов. | Не сохраняется |
uasort() |
Пользов. | Пользов. | Сохраняется |
uksort() |
Ключам (пользов.) | Пользов. | Сохраняется |
sort и rsort
<?php
declare(strict_types=1);
$fruits = ['cherry', 'apple', 'banana'];
// sort — ascending, reindexes keys
sort($fruits);
// [0 => 'apple', 1 => 'banana', 2 => 'cherry']
// rsort — descending, reindexes keys
rsort($fruits);
// [0 => 'cherry', 1 => 'banana', 2 => 'apple']
// Sorting flags
$mixed = ['10', '9', '100', '1'];
sort($mixed); // Default: ['1', '10', '100', '9'] — string comparison!
sort($mixed, SORT_NUMERIC); // [1, 9, 10, 100]
sort($mixed, SORT_NATURAL); // ['1', '9', '10', '100'] — natural order
sort($mixed, SORT_STRING); // ['1', '10', '100', '9'] — lexicographic
sort($mixed, SORT_LOCALE_STRING); // Locale-aware string sort
sort($mixed, SORT_FLAG_CASE | SORT_STRING); // Case-insensitive
Ловушка экзамена: По умолчанию
sort()сравнивает элементы как строки, если массив смешанный.['10', '9']приsort()без флагов даст['10', '9'](строка '10' < '9' лексикографически). ИспользуйтеSORT_NUMERICдля числовой сортировки.
asort и arsort
<?php
declare(strict_types=1);
$scores = ['alice' => 85, 'bob' => 92, 'charlie' => 78];
// asort — sort by VALUES, PRESERVE keys
asort($scores);
// ['charlie' => 78, 'alice' => 85, 'bob' => 92]
// arsort — reverse sort by values, preserve keys
arsort($scores);
// ['bob' => 92, 'alice' => 85, 'charlie' => 78]
Запомни:
sort()переиндексирует ключи (теряет связь).asort()сохраняет связь ключ-значение. Используйтеasortдля ассоциативных массивов,sort— для индексированных.
ksort и krsort
<?php
declare(strict_types=1);
$config = [
'zebra' => 1,
'alpha' => 2,
'beta' => 3,
];
// ksort — sort by KEYS ascending
ksort($config);
// ['alpha' => 2, 'beta' => 3, 'zebra' => 1]
// krsort — sort by keys descending
krsort($config);
// ['zebra' => 1, 'beta' => 3, 'alpha' => 2]
// Numeric keys
$arr = [3 => 'c', 1 => 'a', 2 => 'b'];
ksort($arr);
// [1 => 'a', 2 => 'b', 3 => 'c']
Пользовательская сортировка: usort, uasort, uksort
<?php
declare(strict_types=1);
// usort — custom comparison, REINDEXES keys
$users = [
['name' => 'Charlie', 'age' => 30],
['name' => 'Alice', 'age' => 25],
['name' => 'Bob', 'age' => 35],
];
usort($users, fn(array $a, array $b): int => $a['age'] <=> $b['age']);
// Sorted by age ascending
// Multi-level sort
usort($users, function (array $a, array $b): int {
return $a['name'] <=> $b['name']
?: $a['age'] <=> $b['age'];
});
// uasort — custom comparison, PRESERVES keys
$scores = ['alice' => 85, 'bob' => 92, 'charlie' => 78];
uasort($scores, fn(int $a, int $b): int => $b <=> $a); // Descending
// ['bob' => 92, 'alice' => 85, 'charlie' => 78]
// uksort — sort by keys with custom comparison
$data = ['item_10' => 'a', 'item_2' => 'b', 'item_1' => 'c'];
uksort($data, fn(string $a, string $b): int => strnatcmp($a, $b));
// ['item_1' => 'c', 'item_2' => 'b', 'item_10' => 'a']
Правила callback для сортировки
<?php
declare(strict_types=1);
// Callback MUST return:
// Negative (<0): $a should come before $b
// Zero (0): $a and $b are equal
// Positive (>0): $b should come before $a
// Spaceship operator is ideal for this
$compare = fn(int $a, int $b): int => $a <=> $b; // Ascending
$compare = fn(int $a, int $b): int => $b <=> $a; // Descending
// WRONG: returning bool (deprecated in PHP 8.0+)
// usort($arr, fn($a, $b) => $a > $b); // Don't do this!
// It must return int, not bool
Ловушка экзамена: Callback для
usortдолжен возвращатьint(-1, 0, 1). Возвращениеbool(как$a > $b) вызовет предупреждение в PHP 8.0+ и даст некорректные результаты. Всегда используйте оператор<=>.
Стабильная сортировка
Начиная с PHP 8.0, все функции сортировки стабильны (stable sort): элементы с одинаковым значением сохраняют свой относительный порядок.
<?php
declare(strict_types=1);
// PHP 8.0+: stable sort
$items = [
['name' => 'Alice', 'grade' => 'A'],
['name' => 'Bob', 'grade' => 'B'],
['name' => 'Charlie', 'grade' => 'A'],
];
usort($items, fn(array $a, array $b): int => $a['grade'] <=> $b['grade']);
// Alice comes before Charlie (both grade A) — original order preserved!
// [Alice(A), Charlie(A), Bob(B)]
// Before PHP 8.0: sort was NOT stable
// Equal elements could appear in any order
Запомни: С PHP 8.0 все функции сортировки стабильны. До PHP 8.0 — НЕТ гарантии стабильности. На экзамене могут спросить об этом изменении.
array_multisort
<?php
declare(strict_types=1);
// Sort multiple arrays simultaneously
$names = ['Charlie', 'Alice', 'Bob'];
$ages = [30, 25, 35];
array_multisort($names, SORT_ASC, $ages);
// $names = ['Alice', 'Bob', 'Charlie']
// $ages = [25, 35, 30] — reordered to match names!
// Sort by multiple columns
$data = [
['name' => 'Alice', 'age' => 25],
['name' => 'Bob', 'age' => 25],
['name' => 'Alice', 'age' => 30],
];
$nameCol = array_column($data, 'name');
$ageCol = array_column($data, 'age');
array_multisort($nameCol, SORT_ASC, $ageCol, SORT_ASC, $data);
// Sorted by name ASC, then age ASC
Натуральная сортировка
<?php
declare(strict_types=1);
$files = ['file10.txt', 'file2.txt', 'file1.txt', 'file20.txt'];
// Regular sort (lexicographic)
sort($files);
// ['file1.txt', 'file10.txt', 'file2.txt', 'file20.txt']
// Natural sort
natsort($files);
// [2 => 'file1.txt', 1 => 'file2.txt', 0 => 'file10.txt', 3 => 'file20.txt']
// Keys preserved!
// Case-insensitive natural sort
$items = ['IMG10', 'img2', 'IMG1', 'img20'];
natcasesort($items);
// [2 => 'IMG1', 1 => 'img2', 0 => 'IMG10', 3 => 'img20']
// Using SORT_NATURAL flag
sort($files, SORT_NATURAL);
// ['file1.txt', 'file2.txt', 'file10.txt', 'file20.txt']
// Keys reindexed!
Перемешивание и случайность
<?php
declare(strict_types=1);
$arr = [1, 2, 3, 4, 5];
// Shuffle — random order (reindexes keys)
shuffle($arr);
// Random keys
$randomKeys = array_rand($arr, 2); // 2 random keys
// Reverse
$reversed = array_reverse($arr); // Values reversed, reindexed
$reversed = array_reverse($arr, true); // Values reversed, keys preserved