DEV Community

Thérage Kévin for SensioLabs

Posted on

SymfonyLive Paris 2025 : Ce qu’il faut retenir

J’ai eu la chance d’assister au SymfonyLive Paris 2025, et voici un résumé des annonces, conférences et tendances clés à retenir !

Retrouvez les slides sur ce merveilleux dépôt (Merci Romain Gautier🙏) : https://github.com/SymfonyLive/paris-2025-talks)


Keynote : Scaling to 0 (🎤 Fabien Potencier)

🚀 Qu'est-ce qu'un projet Open Source ?

Un projet open source, ce n'est pas seulement du code. Voici la hiérarchie des priorités :

  1. Communauté
  2. Documentation
  3. Code

Une communauté active et une documentation solide sont essentielles pour assurer la pérennité d’un projet OS.

Avec le temps, Symfony a intégré une nouvelle priorité : l’expérience développeur (DX). La hiérarchie évolue donc ainsi :

  1. Communauté
  2. Documentation
  3. Expérience développeur (DX)
  4. Code

🏗️ Comment créer une application Symfony simple ?

Suite aux débats dans la communauté Laravel sur la complexité d’installation et la multitude de dépendances requises pour démarrer un projet, Fabien s’est posé la question :

"Quelle est l'application Symfony la plus simple possible ?"

En réponse, Symfony propose désormais trois nouveaux points d’entrée, permettant de commencer petit et d’évoluer progressivement.


🔹 Symfony Hello

Une version "Hello world" ultra-minimaliste de Symfony, offrant la puissance du full-stack framework avec une empreinte réduite.

Échelle Taille d'équipe Structuration Conventions
Fichier unique Solo dev Aucune Aucune

✅ Idéal pour :

  • Rapidité
  • Flexibilité
  • Prototypage (PoC) minimaliste
  • Projets personnels non maintenus

🔹 Symfony Solo

Symfony sans Flex, offrant un contrôle total sur l’architecture.

💡 Il permet un front controller CLI & HTTP grâce au composant Runtime :

$mode = PHP_SAPI === 'cli' ? 'console' : 'http';
Enter fullscreen mode Exit fullscreen mode
Échelle Taille d'équipe Structuration Conventions
Petits/moyens projets Solo dev Aucune (personnalisable) Aucune (liberté totale)

✅ Idéal pour :

  • Commencer en toute légèreté
  • Scalabilité progressive (scale as you go)
  • Applications mono-tâche
  • Projets personnels avancés
  • PoC élaborés

🔹 Symfony Team

Le framework full-stack classique, conçu pour les projets de grande envergure.

Échelle Taille d'équipe Structuration Conventions
Moyens à grands projets Équipe de devs Standardisée Documentées

✅ Idéal pour :

  • Industrialisation
  • Travail collaboratif
  • Maintenance à long terme
  • Projets professionnels

⚙️ Un petit teaser à propos de Symfony 8

  • Disparition des fichiers XML pour la configuration des routes, désormais remplacés par des fichiers PHP.

🤖 Hot Takes sur les LLMs

  • Les LLMs ne remplaceront pas les développeurs.
  • Ce sont d’excellents stagiaires : disponibles 24/7, polis… mais parfois incohérents !
  • Très utiles contre le syndrome de la page blanche.
  • Claude s’avère particulièrement efficace pour la génération de code et de documentation.
  • Possibilité d’utiliser les LLMs pour :
    • Mise à jour automatique du code (avec prudence).
    • Documentation des PRs pour améliorer la revue de code.

Symfony ObjectMapper Component (🎤 Antoine Bluchet)

Après une partie d'historique sur l'arrivée du composant dans Symfony. Antoine a démarré par présenter le ce qui existait dans les autres langages et en PHP.

🏗️ Object Mapping dans d'autres languages

  • Spring : jackson
  • .Net : automapper
  • Java :
    • modelmapper
    • Java Map Struct
  • Ruby : Ruby Object Mapper (ROM)

