Retour au cours

backend / php-laravel

Tableaux PHP en profondeur

Leçon 31 exercice

Explication

Ce que vous allez apprendre

  • Comprendre pourquoi les tableaux indexés et associatifs PHP sont en réalité le même type sous le capot
  • Transformer des collections de données avec le trio array_map / array_filter / array_reduce
  • Extraire une colonne d'un tableau de tableaux avec array_column, très utilisé sur des résultats de requêtes
  • Trier des tableaux tout en préservant ou en réindexant les clés selon le besoin
  • Fusionner des tableaux en connaissant la différence critique entre array_merge et l'opérateur +

Dans quel contexte ?

Un développeur récupère depuis une base de données une liste de 200 utilisateurs sous forme de tableau de tableaux associatifs, et doit en extraire uniquement les noms des administrateurs, triés par ordre alphabétique, pour les afficher dans un rapport. Sans les bonnes fonctions de tableaux, il finirait par écrire trois boucles foreach imbriquées ; avec array_filter, array_map et usort, la même tâche tient en trois lignes lisibles.

D'abord, une clarification qui simplifie tout le reste

En PHP, il n'existe qu'un seul type de tableau en interne : une "map ordonnée". Un tableau indexé comme ["pomme", "banane"] et un tableau associatif comme ["pomme" => 50] sont donc la même structure, juste avec des clés différentes (entières auto-incrémentées ou explicites).

Cette unification explique pourquoi on peut mélanger les deux styles de clés dans un même tableau, et pourquoi le parcours avec foreach ($stock as $fruit => $quantite) fonctionne de façon identique quel que soit le type de clé.

Ensuite, le trio qui remplace la majorité des boucles manuelles

Une fois qu'on manipule des tableaux de données, presque tout revient à trois opérations : transformer chaque élément (array_map), n'en garder que certains (array_filter), ou les combiner en une seule valeur (array_reduce). Ces trois fonctions remplacent des boucles foreach entières par des expressions courtes et lisibles.

FonctionRôleRésultat
array_mapTransforme chaque élémentTableau de même taille
array_filterGarde les éléments qui passent un testTableau plus petit (clés conservées)
array_reduceCombine tous les éléments en une valeurUne seule valeur (somme, texte, etc.)
array_columnExtrait une colonne d'un tableau de tableauxTableau des valeurs de cette colonne

Prérequis

Il faut être à l'aise avec les arrow functions (fn($x) => ...) vues en leçon précédente : elles sont omniprésentes comme callbacks de ces fonctions de tableaux.

Un piège classique à connaître avant de trier

Une fois les données filtrées, vient souvent le tri. usort() trie un tableau et réindexe ses clés numériquement, ce qui casse le lien entre une clé et sa valeur d'origine si les clés portaient un sens (par exemple un identifiant). uasort(), elle, préserve les clés d'origine tout en triant par valeur — un détail qui change tout selon le contexte.

Piège fréquent

array_merge($a, $b) réindexe systématiquement les clés numériques, ce qui peut faire disparaître des données si $a et $b utilisent tous deux des clés entières se chevauchant. L'opérateur + ($a + $b), lui, garde les clés de $a et ignore les clés en conflit de $b. Ce sont deux comportements très différents, à choisir consciemment selon le besoin.

Enfin, un opérateur qui simplifie les fusions et copies

Le spread operator (...$fruits) permet de fusionner ou dupliquer des tableaux sans risque de mutation accidentelle de l'original, contrairement à une référence directe. C'est la manière moderne et recommandée de combiner des tableaux en PHP 8+.

Astuce

array_walk($tableau, function (&$valeur) { ... }) modifie un tableau en place via une référence (&$valeur) — pratique pour appliquer une transformation sans créer de copie, notamment sur de gros volumes de données où la performance mémoire compte.

Maintenant que tu maîtrises les tableaux, la structure de données la plus utilisée en PHP, la prochaine leçon te fera passer à une autre façon d'organiser les données et le comportement : la programmation orientée objet, avec les classes, l'héritage et les interfaces.

