Pourquoi et comment utiliser la structure match en PHP ?

La structure match en PHP, présentation, utilisation et avantages.

→ Corrigé du Challenge : Le Pôle Express

Depuis sa version 8.0, disponible depuis fin 2020, PHP propose une nouvelle structure : match. Cette structure présente de nombreux avantages, que ce soit d’un point de vue écriture et lisibilité du code, ou d’un point de vue fonctionnalités.

Pour illustrer sa présentation, je vais m’appuyer sur le challenge « Pôle Express ». Il s’agit dans ce challenge, pour des commandes de chocolat chaud, de partir d’une température de départ, et selon la composition du chocolat chaud, de faire évoluer cette température.

match va très bien se prêter à la réalisation de ce challenge. Pour l’illustrer, on va partir de façons de coder « basiques », pour aller progressivement vers un code + moderne, en s’appuyant donc sur match.

Sommaire :

Présentation du challenge

Dans ce challenge, on part d’une température de départ, sous la forme d’un entier. En premier, on doit analyser la valeur d’un « type de chocolat ». Selon cette valeur, la température augmente. Extrait de l’énoncé :

  • Chocolat noir : Monter la température de 5°
  • Chocolat au lait : Monter la température de 10°
  • Chocolat blanc : Monter la température de 15°
  • Mélange de chocolats : Monter la température de 12°

On va donc étudier la chaine de caractères correspondante pour définir la bonne valeur.

Dans le challenge, il y a un peu de parsing à réaliser avant d’analyser les différentes informations, mais ce n’est pas le sujet ici. Tu pourras trouver à la fin le corrigé complet.

Utilisation de if/else imbriqués en PHP

Une première solution intuitive peut être d’utiliser des if/else imbriqués :

if ($chocolateType === 'noir') {
    $temperature += 5;
} elseif ($chocolateType === 'au_lait') {
    $temperature += 10;
} elseif ($chocolateType === 'blanc') {
    $temperature += 15;
} elseif ($chocolateType === 'melange') {
    $temperature += 12;
}

Bon ça fonctionne… Mais on sait qu’on peut se passer des else (et des if) en PHP et en programmation d’une façon générale.

Remplaçons ces if/else par un switch qui semble déjà plus approprié.

Utilisation d’un switch en PHP

switch permet d’avoir un code plus lisible et mieux organisé :

switch ($chocolateType) {
    case 'noir':
        $temperature += 5;
    break;

    case 'au_lait':
        $temperature += 10;
    break;

    case 'blanc':
        $temperature += 15;
    break;

    case 'melange':
        $temperature += 12;
    break;
}

Chaque cas est bien identifiable. Il serait aussi plus facile de rajouter un nouveau cas à traiter, là où ça peut être plus compliqué de venir se « glisser » dans des if/else imbriqués.

Remplaçons maintenant ce switch par un match.

Utilisation d’un match en PHP

match propose une structure plus moderne. Ce qu’il est tout de suite important de noter c’est que match permet de retourner une valeur. Voici son utilisation :

$temperature += match ($chocolateType) {
    'noir' => 5,
    'au_lait' => 10,
    'blanc' => 15,
    'melange' => 12,
}; 
// Attention à ne pas oublier ce ; après la dernière accolade !

Ici on retourne simplement des valeurs, mais match permet aussi de réaliser directement des opérations.

Par exemple à la fin du challenge, il faut vérifier un « évènement », et altérer la température par différentes opérations. Extrait de l’énoncé :

  • Le chocolat brûle ! Il faut baisser la température de 10°
  • Une épice surprise est tombée dans la tasse : Il faut monter la température de 10°
  • La tasse est froide : Il faut multiplier la température par 2 (après effets du chocolat et des épices)

Ce qui donne avec la structure match :

$temperature = match ($event) {
    'chocolat_brule' => $temperature - 10,
    'epice_surprise' => $temperature + 10,
    'tasse_froide' => $temperature * 2,
};

A première vue, match offre une structure plus concise qu’un switch tout en conservant la lisibilité.

Listons les différents avantages (et un point d’attention).

Avantages du match en PHP

default

On en n’a pas dans les exemples ci-dessus mais à la fois switch et match proposent le mot clé « default » pour permettre de gérer les cas qui ne sont pas définis. Différence importante avec le switch, si un cas n’est pas reconnu, et qu’il n’y a pas de « default », le programme continue sans erreur. Avec un match, une erreur sera déclenchée si le cas n’est pas reconnu et qu’il n’y a pas de « default ».

