Сортировка многомерного массива по значению поля
Представим, что у нас есть многомерный массив с товарами:
$products = [
['id' => 1, 'name' => 'Товар 1', 'price' => 1000],
['id' => 2, 'name' => 'Товар 2', 'price' => 500],
['id' => 3, 'name' => 'Товар 3', 'price' => 2000],
['id' => 4, 'name' => 'Товар 4', 'price' => 300]
];
И нужно отсортировать этот массив по цене. Как это сделать?
Для этого в PHP существует специальная функция usort(). Вот готовый пример:
function mySort($a, $b) {
if($a['price'] == $b['price'])
return 0;
if($a['price'] < $b['price'])
return -1;
else
return 1;
}
usort($products, 'mySort');
print_r($products);
Как работает функция usort()
Поскольку PHP не знает, по каким критериям нужно сортировать массив, мы описываем эти критерии в отдельной функции под названием mySort() (название может быть любым).
Задача этой функции простая - она должна принять два случайных элемента массива ($a и $b), сравнить их и вернуть одно из трёх значений:
- 0 если $a и $b равны
- -1 если $a меньше $b
- 1 если $a больше $b
Именно это мы сделали в примере выше.
Сокращение кода
Разумеется, if-else можно заменить на тернарный оператор:
function mySort($a, $b) {
if($a['price'] == $b['price'])
return 0;
return $a['price'] < $b['price'] ? -1 : 1;
}
usort($products, 'mySort');
Поскольку вторым параметром usort принимает callable, не обязательно создавать отдельную функцию сортировки, можно передать безымянную функцию:
usort($products, function ($a, $b) {
if($a['price'] == $b['price'])
return 0;
return $a['price'] < $b['price'] ? -1 : 1;
});
Кроме этого, в PHP 7 появился оператор spaceship (летающий корабль) <=>. Он возвращает -1, 0 или 1 если $a меньше, равна или больше $b. С этим оператором код становится гораздо короче:
usort($products, function ($a, $b) {
return $a['price'] <=> $b['price'];
});
Несколько условий сортировки
Разумеется, в функции сортировки можно указать сколько угодно правил:
usort($products, function ($a, $b) {
// Сначала сравниваем по цене
if($a['price'] != $b['price'])
return $a > $b ? 1 : -1;
// Если цены равны, сравниваем по id
return $a['id'] <=> $b['id'];
});
Сортировка массива, полученного из БД
Если массив с данными получен из базы данных, лучше сначала подумать, нет ли способа отсортировать данные ещё до их получения, в самом SQL-запросе.
За сортировку в SQL отвечает команда ORDER BY. Сортировка по возрастанию выглядит так:
SELECT * FROM `products` ORDER BY `id`
По убыванию:
SELECT * FROM `products` ORDER BY `id` DESC
Сортируем сначала по наличию товара на складе, затем по возрастанию цены:
SELECT * FROM `products` ORDER BY `in_stock` DESC, `price`
Сначала выведем товар с id=15, затем товары с ценой больше 5000:
SELECT * FROM `products` ORDER BY `id` = 15 DESC, `price` > 5000 DESC