Commandes & code

Tableaux PHP en profondeur

php
<?php
declare(strict_types=1);

// Tableau indexé vs associatif : en PHP, c'est le même type sous le capot (ordered map)
$fruits = ["pomme", "banane", "cerise"];
$stock = ["pomme" => 50, "banane" => 30, "cerise" => 12];

// Tableaux multidimensionnels
$utilisateurs = [
    ["id" => 1, "nom" => "Alice", "roles" => ["admin", "editeur"]],
    ["id" => 2, "nom" => "Bob", "roles" => ["lecteur"]],
];

// Parcours avec clé et valeur
foreach ($stock as $fruit => $quantite) {
    echo "$fruit : $quantite unités
";
}

// array_map / array_filter / array_reduce : le trio fonctionnel indispensable
$noms = array_map(fn($u) => $u["nom"], $utilisateurs);
$admins = array_filter($utilisateurs, fn($u) => in_array("admin", $u["roles"]));
$totalStock = array_reduce($fruits, fn($acc, $f) => $acc + ($stock[$f] ?? 0), 0);

// array_column : extraire une colonne d'un tableau de tableaux (très utilisé)
$idsSeulement = array_column($utilisateurs, 'id');
$parId = array_column($utilisateurs, null, 'id'); // indexé par id

// Tri : sort() réindexe, uasort/uksort préservent ou trient les clés
usort($utilisateurs, fn($a, $b) => $a['nom'] <=> $b['nom']); // <=> spaceship operator
uasort($stock, fn($a, $b) => $b <=> $a); // tri décroissant par valeur, clés préservées

// Décomposition (destructuring) avec list() / []
[$premier, $deuxieme] = $fruits;
['id' => $id, 'nom' => $nom] = $utilisateurs[0];

// Spread operator : fusionner et dupliquer des tableaux sans muter l'original
$fruitsExotiques = [...$fruits, "mangue", "papaye"];
$stockFusionne = [...$stock, "mangue" => 5];

// array_merge vs + : merge réindexe les clés numériques, + garde le tableau de gauche
$a = [0 => 'x', 1 => 'y'];
$b = [0 => 'z'];
print_r(array_merge($a, $b)); // [0 => 'x', 1 => 'y', 2 => 'z']
print_r($a + $b);             // [0 => 'x', 1 => 'y'] (clé 0 de $b ignorée)

// array_walk : modifier en place via référence
$prix = [10, 20, 30];
array_walk($prix, function (&$p) { $p *= 1.2; }); // +20% TVA
print_r($prix);

// Fonctions de recherche courantes
var_dump(in_array("banane", $fruits));     // true
var_dump(array_search("cerise", $fruits)); // 2 (index)
var_dump(array_key_exists("pomme", $stock)); // true

Résumé

  • array_map, array_filter, array_reduce remplacent la plupart des boucles manuelles.
  • array_column extrait une colonne, très pratique pour transformer des résultats de requêtes.
  • <=> (spaceship) simplifie les callbacks de tri.
  • array_merge réindexe les clés numériques, l'opérateur + non — piège classique.

Exercices pratiques

1 disponible
1

Mission : reconstruire un rapport d'administrateurs casse

Objectif : Corriger un pipeline de transformation de tableaux qui perd des donnees a cause d'une mauvaise fusion de cles.

Contexte

Un rapport doit lister, tries par ordre alphabetique, les noms des utilisateurs ayant le role admin, extraits d'un tableau de 200 utilisateurs recupere en deux lots depuis deux sources differentes ($lotA et $lotB, tous deux indexes numeriquement a partir de 0). Le developpeur a ecrit $tousLesUtilisateurs = array_merge($lotA, $lotB); puis s'etonne que certains utilisateurs du rapport final ne correspondent pas aux bons IDs apres un array_column($tousLesUtilisateurs, null, 'id').

Résoudre l’exercice →