Avatar ·

Как отсортировать массив объектов по одному свойству в PHP?

Всем привет! Я начинающий PHP-разработчик и столкнулся с проблемой сортировки массива объектов. У меня есть массив, который содержит объекты класса `User`. Каждый объект имеет свойства `name` и `age`. Вот как выглядит мой код: ```php class User { public $name; public $age; public function __construct($name, $age) { $this->name = $name; $this->age = $age; } } $users = [ new User('Иван', 25), new User('Мария', 30), new User('Петр', 20), new User('Анна', 28) ]; ``` Мне нужно отсортировать этот массив по свойству `age` (возрасту) в порядке возрастания, чтобы на выходе получить: Петр (20), Иван (25), Анна (28), Мария (30). Я пробовал использовать функцию `sort()`, но она не работает с объектами. Пытался применить `usort()`, но не совсем понимаю, как правильно написать callback-функцию. Подскажите, пожалуйста, как это сделать правильно? Желательно с примером кода и объяснением. Заранее спасибо! P.S. Если можно, покажите также, как сортировать по строковому свойству (например, по имени в алфавитном порядке). <<>>

Решение: используем usort() с пользовательской функцией сравнения

Для сортировки массива объектов в PHP лучше всего подходит функция usort(). Она принимает два аргумента: сам массив (передаётся по ссылке) и callback-функцию, которая сравнивает два элемента и возвращает целое число:

  • 0 — если элементы равны
  • Отрицательное число — если первый элемент должен идти перед вторым
  • Положительное число — если первый элемент должен идти после второго

Вот как это работает для вашего примера с сортировкой по возрасту:

usort($users, function($a, $b) {
    return $a->age - $b->age;
});

Принцип простой: если $a->age меньше $b->age, разность будет отрицательной — значит, $a встанет перед $b. Если больше — положительной, и $a встанет после. Если равны — 0, порядок не меняется.

Полный рабочий пример:

class User {
    public $name;
    public $age;
    
    public function __construct($name, $age) {
        $this->name = $name;
        $this->age = $age;
    }
}

$users = [
    new User('Иван', 25),
    new User('Мария', 30),
    new User('Петр', 20),
    new User('Анна', 28)
];

// Сортировка по возрасту (возрастание)
usort($users, function($a, $b) {
    return $a->age - $b->age;
});

foreach ($users as $user) {
    echo $user->name . ' (' . $user->age . ')<br>';
}
// Результат:
// Петр (20)
// Иван (25)
// Анна (28)
// Мария (30)

Сортировка по убыванию

Чтобы отсортировать по убыванию, просто поменяйте операнды местами:

usort($users, function($a, $b) {
    return $b->age - $a->age;
});

Сортировка по строковому свойству (например, по имени)

Для строк используйте функцию strcmp() или оператор spaceship (<=>), доступный с PHP 7:

// Вариант 1: с strcmp()
usort($users, function($a, $b) {
    return strcmp($a->name, $b->name);
});

// Вариант 2: с оператором spaceship (PHP 7+)
usort($users, function($a, $b) {
    return $a->name <=> $b->name;
});

Результат сортировки по имени: Анна, Иван, Мария, Петр (в алфавитном порядке).

Сортировка по нескольким свойствам

Если нужно отсортировать сначала по возрасту, а при равенстве — по имени:

usort($users, function($a, $b) {
    $ageCompare = $a->age - $b->age;
    if ($ageCompare === 0) {
        return strcmp($a->name, $b->name);
    }
    return $ageCompare;
});

Важные замечания

  • usort() изменяет исходный массив (передаётся по ссылке). Если нужно сохранить оригинал, скопируйте массив через $sorted = $users; перед сортировкой.
  • Для сортировки ассоциативных массивов по значению ключа используйте usort() аналогичным образом, обращаясь к элементам как к массиву: $a['age'] - $b['age'].
  • Начиная с PHP 7.4 можно использовать стрелочные функции для краткости: usort($users, fn($a, $b) => $a->age - $b->age);
<<>>

Альтернативный подход: создание вспомогательного массива

Если вам неудобно писать callback-функции, можно использовать старый добрый метод с созданием временного массива для сортировки. Он менее элегантный, но наглядный для новичков:

$ages = [];
foreach ($users as $key => $user) {
    $ages[$key] = $user->age;
}

// Сортируем массив возрастов, сохраняя ключи
array_multisort($ages, SORT_ASC, $users);

// Теперь $users отсортирован по возрасту

Этот метод особенно удобен, когда нужно отсортировать несколько связанных массивов одновременно. array_multisort() может принимать несколько массивов и сортировать их синхронно.

Минусы подхода: больше кода, создаётся дополнительный массив в памяти. Для больших массивов (сотни тысяч элементов) это может быть менее эффективно, чем usort().

Также можно использовать array_column() для извлечения значений свойств (работает с PHP 5.5+):

$ages = array_column($users, 'age');
array_multisort($ages, SORT_ASC, $users);

Этот вариант короче, но требует, чтобы свойства объектов были публичными (как в вашем примере).