Composer
Installer une bibliothèque en une commande, savoir exactement quelles versions tournent, et ne plus jamais écrire de require.
- Gestionnaire de dépendances
- composer.lock
- Autoloading PSR-4
- Mise en production
À la fin de ce cours, vous saurez
- Installer une dépendance, et expliquer pourquoi composer.json et composer.lock ne disent pas la même chose.
- Lire une contrainte de version et prédire ce qu’un composer update fera.
- Charger ses propres classes en PSR-4, sans un seul require.
- Distinguer require de require-dev, et justifier --no-dev en production.
- Ne plus confondre install, update et require.
Avant de commencer
- PHP débutant — variables, fonctions, include et require
- POO en PHP — classes et namespaces — l’autoloading PSR-4 en dépend
Pourquoi Composer
Vous savez déjà inclure un fichier PHP dans un autre. Tant que le projet tient en cinq fichiers, cela suffit. Au-delà, trois problèmes apparaissent que require ne sait pas résoudre.
La vie sans Composer
Vous voulez écrire des journaux applicatifs. Vous téléchargez une bibliothèque, vous la posez dans un dossier, et vous écrivez :
php
<?php
require_once 'libs/Monolog/Logger.php';
require_once 'libs/Monolog/Handler/StreamHandler.php';
require_once 'libs/Monolog/Handler/AbstractHandler.php';
require_once 'libs/Psr/Log/LoggerInterface.php';
// ... et les vingt-cinq autres fichiers dont ceux-ci dépendent
Trois problèmes, et un seul outil
Chaque bibliothèque en appelle d’autres. Monolog a besoin de psr/log ; PHPUnit a besoin de vingt-huit paquets. Vous ne les connaissez pas, et vous devez tous les télécharger à la main.
Vous avez pris Monolog 3.10 en janvier. Six mois plus tard, votre collègue prend la 3.12. Vos deux machines n’exécutent pas le même code, et le bogue n’apparaît que chez l’un des deux.
Une faille est publiée dans une bibliothèque que vous utilisez sans le savoir — parce qu’elle est la dépendance d’une dépendance. Rien ne vous prévient.
Composer règle les trois d’un coup. Il lit une liste de ce que VOUS voulez, calcule tout ce que cela entraîne, télécharge l’ensemble, écrit un chargeur automatique, et grave les versions exactes obtenues.
Ce que Composer n’est pas
- Ce n’est pas un installeur de PHP : il suppose PHP déjà là.
- Ce n’est pas un dépôt de code : les paquets vivent sur GitHub, Composer les y va chercher. Packagist n’est qu’un annuaire.
- Ce n’est pas un outil de déploiement : il prépare
vendor/, il ne publie rien.
Packagist, l’annuaire public, recensait 463 643 paquets le 16 août 2026 (source : packagist.org/statistics.json).
Installer Composer
Composer est un programme PHP. Il s’installe une fois pour toute la machine, et se met à jour tout seul.
Vérifier PHP d’abord
bash
php --version
Sortie
PHP 8.4.22 (cli) (built: Jun 3 2026 01:12:32) (NTS)
Composer 2.10 exige PHP 7.2.5 au minimum (contrainte ^7.2.5 || ^8.0, lue le 16 août 2026 sur repo.packagist.org). Si php --version échoue, installez PHP avant d’aller plus loin.
macOS et Linux
bash
# Homebrew, sur macOS
brew install composer
# Ou l'installeur officiel, partout
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
Windows
Téléchargez Composer-Setup.exe depuis getcomposer.org/download. L’installeur trouve votre PHP et ajoute composer au PATH.
Vérifier
bash
composer --version
Sortie
Composer version 2.8.9 2025-05-13 14:01:37
Au 16 août 2026, la version stable publiée est la 2.10.2, et la 2.2.29 est la version à support long (source : getcomposer.org/versions). composer self-update met à jour Composer lui-même.
N’exécutez JAMAIS sudo composer. Composer télécharge du code écrit par des inconnus et exécute leurs scripts d’installation. Lui donner les droits d’administrateur, c’est les donner à eux. Si Composer vous réclame sudo, c’est que les droits de votre dossier sont mauvais — ce sont eux qu’il faut corriger.
Un premier projet
composer init pose quelques questions et écrit un composer.json. Vous pouvez aussi écrire ce fichier à la main : ce n’est que du JSON.
bash
mkdir mon-projet && cd mon-projet
composer init
Répondez aux questions — nom du paquet, description, type, licence. Le résultat :
json
{
"name": "stjo/demo",
"description": "Démonstration",
"type": "project",
"require": {}
}
Les champs, un par un
name — l’identité du paquet, sous la forme éditeur/paquet, en minuscules. Obligatoire seulement si vous publiez ; pratique dans tous les cas.
description — une phrase. Elle s’affiche dans composer show.
type — project pour une application, library pour du code destiné à être réutilisé. La valeur par défaut est library.
require — vos dépendances de production. Vide pour l’instant.
require-dev — vos dépendances de DÉVELOPPEMENT : tests, analyse statique, outils de mise en forme. Elles ne partent pas en production.
autoload — la correspondance entre vos namespaces et vos dossiers. C’est la section 6.
Ce que Git doit ignorer
bash
# .gitignore
/vendor/
vendor/ ne se commite pas : il se reconstruit à l’identique à partir de composer.lock. Ce sont composer.json ET composer.lock qui vont dans Git — la section 4 explique pourquoi les deux.
Installer des dépendances
Ajouter un paquet
bash
composer require monolog/monolog
Sortie
Using version ^3.10 for monolog/monolog
./composer.json has been updated
Running composer update monolog/monolog
Loading composer repositories with package information
Updating dependencies
Lock file operations: 2 installs, 0 updates, 0 removals
- Locking monolog/monolog (3.10.0)
- Locking psr/log (3.0.2)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 2 installs, 0 updates, 0 removals
- Installing psr/log (3.0.2): Extracting archive
- Installing monolog/monolog (3.10.0): Extracting archive
Generating autoload files
No security vulnerability advisories found.
Lisez cette sortie de haut en bas : Composer choisit une contrainte de version (^3.10), l’inscrit dans composer.json, calcule l’ensemble des paquets nécessaires, grave le résultat dans composer.lock, installe, écrit le chargeur automatique, et vérifie les alertes de sécurité. Vous n’aviez demandé qu’un paquet : psr/log est arrivé parce que Monolog en dépend.
Les outils de développement à part
bash
composer require --dev phpunit/phpunit
Le drapeau --dev range le paquet dans require-dev. La différence est considérable : dans le bac à sable de cette page, le projet compte 29 paquets avec les outils de développement, et 2 sans.
Retirer un paquet
bash
composer remove monolog/monolog
Composer retire aussi les dépendances devenues inutiles — mais jamais celles dont un autre paquet a encore besoin.
composer.lock : le fichier qui fait la différence
C’est le point que l’on comprend le plus tard, et celui qui coûte le plus cher à ignorer. Les deux fichiers ne disent pas la même chose.
composer.json dit ce que vous VOULEZ : « une version 3 de Monolog, au moins la 3.10 ». C’est une intention, et elle a plusieurs solutions.
composer.lock dit ce que vous AVEZ OBTENU : « Monolog 3.10.0, dont l’empreinte est b321dd67 ». C’est un fait, et il n’en a qu’une.
D’où la règle : composer.lock se commite, toujours, y compris pour une application. C’est lui qui garantit que votre machine, celle de votre collègue et le serveur exécutent exactement le même code.
Les trois commandes qu’on confond
bash
composer install # lit composer.lock, installe EXACTEMENT ces versions
composer update # ignore le lock, recalcule, RÉÉCRIT le lock
composer require # ajoute un paquet, puis fait un update de ce paquet seul
Sur un projet que vous récupérez, la commande est install, jamais update. update réécrit le lock et vous fait travailler sur d’autres versions que vos collègues — c’est-à-dire exactement ce que Composer sert à éviter.
Sortie
Installing dependencies from lock file (including require-dev)
Verifying lock file contents can be installed on current platform.
Package operations: 29 installs, 0 updates, 0 removals
- Installing psr/log (3.0.2): Extracting archive
- Installing monolog/monolog (3.10.0): Extracting archive
...
Generating autoload files
Comprendre les versions
SemVer en trois nombres
Un numéro de version comme 3.10.2 se lit MAJEUR.MINEUR.CORRECTIF. Le contrat est simple : le correctif corrige sans rien casser, le mineur ajoute sans rien casser, le majeur a le droit de tout casser.
Les contraintes
^3.10 — « au moins 3.10, et tant que le MAJEUR ne change pas ». Accepte 3.10.1, 3.12.0 ; refuse 4.0.0. C’est ce que composer require écrit par défaut, et c’est presque toujours le bon choix.
~3.10 — « au moins 3.10, et tant que le MINEUR ne change pas ». Accepte 3.10.5 ; refuse 3.11.0. Plus strict.
3.10.2 — cette version exacte, et aucune autre. À réserver aux cas où une version précise pose problème.
>=8.1 — une borne basse, sans borne haute. À éviter : rien n’empêche une future version 12 incompatible d’être installée.
Voir ce qui a vieilli
bash
composer outdated --direct
Sortie
Legend:
! patch or minor release available - update recommended
~ major release available - update possible
phpunit/phpunit 11.5.56 ~ 13.3.1 The PHP Unit Testing framework.
--direct ne montre que VOS dépendances, pas celles de vos dépendances. Ici, PHPUnit 13 existe, mais la contrainte ^11.0 interdit d’y aller : c’est un changement de majeur, il se décide, il ne se subit pas.
Inspecter un paquet
bash
composer show monolog/monolog
Sortie
name : monolog/monolog
descrip. : Sends your logs to files, sockets, inboxes, databases and various web services
keywords : log, logging, psr-3
versions : * 3.10.0
released : 2026-01-02, 7 months ago
type : library
license : MIT License (MIT)
homepage : https://github.com/Seldaek/monolog
La date de publication est une information de sécurité. Une bibliothèque dont la dernière version date de quatre ans n’est pas « stable » : elle est abandonnée.
L’autoloading PSR-4
Jusqu’ici Composer a chargé le code des AUTRES. Il peut charger le vôtre, et c’est le moment où l’on cesse d’écrire des require.
La règle PSR-4
PSR-4 fait correspondre un préfixe de namespace à un dossier. Ensuite, chaque niveau de namespace est un dossier, et le nom de la classe est le nom du fichier, à la casse près.
json
{
"autoload": {
"psr-4": {
"Stjo\\Demo\\": "src/"
}
}
}
Les deux barres obliques inverses ne sont pas une coquille : en JSON, \\ est la façon d’écrire une seule barre. Le namespace déclaré est bien Stjo\Demo\, avec une barre finale.
Le fichier src/Chrono.php déclare alors la classe Stjo\Demo\Chrono :
php
<?php
namespace Stjo\Demo;
class Chrono
{
public function __construct(private float $depart = 0) {}
public function demarrer(): void
{
$this->depart = microtime(true);
}
public function tempsEcoule(): float
{
return round(microtime(true) - $this->depart, 3);
}
}
Régénérer le chargeur
bash
composer dump-autoload
À faire après toute modification de la section autoload. Pas après l’ajout d’une classe : PSR-4 la trouve toute seule.
Un seul require, et un seul
php
<?php
require 'vendor/autoload.php';
use Stjo\Demo\Chrono;
$chrono = new Chrono();
$chrono->demarrer();
usleep(120000);
echo "Temps écoulé : {$chrono->tempsEcoule()} s\n";
Sortie
Temps écoulé : 0.124 s
vendor/autoload.php est le seul require d’un projet moderne. Tout le reste — vos classes comme celles de Monolog — arrive par les namespaces.
autoload-dev
Vos classes de test ne servent pas en production. Elles ont leur propre section, ignorée par composer install --no-dev :
json
{
"autoload-dev": {
"psr-4": {
"Stjo\\Demo\\Tests\\": "tests/"
}
}
}
Les scripts, en trois usages
Composer peut retenir vos commandes de projet, pour que personne n’ait à les deviner.
Déclarer
json
{
"scripts": {
"test": "phpunit",
"verifier": ["@test", "@php -l src/Chrono.php"]
}
}
Lister et exécuter
bash
composer run-script --list
composer test
Sortie
scripts:
test Runs the test script as defined in composer.json
verifier Runs the verifier script as defined in composer.json
Un tableau enchaîne plusieurs commandes. @test appelle un autre script du même fichier, @php appelle le PHP que Composer utilise — et non celui qui traînerait dans le PATH.
Un hook
Certains noms sont réservés : Composer les déclenche lui-même.
json
{
"scripts": {
"post-install-cmd": "@php bin/preparer-cache.php"
}
}
post-install-cmd s’exécute après chaque composer install. Il en existe une quinzaine — pre-update-cmd, post-autoload-dump… L’écriture avancée de scripts, les hooks de plugins et la composition de tâches viendront dans un cours Composer avancé, encore à écrire.
Un script s’exécute avec vos droits, sans confirmation. C’est la raison de la règle de la section 2 : jamais sudo composer.
Mettre en production
La commande
bash
composer install --no-dev --optimize-autoloader
Sortie
Installing dependencies from lock file
Package operations: 2 installs, 0 updates, 0 removals
- Installing psr/log (3.0.2): Extracting archive
- Installing monolog/monolog (3.10.0): Extracting archive
Generating optimized autoload files
--no-dev saute require-dev. Dans le bac à sable de cette page : 29 paquets deviennent 2. Ce n’est pas qu’une question de place — chaque paquet absent est une faille possible en moins.
--optimize-autoloader remplace la recherche de fichiers par une table de correspondance écrite une fois pour toutes. Le chargement de classes cesse de toucher le disque à chaque appel.
Vérifier les alertes de sécurité
bash
composer audit
Sortie
No security vulnerability advisories found.
composer audit confronte votre composer.lock à la base d’avis de sécurité de Packagist. Il ne prouve pas que votre code est sûr : il dit seulement qu’aucune faille CONNUE n’a été publiée pour les versions que vous utilisez. À lancer avant chaque mise en production, et dans votre intégration continue.
Ce qui va dans Git, et ce qui n’y va pas
composer.json— oui, toujours.composer.lock— oui, toujours, y compris pour une application.vendor/— non : il se reconstruit à l’identique depuis le lock.- Les fichiers de configuration contenant des secrets — non, jamais.
Pour aller plus loin sur la sécurité
Deux chemins, et ils ne répondent pas à la même question. Pour COMPRENDRE les failles que ces avis décrivent — injection SQL, XSS, désérialisation — le cours des vulnérabilités les montre une par une. Pour SÉCURISER votre propre code, celui de la sécurisation des formulaires part du geste quotidien.
Un seul require, et tout le reste suit
Composer n’est pas un outil de plus : c’est celui qui rend les autres utilisables. Toute bibliothèque PHP sérieuse passe par lui, et tout framework en dépend.