Aller au contenu principal
La newsletter arrive ! Premier envoi très bientôt : laissez votre adresse pour la recevoir.

PHP 8.0 : la révolution qui a tout changé.

PHP 8 : les attributs et propriétés promues ont révolutionné le code. Analyse des vrais impacts cinq ans plus tard sur le développement PHP.

MAJ 6 min de lecture
Sommaire · 7

La fonctionnalité vedette de PHP 8.0 était le JIT. Sur ce blog, il ne sert à rien. Ce qui a tout changé, ce sont les nouveautés de confort dont personne ne faisait la une : 1 150 attributs, 1 131 propriétés promues, et zéro switch restant.

Cinq ans après, le relevé

PHP 8.0 est sortie en novembre 2020, et sa maintenance s'est arrêtée en novembre 2023. Plus aucun correctif, y compris de sécurité.

L'annonce de l'époque avait une vedette incontestée, le compilateur JIT. Voici ce que les fonctionnalités de cette version ont laissé dans le src/ de ce blog, qui tourne aujourd'hui en PHP 8.5 :

  • attributs : 1 150
  • propriétés promues dans un constructeur : 1 131
  • expressions match : 116
  • instructions switch : 0
  • opérateur nullsafe ?-> : 73
  • str_contains, str_starts_with, str_ends_with : 73
  • types union : 13
  • throw en position d'expression : 2
  • JIT : sans objet

La vedette n'a rien laissé. Les figurantes ont pris toute la place. C'est le sujet de ce billet, et c'est une leçon qui vaut pour chaque version qui sort.

Le JIT, ou la vedette qui ne joue pas dans ce film

Le JIT compile à la volée les portions de code les plus sollicitées en code machine, au lieu de les faire interpréter par la machine virtuelle Zend. Sur du calcul intensif, traitement d'images, algorithmes numériques, boucles serrées, les gains se mesurent en facteurs.

Une application web n'est pas ce genre de programme. Elle passe l'essentiel de son temps à attendre : la base de données, un service distant, le disque. Accélérer l'interprétation d'un code qui attend ne fait pas gagner grand-chose, et c'est exactement ce qu'on observe ici.

Ce n'est pas un reproche adressé au JIT, qui fait précisément ce qu'il promet. C'est un reproche adressé à la façon dont on annonce une version : en mettant en tête la fonctionnalité la plus impressionnante à démontrer, plutôt que celle qui changera le plus de lignes chez le plus de gens.

switch a disparu, et c'est le chiffre le plus parlant

switch existe en PHP depuis 1997. Il compare en égalité faible, ce qui fait que 0 vaut 'foo' dans certaines versions du passé. Il exécute en cascade si on oublie un break. Il ne rend aucune valeur, donc il faut une variable temporaire pour transporter le résultat.

match corrige les trois d'un coup : comparaison stricte, pas de cascade, et c'est une expression, donc elle se pose directement dans un return.

Le compte sur ce dépôt : 116 match, et zéro switch. Pas un seul, y compris dans le code le plus ancien.

Une structure de contrôle vieille de vingt-cinq ans a disparu en cinq. Ce n'est pas un plan de migration ni une règle d'analyse statique qui l'a fait : c'est que le remplaçant est meilleur sur tous les axes à la fois, sans compromis à arbitrer. Les fonctionnalités qui s'imposent le plus vite sont celles qui ne demandent rien en échange.

La promotion de constructeur : 1 131 propriétés, et une convention

Avant 8.0, chaque dépendance s'écrivait trois fois : la propriété, l'argument du constructeur, l'affectation. Trois lignes pour dire une seule chose, et l'occasion de se tromper à chaque fois qu'on en ajoutait une.

La promotion écrit les trois d'un coup :

PHP
// src/Service/Home/ReadingList/Scoring/PostScorer.php
public function __construct(
    #[AutowireIterator('app.reading_list.score_component')]
    private iterable $components,
) {}

1 131 propriétés promues dans 449 constructeurs. À trois lignes chacune dans l'ancienne forme, c'est de l'ordre de deux mille lignes qui n'existent pas.

