Par pitié, suivez les PSR

Au fil des projets auxquels j’ai participé depuis plusieurs années, je me suis rendu compte que chaque développeur prend régulièrement un style de code qui lui est propre s’il n’est pas cadré strictement. Étant donné que les langages permettent dans la grande majorité des cas d’écrire le code sans forme précise dès lors que l’on en suit la syntaxe, chacun choisi la mise en forme qui lui parait la plus juste aux yeux, mais ce n’est pas forcément la même que son voisin, loin de là.

Les PSR (PHP Standards Recommendation) sont un ensemble de règles établies afin d’harmoniser au mieux le code PHP produit par les différents développeurs, afin de garantir l’homogénéité et la lisibilité du code. Elles sont maintenant suivies par de nombreux développeurs, notamment dans les dépôt publics tels Github, puisque la cohérence du code est fondamentale pour faciliter la contribution des projets open source. On rencontre néanmoins encore en SSII ou chez des clients des projets qui ne suivent pas ces recommandations, que ce soit par méconnaissance ou par désintérêt des standards. Je vais donc essayer de vous convaincre de l’utilité de ces règles pour la qualité du code.

A l’heure actuelle il existe 5 règles validées numérotées PSR-0 à PSR-4, je vais ici m’intéresser aux trois premières d’entre elles en parcourant les critères qui me semblent les plus pertinents tout en étant trop souvent ignorés. Vous pouvez les parcourir dans leur version originale et en détail, ainsi que les propositions en cours d’études, sur Github.

PSR-0 : Autoloading

Cette recommandation ne concerne pas directement la forme du code mais l’organisation des fichiers et des classes dans le projet, elle permet d’utiliser un autoloader standard pour les classes des applications suivant cette règle. Ainsi, chaque classe doit être dans un namespace dont le premier niveau est le nom de l’éditeur de cette classe (le “vendor” en anglais), c’est à dire la société ou la personne principale qui maintient le projet. Tous les autres niveaux sont à la discrétion du développeur.

L’arborescence des dossiers et fichiers doit suivre le namespace, c’est à dire que la classe MyClass dans le namespace \Editeur\A\B sera localisée dans le fichier /votre/projet/Editeur/A/B/MyClass.php.

Une fois que le code suit ce standard, il suffit d’enregistrer l’autoloader SplClassLoader (ou un autre qui suit la norme) au démarrage de l’application pour que les fichiers de classes soient inclus automatiquement lorsque la définition de la classe est nécessaire à l’exécution (instanciation, déclaration d’une classe héritée…).

PSR-1 : Le standard basique

Les namespaces et classes doivent suivre une norme d’autoloading (PSR-0 ou PSR-4). La PSR-1 demande donc d’avoir suivi les recommandations de la PSR-0 pour être elle-même validée.

Les fichiers doivent être encodés en UTF-8. Cela parait évident et pourtant on trouve encore des développeurs travaillant avec des éditeurs de code configurés pour faire du latin1 (ISO-8859-1). L’UTF-8 est un standard beaucoup plus souple et surtout beaucoup plus exportable que latin1 qui permet de supporter tous les caractères spéciaux même en dehors des langues latines. Cela vous garantit une compatibilité maximum de vos fichiers avec les autres machines.
De plus, les sites web doivent afficher des pages encodées en UTF8 pour supporter facilement des visiteurs du monde entier et leur afficher ainsi les pages de la même manière quelle que soit leur langue. Avoir vos fichiers de travail encodés correctement vous évite bien des problèmes par la suite, c’est aussi vrai pour le contenu de votre base de données.

Les namepaces et classes doivent être nommés en StudlyCaps, les méthodes en camelCase. Cette règle à pour but de faciliter la lisibilité du code pour tout le monde. L’utilisation de majuscules pour séparer les mots  permet d’améliorer la lecture en évitant la lourdeur des underscores.

Les constantes doivent être déclarées en majuscules avec des underscores pour séparer les mots. Cette recommandation est en fait très ancienne et est une convention utilisée dans la plupart des langages pour que le caractère constant de ces valeurs soit mis en avant même sans avoir le mot clé “const” qui permet généralement de les définir. Un lecteur avisé sait donc directement qu’il a affaire à une constante et non à une variable, sans cela la distinction ne viendrait pas de soi dans la majorité des langages, sauf en PHP où les variables sont préfixées par le dollar. Quoi qu’il en soit, la convention est restée dans les recommandations.

PSR-2 : Le style du code

