Utilisation de Composer dans le développement Symfony : conseils pratiques
Par Louis-Arnaud Catoire
Les fondamentaux de Composer dans un projet Symfony
Composer est le gestionnaire de dépendances de l'écosystème PHP. Son rôle est de résoudre un arbre de dépendances : à partir d'un fichier composer.json déclarant les packages nécessaires au projet, il calcule les versions compatibles entre elles, les télécharge et génère un autoloader PSR-4. Symfony s'appuie entièrement sur Composer, que ce soit pour installer le framework lui-même, ajouter des bundles ou configurer les recettes Flex.
Un projet Symfony démarre généralement avec une seule commande :
composer create-project symfony/skeleton mon-projet
Cette commande installe le squelette minimal du framework. Symfony Flex, le plugin Composer intégré, se charge ensuite d'appliquer les recettes des packages installés : création des fichiers de configuration, ajout des variables d'environnement et mise en place de la structure de répertoires.
require vs require-dev : séparer les contextes
Le fichier composer.json distingue deux sections fondamentales. La section require contient les dépendances nécessaires à l'exécution en production : le framework, les bundles métier, les bibliothèques tierces. La section require-dev regroupe les outils de développement : PHPUnit, PHPStan, php-cs-fixer, le profiler Symfony.
Cette séparation n'est pas cosmétique. En production, la commande composer install --no-dev exclut toutes les dépendances de développement. Le résultat est un répertoire vendor plus léger, une surface d'attaque réduite et un autoloader optimisé. Placer un outil de test dans require au lieu de require-dev revient à embarquer du code inutile sur chaque serveur de production.
Le fichier composer.lock : la reproductibilité
Le fichier composer.lock enregistre les versions exactes de chaque package résolu. Ce fichier doit impérativement être versionné dans le dépôt Git. Sans lui, chaque composer install pourrait résoudre des versions différentes selon le moment de l'exécution, introduisant des écarts subtils entre les environnements.
La distinction est claire : composer install lit le fichier composer.lock et installe exactement les versions verrouillées. composer update recalcule l'arbre de dépendances à partir des contraintes du composer.json et met à jour le composer.lock. En production, seul composer install doit être utilisé.
Stratégie de contraintes de versions
Le choix des contraintes de version dans composer.json est une décision d'ingénierie qui impacte la maintenabilité du projet sur le long terme.
L'opérateur caret (^5.4) autorise les mises à jour mineures et de patch tout en interdisant les changements majeurs. C'est le choix par défaut pour la majorité des dépendances, car il respecte le semver : les mises à jour mineures ajoutent des fonctionnalités sans casser la rétrocompatibilité. L'opérateur tilde (~5.4.0) est plus restrictif et n'autorise que les mises à jour de patch. Il convient aux bibliothèques dont le respect du semver est incertain.
Pour les projets Symfony, il est recommandé de s'aligner sur les branches de support à long terme (LTS). Contraindre symfony/framework-bundle à ^6.4 garantit de recevoir les correctifs de sécurité pendant trois ans sans risquer une montée de version majeure accidentelle.
Dépôts privés et packages internes
Un projet d'entreprise dépend souvent de packages qui ne sont pas publiés sur Packagist. Composer permet de déclarer des dépôts supplémentaires directement dans composer.json :
{
"repositories": [
{
"type": "vcs",
"url": "git@gitlab.entreprise.com:libs/shared-kernel.git"
}
]
}
Pour les organisations qui gèrent plusieurs packages privés, un registre Composer dédié comme Private Packagist ou Satis simplifie considérablement la configuration. Satis génère un index statique déployable sur n'importe quel serveur web, tandis que Private Packagist offre une solution hébergée avec gestion des droits d'accès.
Scripts Composer et automatisation
Les scripts Composer permettent de déclencher des commandes à des moments précis du cycle de vie : après l'installation, avant ou après une mise à jour, lors de l'événement auto-scripts propre à Symfony Flex.
{
"scripts": {
"test": "php bin/phpunit",
"cs": "php-cs-fixer fix --dry-run --diff",
"stan": "phpstan analyse",
"ci": ["@cs", "@stan", "@test"]
}
}
Un script ci qui chaîne linting, analyse statique et tests unitaires offre un point d'entrée unique pour la validation locale comme pour les pipelines CI/CD. Chaque développeur exécute composer ci avant de pousser, ce qui réduit le bruit sur les merge requests.
Audit de sécurité et platform-check
La commande composer audit vérifie les dépendances installées contre la base de données des vulnérabilités connues (PHP Security Advisories). Intégrée dans le pipeline CI, elle bloque automatiquement un déploiement si une CVE affecte l'une des bibliothèques du projet.
La section config.platform du composer.json permet de simuler un environnement PHP cible :
{
"config": {
"platform": {
"php": "8.3.0",
"ext-intl": "1.0"
}
}
}
Ce mécanisme garantit que Composer résout les dépendances en fonction de la version PHP de production, même si le poste de développement utilise une version différente. Combiné avec le plugin composer/platform-check (activé par défaut depuis Composer 2), l'application échoue au démarrage si le runtime ne correspond pas aux exigences déclarées, plutôt que de produire des erreurs silencieuses.
Gouvernance des dépendances à l'échelle
Sur un projet mature, le nombre de dépendances croît naturellement. Sans gouvernance, le répertoire vendor devient un angle mort : des packages obsolètes cohabitent avec des bibliothèques redondantes, et personne ne sait qui a introduit quelle dépendance ni pourquoi.
La première étape consiste à cartographier régulièrement l'arbre de dépendances avec composer depends et composer why-not. Ces commandes répondent aux questions essentielles : pourquoi tel package est-il installé, et qu'est-ce qui empêche la mise à jour vers telle version. Coupler cette analyse avec composer outdated fournit un tableau de bord de la dette technique liée aux dépendances.
Une politique de mise à jour structurée passe par des cycles réguliers : mises à jour de patch en continu, mises à jour mineures mensuelles, mises à jour majeures planifiées avec une analyse d'impact. Automatiser la détection des mises à jour disponibles avec des outils comme Dependabot ou Renovate réduit la charge mentale et maintient le projet à jour sans effort conscient.
Stratégies monorepo et plugins Composer
Dans les organisations qui maintiennent plusieurs applications Symfony partageant du code commun, la stratégie monorepo mérite d'être considérée. Des outils comme Symplify Monorepo Builder ou le plugin wikimedia/composer-merge-plugin permettent de gérer plusieurs composer.json au sein d'un même dépôt, avec un mécanisme de split automatique pour publier chaque package indépendamment.
Les plugins Composer étendent le comportement du gestionnaire de dépendances. Symfony Flex en est l'exemple le plus connu, mais d'autres méritent l'attention : composer-unused détecte les dépendances déclarées mais jamais importées dans le code, composer-require-checker identifie les dépendances utilisées mais non déclarées. Ces outils, intégrés dans le pipeline CI, transforment la gestion des dépendances d'une corvée ponctuelle en un processus continu et fiable.
Sécurité de la chaîne d'approvisionnement
La supply chain security est devenue un enjeu majeur. Chaque package installé via Composer est du code tiers exécuté avec les mêmes privilèges que l'application. Plusieurs pratiques réduisent ce risque.
Vérifier l'intégrité des packages avec les checksums du composer.lock. Restreindre les plugins Composer autorisés via la directive config.allow-plugins, introduite dans Composer 2.2, qui force une validation explicite de chaque plugin. Auditer les scripts post-install-cmd et post-update-cmd des dépendances, car ils s'exécutent automatiquement et peuvent contenir du code arbitraire.
Pour les architectures les plus sensibles, un miroir Composer interne (via Satis ou Private Packagist) permet de contrôler et valider chaque package avant qu'il ne soit accessible aux développeurs. Cette approche ajoute une couche de validation entre Packagist public et l'environnement de développement.
Conclusion
Composer dépasse largement le rôle de simple installateur de packages. Utilisé avec rigueur, il devient un outil de gouvernance technique : contraintes de versions alignées sur la stratégie de support, audit de sécurité automatisé, reproductibilité garantie par le lock file, et maîtrise de la chaîne d'approvisionnement logicielle. La maîtrise de Composer est un marqueur de maturité dans un projet Symfony.
Pour aller plus loin
- Les bundles les plus utilisés dans Symfony — découvrir les bundles incontournables installables via Composer
- Guide de migration Symfony — gérer les mises à jour de dépendances lors d'une migration
- Les PSRs et à quoi servent-ils — comprendre les standards PHP que Composer aide à respecter
- Composer Documentation — documentation officielle de Composer
- Packagist — le répertoire principal des packages PHP
- Symfony — Using Composer — guide officiel pour créer un projet Symfony avec Composer
- GitHub — Composer — dépôt officiel de Composer