Le gain n'est pas seulement la brièveté. Une dépendance déclarée en un seul endroit ne peut pas diverger d'elle-même, et surtout la forme promue est celle qui accueille les attributs d'injection sans se déformer. La convention final readonly class avec promotion, qui structure tout ce projet, n'est écrivable que grâce à cette syntaxe.

Les attributs : 1 150, et un billet à part

Les attributs ont sorti les métadonnées des commentaires pour les mettre dans le langage. Routes, contraintes de validation, mapping ORM, écouteurs d'événements : tout ce qui vivait dans des blocs /** @Annotation */ parsés par une bibliothèque tierce est devenu une classe que le compilateur connaît.

1 150 occurrences ici, ce qui en fait la fonctionnalité la plus dense du dépôt. C'est aussi la seule de 8.0 qui mérite son propre développement : j'ai détaillé dans Attributs PHP : la moitié qu'on oublie d'écrire comment on écrit le sien et, surtout, comment on le relit, ce que la doc explique mal.

Nullsafe, unions, str_contains : le confort qui compte quand même

Trois nouveautés que personne n'a mises en avant, et qui reviennent tous les jours.

L'opérateur ?-> court-circuite la chaîne dès qu'un maillon vaut null, au lieu de fataler. 73 usages, et chacun remplace une condition imbriquée ou un isset défensif.

Les types union int|string disent honnêtement qu'une valeur a deux formes possibles. Seulement 13 ici, et c'est cohérent avec ce qu'on a vu sur les versions suivantes : dans du code applicatif, une valeur qui a deux formes est souvent une valeur mal modélisée. L'union sert surtout aux frontières.

str_contains, str_starts_with et str_ends_with totalisent 73 usages. Elles remplacent strpos($h, $n) !== false, une expression dont la moitié des développeurs PHP se rappelaient de travers, parce qu'une occurrence en position 0 rend 0, qui est faux. Une fonction qui rend un booléen quand la question est booléenne, ça a l'air de rien. Ça a supprimé une classe entière de bugs.

Ce qu'une version vedette apprend

Le relevé, cinq ans après : la fonctionnalité en tête d'affiche n'a rien laissé ici, et quatre nouveautés de confort ont changé chaque fichier.

Il y a une raison structurelle à ça, et elle n'a rien d'un hasard de communication. Une fonctionnalité spectaculaire l'est parce qu'elle repousse une limite, donc elle concerne ceux qui touchaient cette limite, donc peu de monde. Une fonctionnalité de confort s'applique à un geste qu'on répète mille fois par projet. Elle est ennuyeuse à annoncer et elle finit par tout réécrire.

Le meilleur indicateur reste celui du switch : ce qui mesure vraiment l'adoption d'une nouveauté, ce n'est pas le nombre de fois où on l'écrit, c'est le nombre de fois où on n'écrit plus ce qu'elle remplace.

Alors sur la version que vous tournez aujourd'hui : qu'est-ce que vous avez arrêté d'écrire sans même vous en rendre compte ?

Une coquille, une erreur dans ce billet ? Signale-la-moi.

Ce billet est publié sous licence Creative Commons BY-NC-SA 4.0 (attribution, pas d'usage commercial, partage dans les mêmes conditions).

Vous aimerez aussi

Newsletter

Un mail quand il y a quelque chose à dire

Pas de tracking, pas de pub, pas de "10 astuces pour…". Juste les nouveaux billets et parfois une réflexion en plus.

Activez uniquement ce que vous souhaitez. Vos choix sont conservés 6 mois.

Strictement nécessaires

Indispensables au fonctionnement du site (session, sécurité, préférence d'affichage). Aucune donnée n'est partagée à des tiers et aucun consentement n'est requis.

Toujours actif

Mesure d'audience

Statistiques via Google Analytics (GA4) : pages vues, source du trafic, navigateur et interactions clés. Dépose des cookies de mesure, activés seulement avec votre accord (Consent Mode). Sans publicité ciblée, sans Google Signals, sans partage commercial.

Contenus externes

Affiche les GIF animés hébergés par Giphy (CDN aux États-Unis). À l'affichage d'un GIF, votre adresse IP et votre navigateur sont transmis à Giphy. Sans votre accord, les GIF ne s'affichent pas.