Quelques astuces pour améliorer votre code Symfony

Une liste non exhaustive et subjective d'astuces pour améliorer votre façon de développer

17 oct. 2020 à 21:29 – 16min


Table des matières

Bonjour et bienvenue dans ce nouvel article ! Aujourd'hui, je vais partager avec vous quelques astuces que j'utilise au quotidien afin d'améliorer la lisibilité de mon code Symfony. Cet article est une sorte de "fourre tout", dans lequel je vais lister de manière non exhaustive et totalement subjective un certain nombre de choses que j'ai pu découvrir. 

Attention, ces indications sont pour certaines des recommandations totalement personnelles, pour d'autres de simples astuces parfois méconnues ou peu utilisées par les développeurs et que je souhaite simplement partager avec vous. Si vous le souhaitez, vous pouvez également consulter les standards de code officiels de Symfony.

Cet article est mis à jour régulièrement, au fur et à mesure que je découvre de nouvelles choses à vous proposer.

Les standards de code

Symfony repose sur un ensemble de standards de style de code, principalement basé sur PSR-1, PSR-2 et PSR-4. Il s'agit de standards utilisés afin d'unifier la façon dont les développeurs écrivent leur code PHP. Ainsi, il est plus facile de passer d'un projet à l'autre et de travailler sur le code d'un autre développeur car le style de code est clair et lisible. 

Parmis ces règles PSR, on retrouve notamment :

Symfony ajoute également quelques règles propres à son framework, que vous pouvez retrouver ici. Parmi elles : 

Je vous encourage grandement à lire par vous-même l'ensemble des règles PSR et les standards de code officiels Symfony, et surtout de les adopter ! Cela rendra votre code beaucoup plus clair et lisible, pour vous-même et pour les autres !

Automatiser l'application des règles

Avec PHPStorm

Si vous utilisez PHPStorm comme IDE, vous devez savoir qu'il est possible de formater automatiquement le code d'un fichier, via l'onglet code > Reformat Code. Par défaut, PHPStorm va appliquer un ensemble de règles prédéfini en détectant automatiquement le langage utilisé. 

Il est surtout possible de configurer ces règles via les préférences de l'application. Rendez-vous dans les préférences PHPStorm, onglet Editor > Code Style > PHP. En haut à droit de la fenêtre, cliquez sur "Select from...", puis sélectionnez Symfony2 (nécessite l'installation du plugin Symfony) ou à défaut PSR1/PSR2. Une fois les règles de code définies, essayez à nouveau de formater le code d'un fichier. Les règles de code de Symfony sont maintenant appliquées 

Avec PHP-CS-Fixer

Je vous conseille également d'utiliser un outil développé par Fabien Potencier lui-même (le créateur de Symfony) : PHP-CS-Fixer. Il s'agit d'un petit utilitaire extrêmement utile qui va s'occuper pour vous de formater votre code. 

Pour commencer, installez-le globalement via Composer : 

composer global require friendsofphp/php-cs-fixer

En installant globalement via Composer, un nouveau binaire sera ajouté à votre dossier ~/.composer/bin. Si ce n'est pas déjà fait, ajoutez ce chemin à votre PATH :

export PATH=~/.composer/vendor/bin:$PATH

Enfin, exécutez la commande suivante pour formater votre code : 

php-cs-fixer fix src/ [email protected]

Ici, nous indiquons à l'outil qu'il doit s'occuper du dossier src/ de notre projet, qui contient tous nos fichiers PHP. Nous indiquons également qu'il doit utiliser l'ensemble de règles @Symfony. Sachez que cet outil peut être utilisé sur n'importe quel type de projet PHP, autre que Symfony. Il existe en effet un certain nombre de règles, notamment pour PSR-1 et PSR-2, qui sont listées dans la documentation officielle.   

Les commandes

Utiliser le CLI Symfony

Peut-être utilisez-vous uniquement Composer et l'invité de commande fourni dans le dossier bin/console de votre application pour votre développement, mais savez-vous que Symfony propose un CLI bien plus complet et facile d'utilisation ? Vous pouvez le télécharger sur le site officiel de Symfony. Une fois installé, je vous invite à taper la commande symfony dans votre terminal afin de voir toutes les commandes disponibles. 

L'un des avantages à utiliser ce CLI est qu'il va sélectionner automatiquement la bonne version de PHP et Composer installée sur votre système à utiliser. Maintenant, vous pourrez utiliser symfony composer ou encore symfony php pour utiliser ces utilitaires pendant votre développement local.

Le CLI propose également un serveur local intégré, ainsi que la commande security:check qui va détecter pour vous les vulnérabilités de vos packages. 

Enfin, grâce au CLI, vous pourrez profiter de toutes les fonctionnalités offertes par SymfonyCloud.

Configurer correctement la création d'un projet

Pour créer un nouveau projet Symfony, le plus simple est d'utiliser la commande fournie par le CLI :

symfony new [project_name]

Lorsque vous créez un nouveau projet via la commande symfony new, vous pouvez donner un certain nombre d'arguments afin de correctement configurer votre projet, notamment : 

Options pour lancer son serveur

Pour lancer un serveur local avec Symfony, vous pouvez simplement utiliser la commande symfony serve, mais savez-vous que cette commande propose un certain nombre d'arguments intéressants ? 

Les controllers

Un controller, une logique

Par exemple, si j'ai une entité User qui représente un utilisateur, je vais créer un nouveau controller UserController, qui définira toutes les routes préfixées par /user et toutes les actions liées à cette entité. Ainsi, mon code est bien hiérarchisé et je m'y retrouve facilement. 

