• Contact us
  • Documentation
  • Login
Watch a demoFree trial
Blog
Blog
BlogProduitÉtudes de casNouvellesPerspectives
Blog

Expressions match() en PHP 8.0

PHPfonctionnalitésAméliorations
24 septembre 2020
Larry Garfield
Larry Garfield
Directeur de l'expérience des développeurs
Partager
Cette page a été rédigée en anglais par nos experts, puis traduite par une IA pour vous y donner accès rapidement! Pour la version originale, c’est par ici.

Dans notre dernier épisode, nous avons abordé les améliorations à venir du système de types de PHP. Aujourd'hui, nous nous intéressons à une nouvelle construction qui renforce la puissance de la logique de branchement.

PHP dispose d'une switch instruction depuis ses débuts, calquée sur la même construction en C. Tu l'as sûrement déjà vue :

<?php
switch ($var) {
    case 'a':
        $message = "The variable was a.";
        break;
    case 'b':
        $message = "The variable was c.";
        break;
    case 'c':
        $message = "The variable was c.";
        break;
    default:
        $message = "The variable was something else.";
        break;
}

print $message;

Bien qu'elle fasse l'affaire, la structure switch classique présente un certain nombre de limites. La plupart des langages plus récents, comme Go ou Rust, ont opté pour des structures plus robustes et moins sujettes aux erreurs, qui portent divers noms. Et désormais, PHP en dispose également.

Découvre la fonction PHP match . Contrairement à switch, PHP match est une expression. Ça veut dire qu’elle renvoie une valeur, comme ça :

<?php
$message = match($var) {
    'a' => 'The variable was a',
    'b' => 'The variable was b',
    'c' => 'The variable was c',
    default => 'The variable was something else',
};

print $message;

Il y a plusieurs points à souligner ici :

  1. Avec switch, chaque case est comparé selon l'égalité souple ==. Avec PHP match, chaque branche est comparée selon l'égalité stricte, ===. Ça veut dire que les types doivent aussi correspondre.
  2. Chaque branche de la match n'est qu'une seule expression. Pas d'instructions sur plusieurs lignes, juste une seule expression qui est évaluée. Si tu as besoin d'une logique complexe, crée une fonction ou une méthode que tu appelles.
  3. Il n'y a pas de passage d'une branche à l'autre, donc pas besoin qu'une break.
  4. match renvoie une valeur. C'est d'ailleurs sa raison d'être.
  5. Comme il s'agit d'une expression, un ; est nécessaire à la toute fin, tout comme pour les définitions de fermetures.
  6. match est exhaustive. Si $var n'est pas === l'une des valeurs fournies et qu'il n'y a pas de default, une erreur sera levée.

match Les branches peuvent également être composées et séparées par des virgules pour un comportement de type « OU », comme ceci :

<?php
echo match($operator) {
    '+', '-', '*', '/' => 'Basic arithmetic',
    '%' => 'Modulus',
    '!' => 'Negation',
};

PHP match a été présenté comme un langage modernisé et plus utile switch, mais je ne suis pas sûr que ce soit exact. Je considère plutôt match comme un ternaire plus puissant.

Par le passé, je me suis souvent retrouvé dans des cas binaires où une variable pouvait être assignée à l'une de deux valeurs en fonction d'une condition. J'ai trouvé que la façon la plus simple d'écrire ça, c'est comme ça :

<?php
$display = $user->isAdmin()
    ? $user->name() . ' (admin)'
    : $user->name() . ' (muggle)'
;

C'est un code tout à fait valide et très utile. Si la logique de la condition ou de l'une des branches est trop complexe pour être facilement lisible, c'est le signe qu'il faut refactoriser cette logique dans sa propre fonction ou méthode. J'ai trouvé que c'était une très bonne règle empirique pour ce genre de situations, et que ça permettait d'obtenir un code très lisible, compact et testable.

Cela ne fonctionne toutefois que pour true/false, cependant. match, en revanche, fonctionne pour n’importe quel nombre d’options, mais a les mêmes avantages pour t’inciter à écrire un code bien factorisé et propre.

Si tu as besoin de conditions plus complexes qu’une simple identité, tu peux utiliser match sur true:

<?php
$count = get_count();
$size = match(true) {
    $count > 0 && $count <=10 => 'small',
    $count <=50 => 'medium',
    $count >50 => 'huge',
};

Note que, puisqu’il n’y a pas default, une non-correspondance (dans ce cas si $count est égal à 0 ou négatif) entraînera une erreur levée plutôt qu’une affectation silencieuse à null et la poursuite de l’exécution. C’est une bonne chose, car les erreurs ne peuvent pas se propager et polluer le code en aval.

L'expression de correspondance RFC nous est proposée par Ilija Tovilo. 

Restez informé

Abonnez-vous à notre newsletter mensuelle pour les dernières mises à jour et nouvelles.

Votre meilleur travail
est à l'horizon

Essai gratuit