🛠️ Etat du mapping en d'objet en PHP

  • Valinor : offre du mapping et bien plus (ce qui n'est pas une bonne chose selon Antoine)
  • Automapper (JoliCode) : Fonctionne sur le principe de génération de classe PHP pour mapper les objets
  • MicroMapper (SymfonyCasts) : version simpliste.
  • et bien d'autres

🎯 Mapping vs Hydratation

  • Hydratation : remplir un objet avec des données.
  • Mapping : transformer un objet en un autre objet.

💡 Contrairement au serializer, le mapping en PHP permet une meilleure séparation des responsabilités et une meilleure intégration avec Symfony.

Le composant

Le composant offre une approche simple via des attributs permettant de faire un mapping rapide via des attributs.

vous pouvez retrouver la Pull-Request ici

Exemple :

use Symfony\Component\ObjectMapper\ObjectMapper;
use Symfony\Component\ObjectMapper\Attributes\Map;

// This maps class `A` to class `B`.
#[Map(B::class)]
class A
{
    // This maps A::foo to B::bar.
    #[Map(target: 'bar')]
    public string $foo;

    // This calls ucfirst on A::transform
    #[Map(transform: 'ucfirst')]
    public string $name;

    // This doesn't map A::bar if it's value is falsy.
    #[Map(if: 'boolval')]
    public bool $bar = false;
}

$mapper = new ObjectMapper();
$mapper->map(new A);
Enter fullscreen mode Exit fullscreen mode

PostgreSQL pour vos besoins NoSQL (🎤 David Buchmann)

Après une brève introduction et un rappel sur le fait que le NoSQL n'est pas clairement défini alternant entre base de donnée non-relationnel et le fait qu'une base de donnée relationnel permette aussi de stocker des élements sans relation, il a fait le tours des fonctionnalité de PostGreSQL et de MySQL (ce qui a été une petite surprise compte tenu du titre) permettant de stocker et de requête du JSON.

🔍 Type de colonne JSON vs JSONb

En PostGreSQL deux types de colonnes son proposés JSON et JSONb avec leurs avantages et leurs incovénients.

Avantages Inconvénients
JSON Préserve l'ordre des clés dans l'objet stocké sous forme de chaîne de caractères
aucune optimisation des caractères répétés
accepte du JSON invalide (garde les clés dupliquées)
JSONb format binaire optimisé
Performant pour les requêtes
Aucune mention faite

En dehors de cas d'utilisation non standard, il est préférable d'utiliser JSONB.

⚙️ Opérateurs utiles

Soit le JSON suivant :

{"author": "David"}
Enter fullscreen mode Exit fullscreen mode
  • -> : extrait une information JSON. ie : renvoie "David"
  • ->> : extrait une donnée native tout en etant 2.5 fois plus rapide. ie : renvoie David

L'opérateur -> existe aussi pour MySQL mais il faut préciser le JSONPath :
->'$.author'

Ajouter un index sur un champ json

Il est possible d'ajouter un index sur un champ JSON via l'instruction

CREATE INDEX name ON json_column ((json_column->>'author'));
Enter fullscreen mode Exit fullscreen mode

Ce qui améliore le temps de requête considérablement.

Générer une colonne à partir d'une propriété JSON

Il est possible d'extraire et de générer une colonne à partir d'une propriété JSON via l'instruction

CREATE TABLE foo (
    # ...
    author VAR_CHAR(255) generated always as (json_column->>'author') stored,
    # ...
);
Enter fullscreen mode Exit fullscreen mode

l'extraction d'une date est compliqué est nécessite de passer par une procédure stockée.

Fonctions utiles

  • contient :
    • json_column @> '{"author": "David"}'
  • la clé existe :
    • json_column ? 'author'
    • jsonb_exists(json_column, 'author')
  • au moins une clé existe :
    • json_column ?| array['author', 'it_does_not_exists']
    • jsonb_exists_any(json_column, array['author', 'it_does_not_exists'])
  • toutes les clé existent :
    • json_column ?& array['author', 'it_does_not_exists']
    • jsonb_exists_all(json_column, array['author', 'it_does_not_exists'])

Passkeys pour une authentification fluide et sécurisée (🎤 Rémi Janot)

🔐 Problèmes des mots de passe

  • Créés dans les années 60, ils sont devenus vulnérables.
  • Brute-force, phishing, réutilisation
  • HaveIBeenPwned révèle l’ampleur des fuites de données.

🔑 2FA / MFA

Réside sur 3 piliers :

  1. Ce que l'on sait (mot de passe).
  2. Ce que l'on a (téléphone, clé de sécurité).
  3. Ce que l'on est (empreinte digitale, reconnaissance faciale).

🌍 WebAuthn

  • API JS, supportée par 96 % des navigateurs.
  • S'appuie sur les 3 piliers du 2FA / MFA

💻 Démonstration

La démonstration d'un intégration d'un système d'authentification WebAuthn a ensuite été présentée par Rémi avec une explication étape par étape de ce qui était transmis au serveur (payload JSON, request/response).

Retrouvez le dépôt du projet de démonstration ici


Symfony UX : Points forts de 2024 et perspectives d’avenir (🎤 Simon André)

5 ans après : où en est Symfony UX ?

👨‍💻 Symfony UX core team

Officialisation de la core team Symfony UX avec pour membres :

  • Ryan Weaver
  • Kévin Bond
  • Hugo Alliaume
  • Simon André
  • Mathéo Daninos

📌 Adoption

Utilisé par Symfony, EasyAdmin, PrestaShop, Sylius, SensioLabs, et même le ministère de l’Intérieur.

📊 Quelques chiffres

  • 2022 → 800 000 téléchargements
  • 2023 → 4 000 000 téléchargements
  • 2024 → 1 500 000 téléchargements

Les packages UX les plus populaires :

  • 95 000/semaine : Twig Component.
  • 50 000/semaine : UX Icons.
  • 40 000/semaine : Live Component.

🔮 UX en 2025

  • Typony Express : Création d'un jeu https://zty.pe/ entièrement avec Symfony UX comme une expérimentation et avec une documentation.
  • Refonte du site UX.
  • Un UX Bundle unique pour simplifier l’écosystème et l'ajout de nouveau "modules" UX.
  • UX v3 prévu pour l’été 2025.
  • Symfony 8 : retour à une synchronisation des versions.

Rôles & Permissions : Marque blanche et Feature Flipping (🎤 Florian Bogey)

Florian nous as montré comment Rôle et Permissions peuvent être utilisé de concert pour permettre la mise en place d'un marque blanche et d'un mécanisme de feature flag/flipping/toggle/whatever you may call something that activate or not a feature on your website.

🎭 Rôles vs Permissions

  • Rôle : catégorie utilisateur statique.
  • Permission : règle métier dynamique.

Symfony gère les permission via les Voters.
Il est possible de cumuler les attributs #[IsGranted()] pour différencier contrôles d'accès par les rôles des contrôles d'accès par permissions.

Exemple :

use Symfony\Component\Security\Http\Attribute\IsGranted;

final class FooController {

    #[Route('/foo/{id}', name: 'foo')]
    #[IsGranted('ROLE_ADMIN')]
    #[IsGranted('foo_voter', 'id')]
    public function __invoke(int $id): Response
    {
        // ...
    }
}
Enter fullscreen mode Exit fullscreen mode

🗳 Voter

Les voters peuvent être configurés selon 4 stratégies :

  1. Affirmative (par défaut) : Au moins un voter autorise l'action.
  2. Consensus : nécessite de voter qui autorise l'action que de voter qui ne l'interdise.
  3. Unanime : autorise l'action si aucun voter ne l'a interdite.
  4. Priority : renvoie la décision du premier voter qui ne s'est pas abstenu en s'appuyant sur la priorité définie dans les services.

🏢 Gestion de clients exigeants

Deux besoins principaux :

  1. Marque blanche → Identité visuelle, branding personnalisé.
  2. Feature Flipping → Activer/désactiver des fonctionnalités par client.

💮 Marque blanche

Définition : La marque blanche est un modèle commercial qui permet à une entreprise de vendre des produits ou des services conçus par une autre entreprise sous sa propre marque.

Afin de pouvoir avoir une application "Multi-tenant" (comprendre un seul code source pour plusieurs marques/clients différents), Florian nous as expliqué qu'il était nécessaire que chaque dispose de sont propre fichier d'environnement.

C'est rendu possible grâce

  1. l'ajout d'une variable d'environnement côté serveur web (SetEnv apache et set nginx)
  2. une légère modification du front controller (le fichier public/index.php) de Symfony afin d'ajouter la logique permettant le chargement du bon fichier DotEnv.
(new DotEnv())->loadEnv(sprintf('%s/.env.%s', dirname(__DIR__), $context['APP_SOME_NAME']));
Enter fullscreen mode Exit fullscreen mode
  1. une extension TWIG pour transmettre les variables d'environnement nécessaire a TWIG.

🔄 Feature Flipping

Définition : Permettre d'activer/désactiver une fonctionnalité ou des partie d'une application sous certaines conditions.

Après une présentation de plusieurs alternative et bundle permettant un feature flipping, Florian a présenté la solution maison qu'ils ont mis en place chez GL Events (retrouver les slides de Florian ici.


Async avec Messenger, AMQP et Mercure

🔄 Rappel sur Messenger

  • Permet d’exécuter des tâches asynchrones.
  • Transports disponibles : sync, in-memory, AMQP
  • Messages stockés dans une queue.
  • Gestion avec un superviseur (systemd, supervisord).

💡 Conseil : Pour les imports async, ne stockez pas les fichiers en BDD/queue, mais sur un disque partagé.

📡 Donner du feedback en temps réel (exemple : import)

❌ Mauvaises solutions

  • XHR Polling : inefficace.
  • WebSockets : complexe et lourd à maintenir.

✅ Solution moderne : Mercure

  • Surcouche à SSE (Server-Sent Events).
  • Full duplex et optimisé pour les updates en temps réel.
  • Installation via Composer.
  • Connexion JS via new EventSource() présent nativement dans les navigateurs.

🔐 Sécurité

  • Authentification JWT intégrée.
  • Publisher authentifié.
  • Subscriber anonyme ou non.

Symfony UX + Turbo + SSE

{{ turbo_stream_listen('csv:' ~ importId) }}
Enter fullscreen mode Exit fullscreen mode

Permet de recevoir des mises à jour sans écrire une ligne de JS !


Atteindre la qualité d’une SPA avec HTMX et Twig

🌍 HTMX : une alternative aux SPA

  • Créé par Carson Gross en 2020.

  • 50 KB, plus léger que jQuery.

🛠️ Fonctions principales

  • hx-get / hx-post : appels Ajax.

  • hx-trigger : changement d’événement (once, throttle, revealed…).

  • hx-target : où afficher la réponse Ajax.

  • hx-swap : méthode d’insertion (innerHTML, outerHTML, delete…).

  • hx-boost : transforme tous les liens en requêtes AJAX.

📌 Twig et animations CSS

  • Utilisation de renderBlock() pour ne rendre qu’un bloc spécifique d’un template.

  • Morphing des éléments via un ID conservé.


Du Lego de composants pour un bundle Gotenberg

📜 Génération de PDF en Symfony

  • Utilisation du bundle Gotenberg.

  • Permet de convertir HTML en PDF facilement.

  • Exemples et démonstrations disponibles sur Medium.


Top comments (0)