
Symfony 7.2 est disponible : que retenir de cette version ?
Publié le
La version bi-annuelle du célèbre framework PHP, Symfony, a été publiée en version stable le 29 novembre dernier. Plongeons ensemble, dans ses nouveautés.
C'est un rituel bien rôdé pour la communauté Symfony : chaque mois de mai et de novembre est synonyme de nouvelle version. Comme à l'accoutumée, cette version 7.2 apporte sa farandole de nouvelles fonctionnalités et d'améliorations. Faisons un tour des nouveautés les plus marquantes de cette mise à jour.
Un écosystème toujours en mouvement
Rome ne s'est pas faite en un jour, Symfony non plus. C'est un framework en perpétuelle évolution, non seulement par l'ajout de nouvelles fonctionnalités, mais aussi par sa quête constante d'amélioration dans son approche globale.
Des applications mono-fichier simplifiées
Au fil des versions, notamment avec l'introduction de Flex dans la version 4.0, Symfony a évolué d'un framework monolithique vers un micro-framework adapté à des projets de toutes tailles. Cette nouvelle version pousse encore plus loin cette mutation en facilitant la création d'applications mono-fichier.
L'amélioration du MicroKernelTrait
permet de créer des mini-applications avec encore moins de code, comme le montre l'exemple ci-dessous :
<?php
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\String\Slugger\SluggerInterface;
require __DIR__ . '/vendor/autoload.php';
class Kernel extends BaseKernel
{
use MicroKernelTrait;
#[Route('/slugify/{text}', name: 'slugify')]
public function __invoke(string $text, SluggerInterface $slugger): JsonResponse
{
return new JsonResponse([
'slug' => $slugger->slug($text),
]);
}
}
return static function (array $context) {
return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
};
Parmi les améliorations :
- La configuration devient désormais optionnelle. Il n’est plus nécessaire de créer un fichier
config/framework.yaml
ou de surcharger la méthodeconfigureContainer
- Le
FrameworkBundle
est désormais enregistré par défaut. Si aucun autre bundle n’est requis, il n’est plus nécessaire de surcharger la méthoderegisterBundles()
- L'injection de dépendances est maintenant disponible dans la méthode
__invoke()
Toujours plus de configuration dans le code
Depuis quelque temps, Symfony opère un changement en déplaçant de nombreux éléments de la configuration depuis les fichiers dédiés vers le code lui-même, au moyen d'attributs PHP. L’objectif est de rapprocher la configuration du code qu’elle concerne, pour une meilleure lisibilité. Personnellement, j’adore cette approche !
Avec Symfony 7.2, ce travail de longue haleine se poursuit, notamment avec l’introduction de l’attribut #[AsMessage]
: il permet de définir les transports associés à un message pour le composant Messenger.
#[AsMessage('async')]
class SlackNotification
{
// ...
}
Des jetons CSRF sans session ?
Le jeton CSRF est un mécanisme de sécurité utilisé pour protéger les applications web contre les requêtes malveillantes envoyées depuis des sources tierces. Dans la plupart des implémentations, le jeton est généré côté serveur, stocké en session puis inclus dans les formulaires. Lors de la soumission, le jeton envoyé avec la requête est comparé à celui stocké en session, permettant ainsi de confirmer la légitimité de la requête.
Jusqu'à présent, les jetons CSRF de Symfony reposaient sur cette implémentation. Toutefois, la version 7.2 nous propose une nouvelle approche stateless : le jeton authentique n'est plus stocké en session mais dans un cookie créé en Javascript et transmis avec la requête. En complément, une vérification des entêtes HTTP Origin
/ Referer
permet de s'assurer de l'origine de la requête.
En ne se reposant plus sur les sessions, cette approche permet de s'affranchir d'un éventuel problème de récupération ou d'expiration de la session. Néanmoins, il est à noter que cette approche nécessite l'utilisation de Javascript : les utilisateurs l'ayant désactivé ne pourront utiliser correctement ce mécanisme. D'un autre côté, est-il encore possible de naviguer sur internet sans Javascript en 2024 ?
Pour les projets mis à jour depuis une version antérieure, ce nouveau comportement pourra être activé dans la configuration. Pour les nouvelles installations, la configuration par défaut fournie par Symfony Flex, activera ce mode de fonctionnement.
# config/packages/framework.yaml
framework:
form: { csrf_protection: { token_id: 'submit' } }
csrf_protection:
stateless_token_ids: ['submit', 'authenticate', 'logout']
Adieu APP_SECRET
, enfin pas tout à fait
L'une des variables d'environnement les plus emblématiques de Symfony, APP_SECRET
, était jusqu'à présent indispensable au bon fonctionnement du noyau. Cependant, comme le framework ne l'utilise que pour un nombre limité de fonctionnalités, ce paramètre devient désormais optionnel, n'étant requis que si l'une de ces fonctionnalités est activée. Pour ceux qui souhaitent en savoir plus, les détails des modifications ayant permis cette évolution sont disponibles dans cet article.
Toujours faciliter la vie des développeurs
Après avoir exploré les principaux changements apportés aux mécanismes existants, attardons-nous maintenant sur les nombreuses nouveautés que cette version nous offre pour améliorer encore davantage notre expérience avec ce formidable outil (ai-je déjà mentionné à quel point j’aime Symfony ?).
Le validateur s’enrichit (encore)
Le validateur est probablement l'un des premiers composants qui m'a convaincu de laisser les développements PHP from scratch de côté pour passer à Symfony. Et si tu as déjà implémenté des validations de (longs) formulaires manuellement, je suis convaincu que tu comprends mon point de vue. Comme à chaque version ou presque Symfony apporte une série d'amélioration pour ce composant.
Dans un premier temps, 3 nouvelles contraintes prédéfinies s'ajoute à la longue listes des contraintes existantes :
Week
- Valide qu'une chaîne de caractères correspond à un numéro de semaineWordCount
- Valide qu'une chaîne de caractères contient un certain nombre de motsYaml
- Valide qu'une chaîne de caractères correspond à une syntaxe YAML correcte
Ensuite, plusieurs contraintes ont été enrichies de nouvelles options pour améliorer leur flexibilité :
- L'option
mode
pourBic
- Permet de rendre la validation insensible à la casse - L'option
errorPath
pourUnique
- Permet de personnaliser le point d'ancrage de l'erreur - L'option
format
pourUlid
- Permet de choisir le format de validation de l'identifiant
Pour finir, parlons de la contrainte PasswordStrength
introduite dans la version 6.3. Cette dernière permet de valider la complexité d'un mot de passe, en se basant non pas sur la présence ou non de certains caractères mais en calculant l'entropie de la chaîne de caractères.
À une période où les bonnes pratiques de sécurité nous encourageaient déjà à ne plus contraindre l'utilisateur à ajouter tel ou tel type de caractères dans son mot de passe : cet ajout était le bienvenu. Cependant, un détail important manquait. Jusqu'à présent, il était impossible d'accéder au niveau d'entropie du mot de passe validé. Par conséquent, il était difficile de fournir un retour détaillé à l'utilisateur autre qu'un simple échec de validation.
La méthode estimateStrength()
a vu sa visibilité passer de private
à public
, permettant ainsi d'obtenir l'entropie de la valeur soumise et offrant l'opportunité d'améliorer l'expérience pour l'utilisateur.
Une expérience améliorée pour la console
Le composant console est l'un des plus téléchargé de l'écosystème Symfony, de nombreux projets PHP open-source reposent sur ce dernier. Cette version nous propose 2 nouvelles fonctionnalités pour améliorer l'expérience dans nos terminaux.
Une option --silent
est ajoutée par défaut aux commandes, en complément de l'option existante --quiet
. Bien que similaires, ces deux options diffèrent légèrement : toutes deux suppriment la sortie standard lors de l'exécution d'une commande, mais l'option --quiet
renverra tout de même les erreurs, tandis que l'option --silent
rendra la commande aussi silencieuse qu'un rocher antipathique.
La classe ProgressIndicator
possède désormais une option pour définir un indicateur lorsque que la progression est marquée comme terminée. Il est possible de définir un indicateur par défaut :
$progressIndicator = new ProgressIndicator($output, finishedIndicatorValue: '🚀');
L'indicateur peut également être passé dynamiquement lors de l'appel de la méthode finish
:
$progressIndicator->finish('Published', '🚀');
L'ExpressionLanguage
continue de se développer
L'ExpressionLanguage
fourni une syntaxe simplifiée pour évaluer des conditions. Ce dernier est souvent utilisé pour exprimer des règles de validation de donnée ou de contrôle d'accès plus complexes.
Ce langage supporte maintenant les commentaires mono et multi-lignes avec la syntaxe /* Ceci est un commentaire */
. Fini les expressions ésotériques sans explication supplémentaire, à condition que tes collègues aient pris la peine d'ajouter des commentaires explicatifs, bien sûr.
Le comportement de l'opérateur de coalescence des nuls (??
) a été amélioré pour correspondre exactement à celui de PHP. Auparavant, une exception était lancée lorsqu'une variable n'était pas définie.
Créer des EntityType
dynamique plus simplement
Dans la gestion des formulaires Symfony, le champ EntityType
nous simplifie grandement la création de sélecteurs ou de cases à cocher pour relier des entités entre elles. Cependant, son comportement par défaut consiste à charger toutes les options possibles, ce qui peut entraîner des problèmes de performance lorsque le nombre d'options est élevé.
Dans ce cas, il est courant de mettre en place un mécanisme pour ne pas charger tous les choix dès le départ et utiliser un système d'autocomplétion en frontend, afin de ne charger que les options pertinentes. Toutefois, implémenter une telle solution nécessitait jusque-là de modifier le comportement interne du champ EntityType
.
Avec Symfony 7.2, l'option choice_lazy
est introduite. Lorsqu'elle est activée (true
), elle permet de charger dynamiquement les choix en fonction des données soumises. Cette amélioration te libère de la gestion de la logique côté backend, il ne te reste qu'à gérer la partie frontend ! Si tu utilises Symfony UX, le composant ux-autocomplete
peut s'en charger pour toi.
Le composant String
poursuit son évolution
Le composant String
de Symfony, introduit dans le version 5.0, facilite la manipulation des chaînes de caractères en offrant une API orientée objet. Dans la version 7.2, plusieurs améliorations ont été apportées :
- Ajout de la méthode
kebab()
: Permet de convertir une chaîne en kebab-case - Nouveaux modes de troncature : Inclut des options pour tronquer au mot précédent ou suivant, en plus du mode strict par caractère.
- Inflecteur espagnol : Ajout d'un inflecteur pour gérer le singulier et le pluriel en espagnol, en complément des inflecteurs anglais et français déjà présent.
Et bien plus encore
Dans cet article, j'ai voulu mettre en lumière les apports qui, selon moi, font la richesse de cette version. Cependant, Symfony 7.2 a bien plus à offrir. Si tu veux en savoir plus, tu peux retrouver la liste des toutes les modifications sur cet article publié sur le blog officiel de Symfony.
Et pour la suite ?
La 7.3 en ligne de mire et une nouvelle majeure fin 2025
Conformément à la politique de publication du framework, la prochaine version sera publiée courant mai 2025 sous le numéro 7.3. Puis, en novembre 2025, les versions 7.4 (avec un support à long terme) et 8.0 seront publiées simultanément.
Fin des correctifs pour la 5.4
Ce mois de novembre signe également la fin du support correctif de Symfony 5.4. Toutefois, les correctifs de sécurité continueront d’être fournis jusqu’en février 2029. Si tu maintiens des applications sur cette version, il est peut-être temps de songer à planifier une migration vers une version plus récente pour bénéficier des dernières améliorations et correctifs.
Sur ceux, je vous dis à bientôt pour de nouveaux articles techniques 👋