De même que précédemment, le code doit suivre la PSR-1 pour être valide PSR-2.

L’indentation doit se faire par des groupes de 4 espaces et non des tabulations. Cette règle à une origine très simple : toutes les éditeurs de texte n’affichent pas les tabulations avec la même largeur. Un code qui parait harmonieux sous eclipse affichera une indentation probablement trop forte sous vim, qui affiche les tabulations avec une largeur de 8 espaces. Configurer votre IDE pour indenter avec des espaces est la première chose à faire après l’avoir installé sur votre machine, en plus de vérifier la configuration de l’UTF-8. J’ai personnellement pris l’habitude d’afficher les caractères invisibles (espaces et tabulations) dans mon IDE, ce qui permet de repérer d’un coup d’oeil les tabulations mais aussi de repérer facilement une erreur dans le nombre d’espaces d’indentation.

Les lignes doivent autant que possible faire moins de 120 caractères, de préférence moins de 80. Cette règle parait souvent contraignante dès lors que l’on a une forte indentation du code ou que l’on veut utiliser une chaîne de caractères assez longue ou plusieurs conditions dans une boucle. Cependant le premier problème vient souvent d’une logique de l’application trop complexe (beaucoup de structures conditionnelles imbriquées les unes dans les autres), il faut donc se demander si l’on ne peut pas simplifier ou déplacer du code lorsque l’indentation est trop forte. Dans les autres cas, la ligne peut généralement être coupée en deux (ou plus) et donc repasser sous la limite des 80 caractères, soit en créant des variables intermédiaires, soit en faisant un appel de fonction multiligne par exemple.
Notez bien que cette règle n’a pas à être strictement appliquée, mais elle facilite la lecture du code en évitant d’utiliser l’ascenseur horizontal dans un éditeur.

Les accolades ouvrantes et fermantes des déclarations de classes et fonctions doivent être seules sur leur ligne, en revanche l’accolade ouvrante d’une structure conditionnelle doit être sur la même ligne. Cette norme permet de bien délimiter visuellement les blocs de code importants comme les classes et les fonctions, tout en rendant plus concises les structures conditionnelles. Il faut bien reconnaître que le code suivant est lourd à lire :

if ($myCondition === true)
{
  //...
}
else
{
  //...
}

Tandis que sa variante économise des lignes et simplifie le parcours des yeux :

if ($myCondition === true) {
  //...
} else {
  //...
}

La spécification ne le précise pas mais je m’efforce personnellement de toujours avoir des accolades même dans le cas où une condition n’est suivie que d’une seule ligne d’instruction. Encore une fois, cela facilite la lecture des blocs sans être trop lourd visuellement, et cela peut éviter des erreurs dans le futur (rajout d’une instruction sans vérifier que les accolades sont présentes).

Il ne doit pas y avoir d’espaces à droite d’une parenthèse ouvrante ou à gauche d’une fermante pour les structures conditionnelles et les fonctions (sauf si l’appel se fait sur plusieurs lignes, la parenthèse peut terminer la ligne). Aussi, les virgules séparant les arguments de fonctions doivent avoir une espace après mais pas avant.
On suit ici de la grammaire de base puisque ce sont exactement les mêmes règles qui sont appliquées dans les langues latines, il n’y a donc pas lieu de faire d’excès de zèle en rajoutant des espaces inutiles, qui nuisent de toute façon à la fluidité de la lecture comme sur cet exemple :

while ( $i ++ < 100 ) {
  processSomething ( $i , $myObject );
}

Vérification automatique

La vérification des règles de formattage se fait facilement avec l’outil PHP_CodeSniffer récupérable avec PEAR.

pear install PHP_CodeSniffer

Une fois installé, vous avez accès à la commande phpcs qui permet d’inspecter un ou plusieurs fichiers et répertoires à la recherche d’erreur de mise en forme et vous remonte celles-ci une par une. La plupart des éditeurs de code permet de lancer phpcs automatiquement et de vous remonter les erreurs rencontrées directement lorsque vous éditez les fichiers.

Conclusion

Le sujet des normes de codage est vaste et va bien au-delà de la simple mise en forme du code. On pourrait s’attarder sur la documentation, ou encore l’utilisation d’interfaces standards pour certaines classes (c’est notamment ce que décrit la PSR-3 pour les classes de log), ce ne sont pas les sujets qui manquent, mais écrire son code avec clarté dans un style standard me parait être le premier pas pour le travail en communauté, c’est même une obligation dans toute structure sérieuse.