SymfonyLive Paris 2025 comme si vous y étiez
Les 27 et 28 mars 2025, la Cité Internationale Universitaire de Paris a résonné sous les applaudissements : le Symfony Live Paris célébrait les 20 ans de Symfony !
Nous y étions à la fois en tant que spectateurs assidus mais aussi pour partager notre expérience avec 2 conférences (Mercure et HTMX) et 2 Lightnings Talks (MCP et User Agent).
Dans cet article, nous souhaitons partager ce que nous retenons de ces deux journées – si vous n’y étiez pas, voici ce que vous avez raté !
Section intitulée la-keynote-de-fabien-potencierLa Keynote de Fabien Potencier
Fabien a ouvert la journée de conférence avec sa keynote. Il y a retracé l’histoire de l’initiative DX de Symfony, qui a officiellement commencé en 2017 avec l’arrivée de Symfony Flex. Son objectif : simplifier l’installation et la configuration des packages Composer. Depuis, cette démarche d’amélioration continue ne s’est jamais arrêtée, pour notre plus grand bonheur.
Il a également souligné qu’un package open-source, sans communauté ni documentation, n’est pas réellement open-source. Pour lui (et nous partageons cette vision) :
Community > DX > Doc > Code
Pour conclure sa keynote, il s’est appuyé sur un post récent dans l’écosystème Laravel pour poser une question surprenante : serait-il possible de faire tenir toute une application Symfony dans un seul fichier ?
La réponse est oui. Il a nommé cette édition expérimentale « Symfony Hello ». Toutefois, elle n’est pas disponible en ligne, car elle n’a pas d’utilité pratique, si ce n’est pour la beauté de l’exercice ou comme démonstration technique.
Poussant l’idée encore plus loin, il s’est demandé s’il était possible d’avoir un unique fichier capable de servir une application Symfony aussi bien en HTTP qu’en CLI. Là encore, la réponse est oui 🎉. Il a baptisé cette version « Symfony Solo » (ndlr : on aurait aussi pu l’appeler « Symfony YOLO » 😆). Dans cette édition, il est possible de refactorer le code en plusieurs fichiers pour plus de lisibilité. Et avec seulement quelques lignes de configuration, Symfony continue de fonctionner 💪.
À travers ces démonstrations, Fabien a prouvé que Symfony est d’une flexibilité remarquable, capable de s’adapter à tous les besoins et toutes les architectures.
Section intitulée autour-des-apiAutour des API
Section intitulée le-composant-symfony-mapper-antoine-bluchetLe composant Symfony Mapper – Antoine Bluchet
Un nouveau composant Symfony vient d’arriver dans notre boîte à outils 🎉
Le ObjectMapper est conçu pour faciliter la transformation de données entre différentes structures dans les applications Symfony. Contrairement au Symfony Serializer, qui convertit des objets en formats spécifiques (JSON, XML) et vice versa, le ObjectMapper se concentre sur la conversion d’un objet en un autre, simplifiant ainsi le mapping de données complexes.
L’interface proposée est super simple :
interface ObjectMapperInterface
{
/**
* @template T of object
*
* @param object $source The object to map from
* @param T|class-string<T>|null $target The object or class to map to
*
* @return T
*
* @throws MappingException When the mapping configuration is wrong
* @throws MappingTransformException When a transformation on an object does not return an object
*/
public function map(object $source, object|string|null $target = null): object;
}
L’importance du mapping est évidente dans de nombreux frameworks. Par exemple, Doctrine utilise un mapper sophistiqué pour convertir les représentations de bases de données relationnelles en entités PHP. Cependant, jusqu’à présent, Symfony ne disposait pas d’une solution native pour ce type de transformation entre objets.
Nous sommes très impliqués dans le développement de Mapper en PHP et nous avons beaucoup apprécié qu’Antoine retrace l’histoire des différentes tentatives d’intégration d’un tel composant dans Symfony – des essais infructueux qui ont fini par donner naissance à notre AutoMapper ✌️
Concernant ObjectMapper, le composant est marqué comme expérimental et son implémentation dans API Platform est en cours – nous retenons que les performances sont un axe d’amélioration futur important.
Section intitulée api-platform-sans-doctrine-jerome-tamarelleApi Platform sans Doctrine – Jérôme Tamarelle
ApiPlatform est excellent pour l’effet waouh 😍 : à partir d’une entité Doctrine, l’ajout d’un attribut #[ApiResource]
suffit pour avoir un CRUD complet sur cet objet.
Cependant, si l’on se limite à cette approche directe sur une entité, on atteint vite ses limites dès que l’on sort des scénarios très basiques. C’est ce que souligne Jérôme (et nous le constatons aussi chez JoliCode).
Jérôme a développé une application de recettes de cuisine pour illustrer son propos. Il s’agit d’une application CRUD classique, avec de nombreuses relations (ingrédients, étapes, notes, auteurs).
Dès le premier endpoint, on constate que l’API génère un nombre énorme de requêtes SQL. Il faut récupérer les ingrédients, les étapes, les notes, les auteurs, etc. En d’autres termes, toutes les relations de l’objet recette doivent être chargées.
Une première idée d’optimisation consiste à utiliser des JOIN SQL pour récupérer toutes les relations en une seule requête. Cependant, cela entraîne un volume de données considérable (recette × ingrédients × étapes × notes × auteurs). Doctrine met alors beaucoup de temps à hydrater tous ces objets.
Jérôme a donc eu l’idée d’exploiter les fonctionnalités JSON de PostgreSQL pour regrouper directement les données :
- Les relations one-to-one sont encapsulées dans un objet avec
json_select()
; - Les relations one-to-many sont regroupés dans un tableau avec
json_group_array()
.
Résultat : une seule requête SQL permet de récupérer uniquement les données nécessaires, sans avoir à mapper tous les objets Doctrine.
Malheureusement, le format obtenu ne correspond pas à ce que Doctrine attend, ce qui empêche son système de mapping de fonctionner automatiquement.
Il va donc falloir mapper tout ça. Le résultat de la requête SQL custom va être représenté par un DTO, qui sera défini comme une ressource API grâce à l’attribut ApiResource
, mais avec un provider custom ApiPlatform\State\ProviderInterface
.
Pour passer du résultat SQL à son joli DTO, Jérôme utilise notre jolicode/automapper et sa dernière feature, le mapCollection
qui vient tout juste d’être ajoutée.
Tous ces problèmes n’arrivent qu’à cause de la nature relationnelle des données, stockées dans des tables, bien normalisées. MongoDB est un moteur NoSQL qui permet de stocker des objets JSON nested (et bien d’autres choses). Exit l’ORM et bonjour l’ODM de Doctrine, qui permet de gérer les objets EmbeddedDocument (rien à voir avec l’Embedded que l’on retrouve dans l’ORM et qui n’est qu’un autre moyen de grouper des champs de la même table).
Cette conférence est un excellent état des lieux sur comment faire un backend custom avec APIP, qui n’est décidément pas si fortement couplé avec Doctrine.
Section intitulée developper-avec-api-platform-4-ca-change-quoi-mathias-arlaudDévelopper avec API Platform 4, ça change quoi ? – Mathias Arlaud
À travers son histoire personnelle, Mathias nous explique comment APIP est passé de la version 1 à la version 4 actuelle. APIP a provoqué pas mal de breaking changes et a mûri pour devenir aujourd’hui un membre éminent de l’écosystème PHP (Symfony et Laravel).
Cette conférence explique au passage les genèses des deux interventions d’Antoine et Jérôme dont nous venons de parler :
- Il faut privilégier les DTO aux ressources sur les entités ;
- On découple le modèle de données en base et la représentation en API, permettant ainsi de faire évoluer les deux séparément. On évite ainsi les getters mal adaptés dans les entités et les normalizers customs ;
- Cela permet d’avoir plusieurs représentation de la même entité sans multiplier les groupes de sérialisation, difficiles à maintenir ;
- L’arrivée imminente de l’ObjectMapper va supprimer le besoin de provider et processor custom ;
- C’est déjà ce que nous faisons sur nombre de nos projets (sauf ceux bloqués sur la version 2.7 d’APIP…), avec notre jolicode/automapper.
Mathias est un excellent orateur et le vécu commun en a fait une conférence qui a vraiment résonné avec nos propres parcours.
Section intitulée autour-de-la-securiteAutour de la sécurité
Section intitulée passkeys-pour-une-authentification-fluide-et-securisee-remi-janotPasskeys pour une authentification fluide et sécurisée – Rémi Janot
Rémi a commencé sa conférence en présentant quelques dates : la création du mot de passe dans les années 60, la création de l’authentification à deux facteurs en 1987, puis à son adoption à partir de 2011.
Après un rappel sur le brute force des mots de passe, le phishing, les fuites de données, Rémi était là pour nous parler de WebAuthn, une API Javascript disponible dans tous les navigateurs (quelques soucis avec Firefox + TouchID par contre) permettant de s’authentifier sur un site sans avoir à utiliser de mots de passe traditionnels. À la place on utilise un « authentificateur » comme un lecteur d’empreinte digital ou une clé type YubiKey.
L’API JS est extrêmement simple : 1 ligne pour s’enregistrer, 1 ligne pour s’authentifier.
Mais évidemment, il va falloir également gérer cette méthode côté serveur. Il existe différents bundles Symfony pour ajouter cette fonctionnalité, mais Rémi nous conseille web-auth/webauthn-symfony-bundle. À part la configuration du bundle qui semble un peu fastidieuse, la démo présentée pendant la conférence nous a largement donné envie d’implémenter ça sur un maximum d’applications web.
Rémi met aussi l’accent sur un point ⚠️ : même si c’est une très bonne solution, il sera nécessaire tout de même de conserver un autre moyen d’authentification comme mécanisme de secours.
Section intitulée roles-amp-permissions-developper-une-marque-blanche-avec-du-feature-flipping-florian-bogeyRôles & permissions : développer une marque blanche avec du feature flipping – Florian Bogey
À nos débuts avec Symfony, il était difficile de gérer plusieurs applications avec des configurations différentes – sur un de nos projets notamment. Depuis, beaucoup d’outils sont apparus, et nous avons pu regrouper les différentes applications Symfony 2, 3 et 4 de ce projet en une seule application Symfony 6 beaucoup plus maintenable, grâce aux variables d’environnement et aux Voters.
C’est ce qu’est venu nous proposer Florian : la gestion d’une application métier multi-clients en marque blanche. Il détaille l’utilisation des rôles et permissions dans Symfony, avec l’implémentation d’un CustomVoter et une API exposant des permissions dynamiques (que ce soit pour le backend PHP ou pour VueJS). L’équipe exploite la flexibilité des voters Symfony pour créer un système de feature flipping maison, préféré aux solutions existantes comme OpenFeature.
L’utilisation de Redis rend l’ensemble très performant (même si, Redis, ce n’est pas que pour le cache !).
La combinatoire des feature flipping peut vite augmenter et créer des scénarios difficiles à tester et à anticiper. Pas de remède magique (en dehors des tests), mais la communication entre les différents intervenants est clé, avec des templates de ticket et de documentation pour appuyer les différentes features. Des règles PHPStan garantissent le bon usage des features flags, tandis qu’une extension du MakerBundle génère automatiquement les feature flags et migrations.
Une interface CRUD sur leur back-office permet de modifier les configurations à chaud selon les besoins spécifiques de chaque client et si de mauvaises configurations ont été envoyées en production par erreur. L’expérience lui fera par ailleurs dire que ce n’était pas essentiel, ce qui est concordant avec notre propre expérience.
Section intitulée autour-du-frontendAutour du frontend
Section intitulée symfony-ux-points-forts-de-2024-et-perspectives-d-avenir-simon-andreSymfony UX : Points forts de 2024 et perspectives d’avenir – Simon André
Simon est membre de la nouvelle Core Team Symfony UX – et sa conférence était principalement orientée sur l’analyse de l’adoption des composants UX par la communauté.
Nous utilisons 15 fois plus Symfony UX en 2024 qu’en 2022, pour résumer ! 😋
Les véritables informations que nous avons glanées sont :
- StimulusBundle sera peut-être renommé UXBundle un jour tant il est le point de départ de tous les autres ;
- LazyImage va être déprécié et supprimé ;
- UX Map a été intégré en Live Component dans la version 2.23, pour faire des cartes beaucoup plus puissantes sans écrire de JavaScript ; Avec la version à venir (2.24) nous pourrons avoir les UX Icons sur nos UX Map 👌
- Un nouveau site est en préparation ;
- et probablement UX 3 pour la rentrée, avec quelques BC Breaks.
Section intitulée atteindre-la-qualite-d-une-spa-avec-htmx-et-twig-damien-alexandreAtteindre la qualité d’une SPA avec HTMX et Twig – Damien Alexandre
L’avènement des SPA (Single Page Application) a permis la réalisation d’applications Web de plus en plus riches, dynamiques et réactives ; mais à quel prix ? N’y a-t-il pas une autre voie ? Plus proche d’HTTP et HTML sans compromettre la qualité et l’expérience utilisateur ?
C’est la promesse de la librairie HTMX que Damien nous a présenté. Avec quelques attributs dans notre Twig, il est possible de coder des comportements dynamiques riches et très explicites.
{% block like %}
<button class="{{ isLiked ? 'text-rose-600' : 'text-neutral-500' }}"
hx-post="{{ path('app_like_toggle') }}"
hx-swap="outerHTML"
>❤</button>
{% endblock %}
Par exemple, cet extrait va faire un appel AJAX à la route app_like_toggle
en POST, et placer le contenu de la réponse HTTP à la place du bouton lui-même.
Damien a présenté de nombreux exemples comme la gestion des formulaires, le scroll infini, la recherche « as you type », le chargement asynchrone… afin de prouver que oui, les développeurs backend peuvent faire des fonctionnalités riches sans avoir à embarquer trop de JavaScript.
Il partage aussi les astuces suivantes :
- Il y a un bundle tomcri/htmxpony pour améliorer la DX ;
- Vous pouvez activer le support de HTMX dans PHPStorm ;
hincludes.js
n’est plus nécessaire ;- Turbo Stream / les SSE c’est aussi possible en HTMX.
Pour finir il faut bien le dire, dans la communauté, Stimulus est recommandé pour vos comportements JavaScript custom, et Damien recommande d’utiliser Hotwire Turbo si vous avez déjà Stimulus sur votre projet car les deux sont très bien intégrés ensembles. HTMX est donc plutôt réservé aux projets sans Symfony UX.
Section intitulée autour-de-la-performanceAutour de la performance
Section intitulée developper-plus-vite-avec-frankenphp-kevin-dunglasDévelopper plus vite avec FrankenPHP – Kévin Dunglas
Nous aimons Symfony pour ses performances en production et sa DX qui nous permet de développer efficacement. Nous avons à notre disposition des tas d’outils humain friendly (YAML, Twig, attributes, le composant Config…) qui ne sont pas natifs à PHP et doivent être parsés régulièrement pour refléter les modifications apportées par les développeurs. Symfony parse, compile, transforme en PHP… pour que cela soit rapide.
Cela dépend des accès disques, de l’OS, du nombre de fichiers. Nous avons d’ailleurs expliqué le fonctionnement interne et apporté des améliorations il y a quelques années, qui avait beaucoup amélioré le quotidien des développeurs sur nos projets.
Toutes ces opérations en prod ne sont faites qu’une fois, de préférence au warmup de l’application. Mais PHP fonctionne en fire and forget, et chaque requête est individuelle (modulo opcache et le preload).
Ces deux problèmes sont difficilement résolvables en touchant à Symfony lui-même, qui a déjà une certaine complexité sur ces sujets là afin d’optimiser tous les chemins d’exécution possible. La solution doit venir d’ailleurs. C’est ce que propose Kévin Dunglas avec FrankenPHP.
FrankenPHP est plus qu’un remplacement de php-fpm. Il est la combinaison très performante (développée en Go) d’un runtime PHP, d’un serveur Web (basé sur Caddy), d’un serveur SSE (Mercure). Et il va encore plus loin pour l’état de l’art :
- un mode worker, optionnel (en prod) qui permet de garder votre application dans une loop infinie à l’aide de https://github.com/php-runtime/frankenphp-symfony. Les performances s’améliorent alors drastiquement. Il faut par contre contrôler l’utilisation de la mémoire ;
- un mode worker + watcher (en dev) qui permet de déléguer au runtime toute la gestion de la surveillance des fichiers modifiés et leur recompilation. Le développement de cette brique s’est révélé très complexe, merci Kevin.
Les performances sont vraiment au rendez-vous comme le montre ce benchmark indépendant :
FrankenPHP est encore un projet assez jeune, l’adopter en production peut se révéler encore compliqué à justifier mais les récents développements sur l’environnement de développement peuvent faire exploser son utilisation à grande échelle pour toutes les personnes soucieuses de la performance qui aiment la DX.
Qui sait, bientôt nous aurons peut-être nous aussi du Hot Reload avec Turbo !
Section intitulée asynchrone-avec-symfony-messenger-et-mercure-gregoire-pineauAsynchrone avec Symfony Messenger et Mercure – Grégoire Pineau
Symfony Messenger et Mercure permettent d’améliorer la performance et l’expérience utilisateur en combinant traitements asynchrones et notifications en temps réel. Lorsqu’une tâche lourde, comme un import CSV, est exécutée de manière synchrone, l’utilisateur doit attendre la fin du processus, ce qui peut être frustrant et entraîner des erreurs s’il quitte la page. En déléguant ces traitements en arrière-plan via Messenger, on libère l’utilisateur de cette attente, rendant l’application plus fluide et scalable.
Cependant, l’asynchronisme seul ne suffit pas toujours : il faut aussi informer l’utilisateur de l’état de ses actions. C’est là que Mercure intervient, en permettant de pousser des mises à jour en temps réel vers le navigateur ou une application mobile. Cette combinaison Messenger + Mercure assure une application réactive et performante.
En intégrant ces outils, on obtient une meilleure séparation des responsabilités : Messenger prend en charge les traitements de fond, tandis que Mercure maintient une interface utilisateur réactive. Résultat : une application Symfony moderne, fluide et efficace.
Dans ce talk, Grégoire nous montre comment brancher Mercure avec Symfony avec un exemple fil rouge très complet. Nous retenons l’idée de pousser directement du HTML dans le Message, simplifiant l’utilisation avec Turbo !
Bonus : Retrouvez la démo sur github
Section intitulée autour-de-l-architectureAutour de l’architecture
Section intitulée du-lego-de-composants-pour-un-bundle-gotenberg-hubert-lenoir-adrien-rochesDu Lego de composants pour un bundle Gotenberg – Hubert Lenoir, Adrien Roches
Après une introduction sur les différentes façons de construire un PDF avec PHP, les conférenciers ont présenté l’utilisation de Gotenberg, une solution que nous utilisons également à JoliCode. Pour résumer, c’est un service qui expose une API HTTP permettant de convertir du HTML, du Markdown, des documents Word, Excel, etc., en PDF via une API unifiée. De plus, ce service peut être utilisé via une image Docker, ce qui simplifie grandement son installation.
Cependant, cette conférence ne se focalisait pas uniquement sur la génération de PDF. Elle visait aussi à mettre en lumière des fonctionnalités peu connues de PHP et des mécanismes avancés de Symfony.
Au programme :
- L’utilisation des iterators PHP combinés avec le stream du client HTTP de Symfony, afin de minimiser la consommation mémoire de PHP ;
- L’emploi des composants Webhook et RemoteEvent pour rendre la génération asynchrone ;
- La construction d’un bundle, de la configuration sémantique à l’utilisation des compiler pass pour configurer le conteneur d’injection de dépendances, en passant par la création d’un profiler pour faciliter le debug.
Retrouvez les slides en ligne pour en apprendre davantage, vous y trouverez de nombreuses astuces comme par exemple la possibilité de dire à PHPStorm qu’un argument est une route Symfony !
/**
* Translate route
*
* @param $route string #Route to translate the URL for
* @param $locale string Locale to translate into
*/
protected function translateRoute($route, $locale) {
// ...
}
Le bundle est aussi public et est hébergé sur github.
Section intitulée tirez-profit-de-messenger-pour-ameliorer-votre-architecture-tugdual-saunierTirez profit de Messenger pour améliorer votre architecture – Tugdual Saunier
Tugdual nous a présenté avec brio comment utiliser le composant Messenger en synchrone pour améliorer l’architecture de son application.
D’ordinaire, nous utilisons Messenger pour les traitements asynchrones. L’approche proposée est différente.
Il utilise des Message pour faire circuler des appels à des services, et cela apporte beaucoup de confort :
- Le Message est un DTO, il est particulièrement adapté aux FormType ;
- Messenger et ses middleware sont capable de valider le message ;
- Avec un mapper nous pouvons passer d’un DTO à notre entité facilement et ainsi ne jamais polluer une entité avec des données invalides ;
- Notre Handler est facilement testable, créer des Messages de test est trivial ;
- Cela force à penser « métier » : le Message ainsi utilisé représente une action utilisateur ;
- Les middleware Messenger sont super utiles : transaction, validation, sécurité…
- Il propose aussi de créer un middleware « audit » pour loguer toutes les actions métiers qui passent dans le bus ! C’est une superbe idée.
Sans compter les outils de debug, la commande « make » : et si Messenger était le meilleur outil de Command Bus Pattern ? 🙂
Section intitulée keynote-nicolas-grekasKeynote – Nicolas Grekas
Pour terminer ces deux journées riches en enseignements, Nicolas à fait un tour d’horizon des nouveautés à venir dans Symfony. Les versions 7.4 (LTS) et 8 vont sortir en novembre mais nous profiterons des nouvelles fonctionnalités dès la 7.3.
Nous pouvons citer le gros travail sur PHPUnit, les nouveaux composants JsonStreamer, ObjectMapper et JsonPath, ou encore le support de HTTP/3 dans le HttpClient.
Section intitulée le-mot-de-la-finLe mot de la fin
Vous pouvez retrouver tous les sujets, les slides et bien plus encore sur ce repository GitHub, maintenu par Romain Gautier, merci à lui ♥️
Merci à toute l’équipe en charge de cet événement, ainsi qu’à William JEZEQUEL pour les superbes photos !
Rendez-vous l’année prochaine ! 🫶
Cet article porte sur la conférence SymfonyLive Paris 2025.
Commentaires et discussions
Ces clients ont profité de notre expertise
Groupama Épargne Salariale digitalise son expérience client en leur permettant d’effectuer leurs versements d’épargne salariale en ligne. L’application offre aux entreprises une interface web claire et dynamique, composé d’un tunnel de versement complet : import des salariés via fichier Excel, rappel des contrats souscrits et des plans disponibles, …
Studapart a fait appel à JoliCode pour surmonter plusieurs défis techniques que leur équipe interne ne pouvait gérer, faute de temps ou d’expertise. Nous avons travaillé ensemble pour améliorer leur processus d’onboarding des développeurs, résoudre des problématiques complexes de gestion des droits, et configurer correctement leurs certificats HTTP/HTTPS…
Cacharel, marque emblématique du prêt-à-porter féminin et du parfum, s’associe à JoliCode pour accélérer son virage digital et renouer avec les jeunes femmes après trois ans d’absence. Avec une nouvelle direction artistique, l’objectif est de proposer une collection moderne tout en restant fidèle à l’héritage de la marque. Pour accompagner cette renaissance, …