Tri d'un tableau d'objets en PHP : par une propriété pour débutants

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Tri d'un tableau d'objets en PHP : du chaos à l'ordre en 5 minutes

\n\n

Imaginez : vous écrivez un site éducatif en PHP et vous avez reçu une liste d'étudiants depuis la base de données. Chaque étudiant est un objet avec un nom, un âge et des points. Vous devez les afficher sur la page : d'abord les plus âgés, ou au contraire les plus jeunes. Ou peut-être les trier par ordre alphabétique. Comment faire si vous n'avez pas un simple tableau de nombres, mais un tableau d'objets ?

\n\n

Cette question est l'une des plus populaires sur Stack Overflow. Des milliers de développeurs, des débutants aux experts, sont confrontés à la tâche de « sort array of objects by one property ». Et aujourd'hui, nous allons la résoudre une fois pour toutes. Sans blabla, avec des exemples concrets et des explications claires.

\n\n

Pourquoi la fonction sort() classique ne fonctionne-t-elle pas ?

\n\n

Supposons que nous ayons un tableau d'objets $students :

\n\n
<?php\nclass Student {\n    public $name;\n    public $age;\n    public $score;\n\n    public function __construct($name, $age, $score) {\n        $this->name = $name;\n        $this->age = $age;\n        $this->score = $score;\n    }\n}\n\n$students = [\n    new Student("Anna", 22, 85),\n    new Student("Ivan", 20, 92),\n    new Student("Maria", 23, 78),\n    new Student("Pierre", 21, 95)\n];\n?>
\n\n

Si vous essayez d'appeler sort($students), PHP générera une erreur ou ne fera tout simplement rien. Pourquoi ? Parce que sort() sait comparer des nombres et des chaînes, mais ne sait pas comment comparer deux objets. Il faut lui expliquer : « Compare par la propriété age » ou « Compare par name ». Pour cela, PHP dispose d'une fonction spéciale : usort().

\n\n

Faites connaissance avec usort() : votre outil principal

\n\n

La fonction usort() prend deux arguments : le tableau lui-même et une fonction de comparaison. Cette fonction de comparaison doit retourner :

\n
    \n
  • 0, si les éléments sont égaux ;
  • \n
  • un nombre négatif, si le premier élément est inférieur au second ;
  • \n
  • un nombre positif, si le premier élément est supérieur au second.
  • \n
\n\n

Cela semble compliqué ? En réalité, c'est simple. Trions les étudiants par âge (ordre croissant) :

\n\n
<?php\nusort($students, function($a, $b) {\n    return $a->age <=> $b->age;\n});\n\n// Résultat : Ivan (20), Pierre (21), Anna (22), Maria (23)\n?>
\n\n

Remarquez l'opérateur <=> (vaisseau spatial). Il est apparu dans PHP 7 et rend le tri extrêmement concis. Il compare deux valeurs et retourne -1, 0 ou 1. Exactement ce dont usort() a besoin.

\n\n

Tri décroissant : on change le signe

\n\n

Vous voulez trier du plus âgé au plus jeune ? Il suffit d'inverser les opérandes dans l'opérateur <=> :

\n\n
<?php\nusort($students, function($a, $b) {\n    return $b->age <=> $a->age;  // maintenant b est comparé à a\n});\n\n// Résultat : Maria (23), Anna (22), Pierre (21), Ivan (20)\n?>
\n\n

Ou, ce qui revient au même, multipliez le résultat par -1 :

\n\n
<?php\nusort($students, function($a, $b) {\n    return -($a->age <=> $b->age);\n});\n?>
\n\n

Tri par chaînes (ordre alphabétique)

\n\n

Et si la propriété est une chaîne ? Par exemple, le nom. Même principe, mais au lieu de <=>, on utilise strcmp() ou strcasecmp() (pour une comparaison insensible à la casse) :

\n\n
<?php\n// Par ordre alphabétique (A-Z)\nusort($students, function($a, $b) {\n    return strcmp($a->name, $b->name);\n});\n\n// Résultat : Anna, Ivan, Maria, Pierre\n\n// Par ordre alphabétique inverse (Z-A)\nusort($students, function($a, $b) {\n    return strcmp($b->name, $a->name);\n});\n?>
\n\n

Tri par propriété numérique : alternative à <=>

\n\n

L'opérateur <=> est pratique, mais si vous travaillez avec une ancienne version de PHP (avant 7.0), il n'existe pas. Dans ce cas, écrivez la comparaison manuellement :

Blogs

Book Recommendations