
La fondation PHP a annoncé que PHP 8.5, dont la sortie est prévue en novembre 2025, apportera une autre fonctionnalité très attendue : l'opérateur pipe (|>). Il s'agit d'une petite fonctionnalité au potentiel énorme, mais qui a tout de même pris des années à voir le jour.
PHP est un langage de script polyvalent destiné au développement web. Le code PHP est généralement traité sur un serveur web par un interpréteur PHP implémenté sous forme de module, de démon ou d'exécutable CGI (Common Gateway Interface). Sur un serveur web, le résultat du code PHP interprété et exécuté, qui peut être n'importe quel type de données, telles que du code HTML généré ou des données d'image binaires, forme tout ou partie d'une réponse HTTP.
Il existe divers systèmes de modèles web, systèmes de gestion de contenu web et frameworks web qui peuvent être utilisés pour orchestrer ou faciliter la génération de cette réponse. En outre, PHP peut être utilisé pour de nombreuses tâches de programmation en dehors du contexte web, telles que les applications graphiques autonomes et le contrôle de drones. Le code PHP peut également être exécuté directement à partir de la ligne de commande.
Selon un rapport, en octobre 2024 (environ deux ans après l'arrêt de PHP 7 et 11 mois après la sortie de PHP 8.3), PHP 7 est toujours utilisé par 50,0 % des sites web PHP, ce qui est obsolète et connu pour être peu sûr. En outre, 13,2 % des sites web PHP utilisent PHP 5, encore plus obsolète (discontinué depuis plus de 5 ans) et peu sûr, et PHP 8.0, qui n'est plus pris en charge, est également très populaire, de sorte que la majorité des sites web PHP n'utilisent pas de versions prises en charge.
La fondation PHP a annoncé que PHP 8.5, dont la sortie est prévue en novembre 2025, apportera une autre fonctionnalité très attendue : l'opérateur pipe (|>). Il s'agit d'une petite fonctionnalité au potentiel énorme, mais qui a tout de même pris des années à voir le jour.
Qu'est-ce qu'un opérateur pipe ?
L'opérateur pipe, écrit |>, est d'une simplicité trompeuse. Il prend la valeur située à sa gauche et la transmet comme argument unique à une fonction (ou, dans le cas de PHP, callable) située à sa droite :
Code PHP : | Sélectionner tout |
1 2 3 4 | $result = "Hello World" |> strlen(...) // Is equivalent to $result = strlen("Hello World"); |
En soi, cela n'a rien de très intéressant. Ce qui est intéressant, c'est lorsqu'il est répété ou enchaîné pour former un « pipeline ». Voici par exemple du code réel issu d'un projet réel, refondu pour utiliser des pipes :
Code PHP : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | $arr = [ new Widget(tags: ['a', 'b', 'c']), new Widget(tags: ['c', 'd', 'e']), new Widget(tags: ['x', 'y', 'a']), ]; $result = $arr |> fn($x) => array_column($x, 'tags') // Gets an array of arrays |> fn($x) => array_merge(...$x) // Flatten into one big array |> array_unique(...) // Remove duplicates |> array_values(...) // Reindex the array. ; // $result is ['a', 'b', 'c', 'd', 'e', 'x', 'y'] |
Le même code sans pipes nécessiterait soit cette horrible imbrication :
Code PHP : | Sélectionner tout |
array_values(array_unique(array_merge(...array_column($arr, 'tags'))));
Ou de créer manuellement une variable temporaire pour chaque étape. Bien que les variables temporaires ne soient pas la pire chose au monde, elles représentent une charge mentale supplémentaire et signifient qu'une chaîne comme celle-ci ne peut pas être utilisée dans un contexte à expression unique, comme un bloc match(). Une chaîne de pipes le peut.
Quiconque a déjà travaillé sur la ligne de commande Unix/Linux reconnaîtra probablement la similitude avec le pipe du shell, |. C'est tout à fait délibéré, car il s'agit en fait de la même chose : utiliser la sortie du côté gauche comme entrée du côté droit.
D'où cela vient-il ?
L'opérateur |> apparaît dans de nombreux langages, principalement dans le monde fonctionnel. F# dispose essentiellement du même opérateur, tout comme OCaml. Elixir propose une version légèrement plus sophistiquée. Il existe de nombreuses bibliothèques PHP qui offrent des fonctionnalités similaires avec de nombreuses étapes supplémentaires coûteuses, y compris la bibliothèque Crell/fp.
L'histoire des pipes PHP commence cependant avec Hack/HHVM, le fork PHP de Facebook, anciennement une implémentation concurrente. Hack incluait de nombreuses fonctionnalités qui allaient au-delà de ce qu'offrait PHP 5 à l'époque ; beaucoup d'entre elles ont finalement été intégrées dans les versions ultérieures de PHP. L'une de ses fonctionnalités était une version unique de l'opérateur pipe.
En 2016, Sara Golemon, contributrice de longue date à PHP et ancienne responsable Open Source du projet HHVM, a proposé de porter directement les pipes de Hack vers PHP. Dans cette RFC, le côté droit d'un pipe n'était pas une fonction callable, mais une expression, et utilisait un jeton magique $$ (affectueusement appelé T_BLING, du moins selon votre serviteur) pour y injecter le résultat du côté gauche. Dans ce cas, l'exemple ci-dessus ressemblerait à ceci :
Code PHP : | Sélectionner tout |
1 2 3 4 5 6 | $result = $arr |> array_column($$, 'tags') |> array_merge(...$$) |> array_unique($$) |> array_values($$) ; |
Bien que puissant, ce système était également quelque peu limitatif. Il était très atypique, contrairement à tous les autres langages. Cela impliquait également une syntaxe étrange et unique pour les fonctions à appel partiel qui ne fonctionnait qu'en association avec des pipes.
Cette RFC n'a pas été soumise au vote. Il ne s'est pas passé grand-chose pendant plusieurs années, jusqu'en 2020/2021. C'est à ce moment-là que Larry Garfield a décidé de s'y attaquer, après avoir écrit un livre sur la programmation fonctionnelle en PHP qui traitait de la composition de fonctions. Il s'est associé à une équipe pour travailler sur l'application partielle de fonctions (PFA) dans le cadre d'une RFC distincte de la pipe plus traditionnelle. L'idée était que transformer une fonction à plusieurs paramètres (comme array_column() ci-dessus) en une fonction à paramètre unique dont |> avait besoin était une fonctionnalité utile en soi, qui devrait pouvoir être utilisée ailleurs. La syntaxe était légèrement différente de celle de la version Hack, afin de la rendre plus flexible : some_function(?, 5, ?, 3, ...), qui prenait une fonction à 5 paramètres ou plus et la transformait en une fonction à 3 paramètres.
Malheureusement, PFA n'a pas été adopté en raison de certains problèmes de complexité du moteur, ce qui a également largement compromis la RFC Pipe v2. Cependant, l'quipe en a tiré un lot de consolation : les First Class Callables (la syntaxe array_values(...)), gracieusement offerts par Nikita Popov, étaient par conception une version « junior » et dégénérée de l'application partielle de fonctions.
En 2025, Larry Garfield s'y est mis à nouveau aux pipes. Cette fois-ci, grâce à une meilleure implémentation et à l'aide précieuse d'Ilija Tovilo et d'Arnaud Le Blanc, tous deux membres de l'équipe de développement de la Fondation PHP, il a réussi à faire passer le projet.
La troisième fois, c'est la bonne.
Plus que la somme de ses parties
Ci-dessus, les pipes ont été décrites comme « d'une simplicité trompeuse ». Leur implémentation est presque triviale ; il s'agit en fait d'un simple sucre syntaxique pour la version avec variable temporaire. Cependant, les meilleures fonctionnalités sont celles qui peuvent être combinées avec d'autres ou utilisées de manière novatrice pour dépasser leur poids.
Nous avons vu plus haut comment un long processus de manipulation de tableaux pouvait désormais être condensé en une seule expression chaînée. Imaginez maintenant que vous utilisiez cela dans des endroits où seule une expression unique est autorisée, comme match() :
Code PHP : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | $string = 'something GoesHERE'; $newString = match ($format) { 'snake_case' => $string |> splitString(...) |> fn($x) => implode('_', $x) |> strtolower(...), 'lowerCamel' => $string |> splitString(...), |> fn($x) => array_map(ucfirst(...), $x) |> fn($x) => implode('', $x) |> lcfirst(...), // Other case options here. }; |
Ou bien, considérez que le côté droit peut également être un appel de fonction qui renvoie Closure. Cela signifie qu'avec quelques fonctions qui renvoient des fonctions :
Code PHP : | Sélectionner tout |
1 2 3 4 5 | $profit = [1, 4, 5] |> loadSeveral(...) |> filter(isOnSale(...)) |> map(sellWidget(...)) |> array_sum(...); |
Ce qui... nous donne à peu près la même chose que les méthodes scalaires dont on a longuement parlé ! Seuls les pipes sont plus flexibles, car vous pouvez utiliser n'importe quelle fonction à droite, et pas seulement celles qui ont été approuvées par les concepteurs du langage en tant que méthodes.
À ce stade, les pipes se rapprochent beaucoup des « fonctions d'extension », une fonctionnalité de Kotlin et C# qui permet d'écrire des fonctions qui ressemblent à des méthodes sur un objet, mais qui ne sont en réalité que des fonctions autonomes. L'orthographe est légèrement différente (| au lieu de -), mais on y est déjà à 75 %, et gratuitement.
Ou allons encore plus loin. Que se passe-t-il si certaines étapes de la pipe renvoient une valeur null ? Nous pouvons, à l'aide d'une seule fonction, « soulever » les éléments de notre chaîne pour traiter les valeurs null de la même manière que les méthodes null-safe.
Code PHP : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | function maybe(\Closure $c): \Closure { return fn(mixed $arg) => $arg === null ? null : $c($arg); } $profit = [1, 4, 5] |> maybe(loadSeveral(...)) |> maybe(filter(isOnSale(...))) |> maybe(map(sellWidget(...))) |> maybe(array_sum(...)); |
C'est exact, on vient d'implémenter une monade Maybe avec un tuyau et une fonction d'une seule ligne.
Maintenant, pensez à cela pour les flux...
Code PHP : | Sélectionner tout |
1 2 3 4 5 6 7 | fopen('pipes.md', 'rb') // No variable, so it will close automatically when GCed. |> decode_rot13(...) |> lines_from_charstream(...) |> map(str_getcsv(...)) |> map(Product::create(...)) |> map($repo->save(...)) ; |
Le potentiel est absolument énorme. Il ne serait pas immodeste de dire que l'opérateur pipe est l'une des fonctionnalités les plus rentables de ces dernières années, au même titre que des fonctionnalités telles que la promotion des propriétés du constructeur. Et tout cela grâce à un petit sucre syntaxique.
Quelle est la prochaine étape ?
Bien que les pipes constituent une étape importante, l'équipe de la Fondation PHP n'en aurait pas fini. Deux RFC sont actuellement en cours d'élaboration.
La première est une deuxième tentative d'application partielle de fonction. Il s'agit d'une fonctionnalité plus importante, mais les fonctions appellables de première classe apportent déjà une grande partie de l'infrastructure nécessaire, ce qui simplifie la mise en œuvre. Les pipes offrant désormais un cas d'utilisation naturel, ainsi que des points d'optimisation faciles, cela vaut la peine de faire une deuxième tentative. La question est de savoir si cette fonctionnalité sera intégrée à PHP 8.5, reportée à la version 8.6 ou à nouveau rejetée.
Le deuxième est un opérateur de composition de fonctions. Alors que pipe s'exécute immédiatement, la composition de fonctions crée une nouvelle fonction en collant deux fonctions bout à bout. Cela signifie que l'exemple de flux ci-dessus pourrait être encore optimisé en combinant les appels map() :
Code PHP : | Sélectionner tout |
1 2 3 4 5 | fopen('pipes.md', 'rb') |> decode_rot13(...) |> lines_from_charstream(...) |> map(str_getcsv(...) + Product::create(...) + $repo->save(...)) ; |
Celui-ci ne sera certainement pas intégré à PHP 8.5, mais peut-être intégrer à la version 8.6.
Il est intéressant de rappeler que PHP a permis la création de millions de sites web partout dans le monde et reste l’une des pierres angulaires du développement web. Ses utilisateurs, qui forment une particulièrement communauté active et impliquée, l’apprécient pour sa flexibilité et sa simplicité d’utilisation. En mars, JetBrains a partagé les résultats de l’Enquête sur l’État de l’Écosystème des Développeurs en 2024, qui permet de comprendre l’état actuel du développement de PHP .
Source : Larry Garfield, Ilija Tovilo et Arnaud Le Blanc, membres de l'équipe de la Fondation PHP
Et vous ?


Voir aussi :



Vous avez lu gratuitement 1 600 articles depuis plus d'un an.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.