Utiliser les constructeurs

Imaginons que je travaille sur un controller chargé de la gestion des articles d'un blog, chaque fonction de cette classe aura besoin d'utiliser le repository ArticleRepository (pour récupérer, mettre à jour ou supprimer des articles par exemple). Au lieu d'avoir à appeler Doctrine pour récupérer mon repository à chaque fois, j'instancie mon repository dans mon constructeur, que je peux donc appeler n'importe où dans ma classe. 

Bien sûr, je peux faire ceci pour n'importe quelle autre interface qui pourrait être utilisée partout dans mon code. 

Annotation des routes

Comme je l'ai dit, je fais généralement en sorte que chaque controller soit chargé d'une partie bien délimitée de mon application, par exemple la gestion de mes articles. Chaque route en rapport avec un article doit commencer par /, alors que les routes liées à la gestion des utilisateurs seront préfixées par /user par exemple. Ainsi, j'indique dans les annotations de ma classe le préfix de nom et d'URL, ce qui m'évite d'avoir à les redéclarer dans chaque fonction de ma classe. Grâce à cela, je suis sûr que chaque URL de ma classe aura le même préfix de route et de nom. Si je reprends l'exemple d'un controller en charge des utilisateurs, voilà ce qu'un controller "propre" pourrait donner : 

Vous remarquez également qu'une erreur de frappe peut très vite se glisser dans le second exemple, et donc rendre notre système de routes inconsistant 

Utiliser le ParamConverter

Imaginons que vous souhaitez créer une fonction findArticle chargée de récupérer une entité Article selon un paramètre id donné dans l'URL. Vous pourriez être tenté d'écrire quelque chose comme ceci : 

Mais savez-vous que Symfony intègre un convertisseur de paramètres, appelé ParamConverter, capable de transformer automatiquement les paramètres d'URL afin de récupérer la bonne entité ? Voici un exemple pour mieux comprendre : 

Symfony est assez intelligent pour comprendre qu'ici, vous souhaitez récupérer un objet de classe Article (indiqué en paramètre) en fonction du champ id donné dans l'URL. En plus, si l'objet n'est pas trouvé, Symfony lèvera une exception avec un code d'erreur 404 Not Found. Essayez par vous-même ! Vous verrez qu'avec cette méthode, votre code sera grandement simplifié et beaucoup plus lisible !

Les templates

Créer des filtres Twig

Vous utilisez sûrement déjà les nombreux filtres offerts par Twig, par exemple le filtre date permettant de convertir un objet DateTime en chaîne de caractères formatée, mais savez-vous que vous pouvez créer vos propres filtres ? 

Pour illustrer cela, nous allons créer un nouveau filtre truncate, qui nous permettra de tronquer une chaîne de caractères et d'ajouter "..." si la chaîne est trop longue. 

Il vous suffit de créer un nouveau dossier src/Twig/ et d'y ajouter une nouvelle classe AppExtension.php contenant le code suivant : 

Chaque fonction de filtre prendra en premier argument l'objet passé dans votre template Twig, les autres arguments sont les paramètres utilisés par votre filtre. Par exemple, pour utiliser ma fonctione truncate, je devrai l'appeler comme ceci dans mon template : 

Lorsque vous rajouterez de nouveaux filtres, n'oubliez pas de les définir dans la fonction getFilters, qui associe une fonction définie dans la classe à un nom de filtre donné, utilisé dans vos templates Twig.

La boucle for...else

Imaginez que vous vouliez lister des commentaires sur une page. Vous voudriez peut-être afficher un message si aucun commentaire n'a été posté pour l'instant, et donc passer par une condition qui vérifie le nombre d'éléments de votre liste, puis une boucle pour itérer sur vos messages. Mais savez-vous que Twig propose du sucre syntaxique pour rendre ce cas de figure plus lisible dans votre code ? 

Diviser ses templates

Sur des projets complexes, vos templates peuvent vite devenir très longs et illisibles. Pour pallier ce problème, vous pouvez utiliser la fonction Twig include, qui va vous permettre d'insérer un template Twig dans un autre.

Dans cet exemple, j'ai externalisé trois templates dans un dossier tamplates/core/blocks, et que j'appelle grâce à la fonction include. Notez que je peux parfaitement passer des paramètres lors de mon appel à la fonction include.

Il existe également la fonction render de Twig, qui permet cette fois d'effectuer le rendu d'un template en passant par un controller, et donc d'ajouter de la logique dans ce template (injection de variables, etc). Néanmoins, je ne vous la conseille pas, car elle peut grandement dégrader les performances de votre application.

Override de la fonction __toString()

Avec PHP, il est possible d'overrider les méthodes magiques. Les méthodes magiques sont les méthodes qui, lorsqu'elles sont présentes dans vos classes, seront appelées lors d'évènements spécificiques. Vous connaissez déjà sûrement la méthode __construct(), qui est appelée lors de l'instantiation de votre classe. 

La méthode __toString() est également une fonction magique, qui détermine comment l'objet doit se comporter lorsqu'il est traité comme une chaîne de caractères. Essayez par vous-même en ajoutant la méthode __toString() dans l'une de vos entités : 

Essayez maintenant d'afficher directement votre entité dans un template Twig via {{ article }} (sans préciser de champ). C'est maintenant la méthode __toString() qui est automatiquement appelée, et affiche donc l'id et de le titre de l'article !