Qu'est-ce que les PSRs et à quoi servent-ils ?
Par Florian Chenot
Les PSR (PHP Standards Recommendations) sont les spécifications techniques publiées par le PHP-FIG (PHP Framework Interop Group). Ce consortium, fondé en 2009, réunit les mainteneurs des principaux frameworks et bibliothèques PHP — Symfony, Laravel, Laminas, Slim, Doctrine, Composer — autour d'un objectif unique : définir des interfaces et des conventions communes pour que l'écosystème PHP parle un même langage technique.
Contrairement à ce que leur nom suggère, les PSR ne sont pas de simples recommandations de style. Certaines définissent des interfaces PHP concrètes, distribuées via Composer, que des centaines de bibliothèques implémentent ou consomment. Comprendre les PSR, c'est comprendre le socle d'interopérabilité sur lequel repose l'écosystème PHP moderne.
Les fondamentaux : style et autoloading
Conventions de codage : PSR-1, PSR-2, PSR-12 et PER
Le PSR-1 pose les bases minimales : PascalCase pour les classes, camelCase pour les méthodes, UPPER_CASE pour les constantes, un seul effet de bord par fichier. Le PSR-2, puis le PSR-12 qui l'a remplacé, précisent les règles de formatage : indentation à quatre espaces, placement des accolades, longueur de ligne, déclarations de types.
Depuis 2022, le PHP-FIG a introduit le PER Coding Style (PHP Evolving Recommendation), un format vivant qui évolue avec le langage sans nécessiter un nouveau numéro de PSR à chaque version de PHP. PER 2.0 intègre notamment les types d'union, les enums et les propriétés en lecture seule. En pratique, des outils comme PHP-CS-Fixer ou PHP_CodeSniffer appliquent ces règles automatiquement : le débat sur le style devient un non-sujet dès lors que l'équipe adopte un standard partagé.
Autoloading : PSR-0 et PSR-4
Le PSR-0 (aujourd'hui obsolète) a introduit le concept d'autoloading standardisé en PHP. Le PSR-4, qui l'a remplacé, établit la correspondance entre un namespace et un répertoire de base. C'est le standard que Composer utilise nativement : chaque entrée autoload dans composer.json repose sur PSR-4. Sans cette convention, l'écosystème de packages PHP tel qu'on le connaît n'existerait tout simplement pas.
Les interfaces d'interopérabilité
C'est ici que les PSR prennent toute leur dimension technique. Chaque interface ci-dessous est un package Composer (psr/*) que les bibliothèques implémentent ou typent dans leurs signatures.
PSR-3 : Logger Interface
Le PSR-3 définit l'interface Psr\Log\LoggerInterface avec huit niveaux de sévérité (emergency, alert, critical, error, warning, notice, info, debug). Monolog, le logger dominant de l'écosystème, implémente cette interface. Mais le point important est ailleurs : en typant vos dépendances sur LoggerInterface plutôt que sur Monolog\Logger, vous pouvez remplacer Monolog par n'importe quelle implémentation compatible sans modifier une seule ligne de code applicatif.
PSR-7 et PSR-17 : messages et factories HTTP
Le PSR-7 modélise les messages HTTP (requêtes et réponses) sous forme d'objets immuables. Ce choix d'immutabilité, parfois déroutant au premier abord, garantit qu'un middleware ne peut pas altérer silencieusement la requête pour les middlewares suivants sans retourner explicitement un nouvel objet.
Le PSR-17 complète PSR-7 en définissant des factories pour créer ces objets. Cela permet à une bibliothèque d'instancier des requêtes ou des réponses sans dépendre d'une implémentation spécifique comme Guzzle, Nyholm ou Laminas Diactoros.
PSR-15 : HTTP Handlers et Middleware
Le PSR-15 formalise le pattern middleware en PHP. Il définit deux interfaces : RequestHandlerInterface (le handler final) et MiddlewareInterface (chaque couche intermédiaire). Ce standard a unifié des dizaines d'implémentations incompatibles et permis l'émergence de micro-frameworks comme Slim 4 ou Mezzio, où l'application entière est un pipeline de middlewares PSR-15 empilés.
L'architecture middleware PSR-15, combinée aux messages PSR-7, forme un modèle de traitement HTTP composable. Chaque middleware peut inspecter la requête, la transformer, déléguer au handler suivant, puis post-traiter la réponse. L'authentification, le CORS, le rate limiting, la compression — tous deviennent des briques interchangeables.
PSR-11 : Container Interface
Le PSR-11 standardise l'injection de dépendances avec deux méthodes : get(string $id) et has(string $id). Symfony DI, PHP-DI, Laravel Container, League Container : tous implémentent cette interface. Cela permet à des bibliothèques tierces de consommer un conteneur sans savoir lequel est utilisé.
En pratique, PSR-11 a rendu possible la création de bibliothèques véritablement framework-agnostiques. Un bundle de validation, un système de routage, un gestionnaire de files d'attente peuvent déclarer une dépendance sur Psr\Container\ContainerInterface et fonctionner dans n'importe quel framework.
PSR-14 : Event Dispatcher
Le PSR-14 définit un modèle d'événements basé sur deux concepts : le EventDispatcherInterface qui émet des événements, et le ListenerProviderInterface qui résout les listeners associés. Cette séparation est délibérée — elle découple l'émission d'événements de leur enregistrement, ce qui permet des stratégies de résolution variées (attributs PHP, configuration YAML, convention de nommage).
Le PSR-14 a introduit le concept d'événement stoppable via StoppableEventInterface, permettant à un listener de court-circuiter la propagation. Ce pattern est particulièrement utile pour les systèmes de validation ou d'autorisation où un rejet doit interrompre la chaîne.
PSR-6 et PSR-16 : Cache
Le PSR-6 définit un système de cache à base de pool et d'items, adapté aux cas d'usage avancés (tags, invalidation fine). Le PSR-16 (Simple Cache) propose une API plus directe (get, set, delete) pour les cas courants. Symfony Cache, par exemple, implémente les deux interfaces, permettant aux consommateurs de choisir le niveau d'abstraction approprié.
PSR-18 : HTTP Client
Le PSR-18 standardise l'envoi de requêtes HTTP avec une seule méthode : sendRequest(RequestInterface $request): ResponseInterface. Combiné aux factories PSR-17 et aux messages PSR-7, il permet de construire des SDK et des clients API sans dépendre de Guzzle, Symfony HttpClient ou tout autre implémentation spécifique.
PSR-13 : Hypermedia Links
Le PSR-13 définit des interfaces pour la gestion des liens hypermédia dans les API RESTful. Il standardise la création et la traversée de liens entre ressources, ce qui facilite l'implémentation de HATEOAS dans les API PHP.
L'interopérabilité comme principe d'architecture
Au-delà de chaque PSR pris individuellement, c'est leur effet systémique qui transforme la façon de concevoir une application PHP.
Prévenir le vendor lock-in
Lorsqu'une architecture repose systématiquement sur les interfaces PSR plutôt que sur des implémentations concrètes, le coût de migration d'un composant devient marginal. Changer de logger, de client HTTP, de système de cache ou de conteneur DI se réduit à modifier une ligne de configuration. Cette flexibilité n'est pas théorique : elle se manifeste concrètement lors des montées de version majeures de frameworks, où les bibliothèques conformes PSR survivent sans modification.
Pour un architecte, les PSR sont un outil de gestion du risque technique. Ils permettent de repousser les décisions d'implémentation sans compromettre l'architecture, et de remplacer des composants sans réécriture.
Le processus de gouvernance du PHP-FIG
Chaque PSR traverse un processus rigoureux : proposition (Draft), discussion et révision (Review), vote des membres (Accepted). Un PSR peut aussi être marqué Deprecated ou Abandoned. Ce processus garantit que les standards publiés reflètent un consensus de l'industrie, pas la vision d'un seul framework.
Le PHP-FIG compte parmi ses membres votants les représentants de Symfony, Laravel, Drupal, Slim, Laminas et d'autres projets majeurs. Quand un PSR est accepté, il porte le poids d'un accord entre des projets qui, par ailleurs, sont en concurrence. C'est cette légitimité qui explique l'adoption massive des PSR dans l'écosystème.
PSR et qualité logicielle
Les PSR incarnent le principe d'inversion de dépendance (le D de SOLID) à l'échelle d'un écosystème entier. En dépendant d'abstractions plutôt que de concrétions, le code applicatif gagne en testabilité (les mocks implémentent la même interface), en maintenabilité (les composants sont remplaçables) et en lisibilité (les contrats sont explicites).
Pour une équipe, adopter les PSR signifie aussi réduire la surface de décision : les débats sur le style de code, le choix d'interface de logging ou le format des messages HTTP sont déjà tranchés. L'énergie se concentre sur la logique métier.
Pour aller plus loin
- Conventions de codage — Les conventions de codage pour un code propre et maintenable
- PHPStan : améliorer la qualité de votre code PHP — L'analyse statique au service de la qualité
- Pourquoi choisir Symfony pour vos projets — Un framework qui implémente les standards PSR
- PHP-FIG — Le site officiel du PHP Framework Interop Group
- Liste des PSRs — Documentation complète de tous les PSRs
- PHP-FIG sur GitHub — Les dépôts officiels des interfaces PSR
- PHP.net — Site officiel du langage PHP