$event = 'machine_cassee';

$temperature = match ($event) {
    'chocolat_brule' => $temperature - 10,
    'epice_surprise' => $temperature + 10,
    'tasse_froide' => $temperature * 2,
};

// Une erreur sera déclenchée car il n'y a pas de "default"
// Le programme s'arrête
$event = 'machine_cassee';

switch ($event) {
    case 'chocolat_brule':
        $temperature - 10;
    break;

    case 'epice_surprise':
        $temperature + 10;
    break;

    case 'tasse_froide':
        $temperature * 2;
    break;
}

// Aucune erreur
// Le programme continue

Cela permet de mieux gérer le déroulement de son code et d’éviter des bugs subtils avec le switch qui ne déclencheraient pour autant aucune erreur !

Plus besoin du break

On le voit dans les exemples ci-dessus, on n’a plus besoin du break après chaque cas. Comme il y a cette notion de retour, le match se « termine » dès qu’une correspondance est trouvée.

Multi cas

// Avec un match, on sépare les cas par des virgules

$temperature += match ($chocolateType) {
    'noir', 'noisettes' => 5,
    'au_lait' => 10,
    'blanc', 'canelle' => 15,
    'melange' => 12,
};
// Avec un switch, on rajoute des lignes "case"

switch ($chocolateType) {
    case 'noir':
    case 'noisettes':
        $temperature += 5;
        break;
    case 'au_lait':
        $temperature += 10;
        break;
    case 'blanc':
    case 'canelle':
        $temperature += 15;
        break;
    case 'melange':
        $temperature += 12;
        break;
}

Encore une fois, match « gagne » pour son côté concis.

Comparaison stricte

Contrairement à switch, match réalise toujours des comparaisons strictes. Il faut considérer que les valeurs sont comparées avec « === » et non « == ». Cela permet d’éviter les erreurs ce coercition de type. Par exemple considérer que 0 et false sont égaux.

Point d’attention si besoin d’opérations complexes

Attention, match ne pourra (pour le moment) exécuter qu’une seule instruction pour chaque cas. Et lorsqu’une correspondance est trouvée, match « s’arrête ».

Donc si tu as des opérations complexes à réaliser (c’est à dire plusieurs lignes de code à exécuter) ou si tu veux pouvoir réaliser plusieurs opérations (déclenchement de plusieurs « case ») alors la structure switch reste la + adaptée.

Conclusion et corrigé complet

On a donc vu que match propose à la fois une structure + concise et un code + rigoureux, par des comparaisons strictes et le déclenchement d’une erreur si on se trouve dans un cas non prévu.

match est aussi beaucoup utilisé pour l’écriture des enums. Si tu n’es pas familier de cette structure, n’hésite pas à découvrir notre corrigé dédié : Utilisation des enums avec PHP 8.1

Et voici le corrigé complet du challenge, un peu de parsing au début et 3 utilisations de la structure match :

$total = 0;

foreach ($orders as $orderInformations) {

    // Parsing -------------------------------
    $data = explode(',', $orderInformations);

    $temperature = (int) $data[0];
    $chocolateType = $data[1];
    $spiceType = $data[2];

    $event = $data[3] ?? null;
    // --------------------------------------

    // Type de chocolat ---------------------
    $temperature += match ($chocolateType) {
        'noir' => 5,
        'au_lait' => 10,
        'blanc' => 15,
        'melange' => 12,
    };
    // --------------------------------------

    // Type d'épice -------------------------
    $temperature += match ($spiceType) {
        'cannelle' => 4,
        'muscade' => 7,
        'piment' => 9,
        'vanille' => 1,
    };
    // --------------------------------------

    // Evènement ----------------------------
    if (! is_null($event)) {
        $temperature = match ($event) {
            'chocolat_brule' => $temperature - 10,
            'epice_surprise' => $temperature + 10,
            'tasse_froide' => $temperature * 2,
        };
    }
    // --------------------------------------

    // Incrémentation du total --------------
    $total += $temperature;
    // --------------------------------------
}

// Calcul de la moyenne
$average = ceil($total / count($orders));

Qui a codé ce superbe contenu ?

Keep learning

Autres contenus à découvrir


Ta newsletter chaque mois

Corrigés, challenges, actualités, veille technique... aucun spam.