![Symfony ExpressionLanguage : Comment utiliser ce composant ?](/imgs/articles/2024-01-17-expressionlanguage-comment-utiliser-ce-composant-symfony/cover-w190-h190-x1.avif)
Symfony ExpressionLanguage : Comment utiliser ce composant ?
Le composant Symfony ExpressionLanguage : qu'est-ce que c'est ? Quand et comment l'utiliser ? Comment créer des expressions lors de cas plus complexes ?
Sommaire
Les 13 & 14 octobre 2022 a eu lieu le mythique Forum PHP 2022 organisé par l'AFUP, dans un lieu non moins mythique : DisneyLand Paris. C'est la première fois que l'AFUP vient poser ses valises dans ce lieu magique, plus précisément dans l'hôtel New York qui dispose de salles de conférences grandioses.
Et vous, il est comment votre vendredi ? pic.twitter.com/SFMqKjIGfb
— AFUP (@afup) October 7, 2022
Les astronautes étaient présents pour assister aux différents talks proposés. Impossible bien entendu d'assister à tout, mais entre rappels et nouveaux apprentissages, voici un retour pêle-mêle sur les talks qui nous ont marqués !
On commence fort car ce n'est pas n'importe qui qui monte sur scène pour ce premier talk. Il s'agit tout simplement de Sebastian Bergmann, notamment créateur de PHPUnit. Il est accompagné de Roman Pronskiy, product marketing manager chez JetBrains.
Ils sont venus nous présenter la PHP Foundation, qu'ils ont créée il y a tout juste un an. Le but ? Réduire le bus factor de l'écosystème PHP.
Rembobinons, qu'est-ce qu'un Bus Factor ? Eh bien c'est simple, ce principe part du postulat que nous allons tous mourir (oui, PHP y compris).
Or, imaginez un bus transportant une poignée de personnes, rassemblant à elles seules 80% de la connaissance sur PHP (le fonctionnement de son moteur, son interpréteur, toutes les zend functions utilisées en C, etc.). Si ce bus se crashe, on perd instantanément toute la connaissance.
La solution à ce problème est de réduire le plus possible le Bus Factor, en partageant au maximum la connaissance sur le développement et la maintenance du langage PHP.
Et c'est exactement le but de la PHP Foundation nouvellement créée. D'après eux, le Bus Factor du PHP est immense sur beaucoup de concepts, et il est important de le réduire le plus possible.
Pour retrouver le support de présentation de ce talk :
Here is the material from the presentation on @ThePHPF that I just gave with @pronskiy at @afup #ForumPHP:https://t.co/wKUrOVuXrI pic.twitter.com/RMbQNf4ibG
— Sebastian Bergmann (@s_bergmann) October 13, 2022
Le premier rappel et le plus important, qui a d'ailleurs été évoqué à de nombreuses reprises durant ce Forum PHP, c'est l'aspect shared-nothing du langage lui-même. Entre 2 requêtes distinctes, PHP oublie tout, ce qui est un avantage pour nous développeurs. Il est plus facile de coder sans se soucier de potentielles fuites mémoire entre deux requêtes, mais c'est également un coût en performance : à chaque requête, on ré-alloue la mémoire nécessaire, on ré-ouvre des connexions, etc.
Note
Plutôt que d'utiliser les traditionnels malloc
& mfree
natifs du langage C, PHP utilise son propre gestionnaire de mémoire ZMM (pour Zend Memory Manager) afin d'optimiser l'allocation de mémoire en PHP, qui s'effectue à chaque requête.
Le SAPI PHP-FPM est très bien optimisé, certes, mais cela ne suffit pas toujours à avoir une application qui fonctionne parfaitement. De plus, il n'existe pas de multi-threading en PHP. On peut cumuler plusieurs processus avec PHP-FPM, mais ce n'est pas une solution illimitée ; chaque nouveau processus va consommer du CPU et de la RAM. Il ne s'agit donc pas d'en rajouter dès que l'application connaît des lenteurs.
Des problèmes, des problèmes, mais où sont les solutions alors ?
Eh bien, au risque de vous décevoir, il n'y a pas de solution magique (auquel cas, vous le sauriez déjà), mais on peut rappeler quelques pistes à prendre en compte lorsque l'on projette d'améliorer nos performances :
Important
En ce qui concerne l'OPCache, l'activer ne suffit pas, le configurer CORRECTEMENT est un point central, au risque d'être totalement contre-productif.
J'en profite pour vous présenter le super compte Twitter de @mdesnouveaux, découvert pendant l'événement, qui a partagé sa prise de notes en format #sketchnotes, admirez :
Retour en #sketchnote sur la conférence de @pascal_martin au #ForumPHP de l’@afup sur le fonctionnement de #php pic.twitter.com/Ep2JeO0SK6
— Mathieu Desnouveaux (@mdesnouveaux) October 13, 2022
Une de mes conférences préférées, merci à Thibault Richard pour ce talk. La présentation de ce design patterns en application dans un cas concret, c'était la meilleure manière d'en prouver l'efficacité et la simplicité.
Ce design pattern implémente un système qui évalue un ensemble de règles pour définir les actions à mener.
Note
C'est un design pattern avant tout indiqué dans un projet comprenant beaucoup de règles métier à vérifier. Si vous constatez une armée de if (...)
qui commence à s'entasser dans votre code pour vérifier chacune d'entre elles, impactant la lisibilité et la testabilité de votre application, alors le Rules engine est fait pour vous.
Il vous faudra dans un premier temps créer 1 fichier par règle métier. Ce fichier devra faire 2 choses :
Ces 2 actions peuvent être dans 2 fonctions différentes ou non, selon votre préférence.
Il ne vous reste plus qu'à créer votre fichier principal, le système. Dans une boucle, on appelera chacune de ces règles pour en exécuter ou non le contenu si la condition est préalablement vérifiée.
Votre code est à présent bien mieux découpé, et beaucoup plus facilement testable : une règle = 1 fichier = 1 test unitaire.
De plus, avec un framework comme Symfony, implémenter ce design pattern peut être plus rapide, grâce aux annotations AutoconfigureTag
et TaggedIterator
.
Note
Vous pouvez même ajouter un attribut priority
sur votre tag si vous souhaitez que vos règles soient appelées dans un ordre particulier, très pratique !
Si des exemples de code sont plus parlant pour vous, retrouvez-en dans les slides de Thibault.
Mon #sketchnote de la conférence « un moteur bien huilé » donné par @t__richard lors du #forumphp de l’@afup concernant le Rule engine pattern. Un sujet intéressant surtout que j’ai eu à implémenter un cas similaire. pic.twitter.com/K0T39CDvWJ
— Mathieu Desnouveaux (@mdesnouveaux) October 17, 2022
Ahhh, les dates... Ne partez pas tout de suite ! Je sais que c'est la némésis de beaucoup d'entre vous, notamment lorsqu'il s'agit d'écrire des tests. Pour venir à bout de ce problème, Andreas Heigl est là pour nous aiguiller.
Question
Pourquoi est-ce si compliqué de tester des dates ?
C'est surtout parce que les fonctions comme time()
qui nous renvoient l'heure actuelle ne sont pas des fonctions pures, c'est-à-dire que la valeur de retour de la fonction n'est pas prédictible, quel que soit l'argument passé, même en utilisant un DateTimeImmutable.
Pour solutionner cela, Andreas nous présente la PSR-20 qui est actuellement en Draft, et est bien nommée Clock. Ce standard fournit une ClockInterface qui permet une interopérabilité avec les tests. Elle expose une méthode now()
qui renvoie un DateTimeImmutable
.
À partir de là, il suffit d'implémenter l'interface avec différents types de Clock
, dont une pourrait par exemple renvoyer toujours la même date, et donc être utilisée pour les tests. Ainsi, vous pouvez utiliser un objet RegularClock
au comportement habituel dans votre code. Et grâce à l'interface, vous pouvez maintenant utiliser votre MockClock
dans vos tests et enfin accéder au bonheur du test unitaire de date sans bug inattendu.
En attendant que cette PSR soit validée, sachez que vous pouvez tout de même en installer une implémentation :
composer require psr/clock
Cependant, après une petite recherche de mon côté, sachez que Symfony a créé son propre composant Clock qui sera disponible dès la version 6.2.
Elle vous permettera d'accéder à ces différentes implémentations de la ClockInterface
:
NativeClock
=> Pour créer une date basée sur celle du système (renvoie simplement un new DateTimeImmutable('now')
) avec une timezone que vous pouvez passer en paramètre.MonotoniClock
=> Une Clock adaptée pour l'analyse de performance par exemple.MockClock
=> Pour renvoyer toujours la même date, votre graal pour les tests.Pour retrouver les slides d'Andreas :
Find the slides of my talk "Watch the Clock" earlier at #ForumPHP at https://t.co/HZfZH25P6n - and while you're there, why not also leave some feedback at https://t.co/nf7ZWmOLoT ? Thanks!
— 💙💛Andreas Heigl @ 🏡 (@heiglandreas) October 13, 2022
Une fois n'est pas coutume, Kévin Dunglas a quelque chose sous la main à nous montrer. Et une fois n'est pas coutume, c'est un outil expérimental qu'il a créé lui-même qu'il nous présente. Voici FrankenPHP.
Question
Quel est le problème de base ?
Le constat principal de Kévin est le suivant : il est compliqué de dockeriser une application PHP / Symfony, notamment avec PHP-FPM qui est un service externe.
On se retrouve donc rapidement avec une architecture complexe juste pour avoir une application qui tourne.
La solution est double :
Premièrement, partir d'une base Caddy pour le serveur. Nginx fait partie des serveurs web les plus populaires aujourd'hui, mais depuis que Caddy a pointé le bout de son nez, il lui vole la vedette. Une configuration plus intuitive et plus simple, une résolution automatique de certificat pour le HTTPS, une extensibilité par modules, le support des HTTP 103 (Early Hint)... Tout ça, c'est la modernité de Caddy, le serveur web écrit en Go.
Ensuite, il y a FrankenPHP en lui-même, un SAPI (Serveur Application Programming Interface), lui-même écrit en Go, qui fonctionne directement par-dessus Caddy.
L'avantage ? Plus besoin de dockeriser plusieurs containers pour notre serveur web d'un côté, et notre SAPI (PHP-FPM) de l'autre, qui doivent communiquer ensemble.
À présent, vous avez un seul service. One service to rule them all, and in docker, bind them. On parle de Docker, mais FrankenPHP est tout aussi facile d'utilisation sans.
Note
Pour la config ? Plus qu'à éditer votre Caddyfile pour la partie Web server, et votre php.ini pour la partie applicative. FrankenPHP vient également avec une intégration spéciale Symfony pour en facilité l'interopérabilité.
Le tout étant bâti sur Caddy et donc Go, votre application peut à présent supporter la puissance des Early Hints.
Mais une des killers features de FrankenPHP, c'est son Worker Mode. Grâce à ce mode, Franken construit votre application une seule fois au démarrage et la garde en mémoire, ce qui permet de traiter toutes les futures requêtes sans avoir à redémarrer l'application à chaque fois, comme le voudrait le comportement de base de PHP.
Ce comportement est compatible avec Symfony et Laravel, et permet d'atteindre des performances assez dingues, d'après le benchmark que Kévin nous présente.
Important
S'il est découragé d'utiliser FrankenPHP en production pour le moment, c'est d'autant plus le cas pour son Worker Mode. Vous pouvez être sûr de faire face à des bugs en vous y essayant. Préférez plutôt tester l'outil en local et remonter les bugs à Kévin (voire de faire une PR, FrankenPHP est open source !) pour le faire grandir en maturité.
Et pour finir, le site de FrankenPHP, et ci-dessous notre habituel sketchnote :
Retour en #sketchnote sur la découverte de #frankenphp, un serveur d’application PHP par @dunglas lors de sa conférence au #ForumPHP de l’@afup pic.twitter.com/j9cXLAtETs
— Mathieu Desnouveaux (@mdesnouveaux) October 14, 2022
Ce fut un ForumPHP encore riche en partage, qui a atteint le nombre record de 774 participants. De quoi faire taire ceux qui pensent que le PHP est mort. Les évolutions et acquis récents de notre langage préféré prouvent qu'il a encore de belles années devant lui, et c'était un plaisir de partager le même état d'esprit et la même philosophie avec autant d'homologues.
Je ne pouvais pas vous partager toutes les conférences de manière exhaustive, mais restez connectés sur youtube pour accéder aux replays des talks qui seront partagés bientôt !
Merci aux conférenciers, aux participants, et surtout, merci au PHP.
Auteur(s)
Arthur Jacquemin
Développeur de contenu + ou - pertinent @ ElevenLabs_🚀
Vous souhaitez en savoir plus sur le sujet ?
Organisons un échange !
Notre équipe d'experts répond à toutes vos questions.
Nous contacterDécouvrez nos autres contenus dans le même thème
Le composant Symfony ExpressionLanguage : qu'est-ce que c'est ? Quand et comment l'utiliser ? Comment créer des expressions lors de cas plus complexes ?
Découvrez comment réaliser du typage générique en PHP : introduction et définition du concept, conseils et explications pas-à-pas de cas pratique.
Découvrez un cas d'usage d'intégration d'un CRM avec une application e-commerce, en asynchrone, avec Hubspot et RabbitMQ