Standard de codage
******************
.[perex]
Ce document décrit les règles et les recommandations pour le développement de Nette. Quand vous contribuez du code à Nette, vous devez les respecter. Le plus simple est d'imiter le code existant. L'objectif est que tout le code paraisse écrit par une seule personne.
Le Nette Coding Standard correspond au [PSR-12 Extended Coding Style |https://www.php-fig.org/psr/psr-12/] avec deux exceptions majeures : il indente avec des [tabulations au lieu d'espaces |#Tabulations au lieu d'espaces] et emploie le [PascalCase pour les constantes de classe|https://blog.nette.org/fr/for-less-screaming-in-the-code].
.[tip]
Beaucoup de ces règles peuvent être vérifiées et corrigées automatiquement par l'outil [Nette Coding Standard |tools:coding-standard], vous n'avez donc pas à les contrôler à la main.
Règles générales
================
- Chaque fichier PHP doit contenir `declare(strict_types=1)`
- Deux lignes vides séparent les méthodes, pour une meilleure lisibilité
- La raison d'employer l'opérateur de silence (`@`) doit être documentée : `@mkdir($dir); // @ - directory may exist`
- Si un opérateur de comparaison faible est utilisé (`==`, `!=`, ...), l'intention doit être documentée : `// == to accept null`
- Vous pouvez écrire plusieurs classes d'exception dans un seul fichier nommé `exceptions.php`, et plusieurs enums dans `enums.php`
- La visibilité des méthodes n'est pas précisée dans les interfaces, car elles sont toujours publiques
- Chaque propriété, valeur de retour et paramètre doit avoir un type. À l'inverse, pour les constantes finales, nous ne précisons jamais le type, car il est évident
- Les chaînes se délimitent par des apostrophes, sauf lorsque le littéral contient lui-même des apostrophes
Conventions de nommage
======================
- Évitez les abréviations, sauf si le nom complet est excessif
- Écrivez les abréviations de deux lettres en majuscules, et employez PascalCase/camelCase pour les plus longues
- Employez un nom ou un groupe nominal pour le nom d'une classe
- Un nom de classe doit contenir non seulement le spécifique (`Array`) mais aussi le générique (`ArrayIterator`). Les attributs PHP font exception
- "Les constantes de classe et les enums devraient utiliser PascalCaps":https://blog.nette.org/fr/for-less-screaming-in-the-code
- "Les interfaces et les classes abstraites ne devraient pas porter de préfixes ni de suffixes":https://blog.nette.org/fr/prefixes-and-suffixes-do-not-belong-in-interface-names comme `Abstract`, `Interface` ou `I`
Retours à la ligne et accolades
===============================
Le Nette Coding Standard correspond au PSR-12 (ou PER Coding Style), mais le précise ou le modifie sur certains points :
- Les fonctions fléchées s'écrivent sans espace avant la parenthèse, c'est-à-dire `fn($a) => $b`
- Aucune ligne vide n'est exigée entre les différents types d'imports `use`
- Le type de retour d'une fonction/méthode et l'accolade ouvrante sont toujours sur des lignes distinctes :
```php
public function find(
string $dir,
array $options,
): array
{
// method body
}
```
L'accolade ouvrante sur une ligne à part est importante pour séparer visuellement la signature de la fonction/méthode de son corps. Si la signature tient sur une ligne, la séparation est claire (image de gauche). Si elle s'étale sur plusieurs lignes, en PSR la signature et le corps se confondent (au milieu), tandis que dans le standard de Nette ils restent séparés (à droite) :
[* new-line-after.webp *]
Blocs de documentation (phpDoc)
===============================
La règle principale : **ne dupliquez jamais** une information de la signature, comme le type d'un paramètre ou le type de retour, sans apporter de valeur.
Bloc de documentation d'une définition de classe :
- Commence par une description de la classe
- Suivie d'une ligne vide
- Suivie des annotations `@property` (ou `@property-read`, `@property-write`), une par ligne. Syntaxe : annotation, espace, type, espace, `$nom`
- Suivies des annotations `@method`, une par ligne. Syntaxe : annotation, espace, type de retour, espace, `nom(type $param, ...)`
- L'annotation `@author` est omise. La paternité est conservée dans l'historique du code source
- Les annotations `@internal` ou `@deprecated` peuvent être utilisées
```php
/**
* MIME message part.
*
* @property string $encoding
* @property-read array $headers
* @method string getSomething(string $name)
* @method static bool isEnabled()
*/
```
Un bloc de documentation de propriété ne contenant que l'annotation `@var` doit tenir sur une seule ligne :
```php
/** @var string[] */
private array $name;
```
Bloc de documentation d'une définition de méthode :
- Commence par une courte description de la méthode
- Pas de ligne vide
- Les annotations `@param`, une par ligne
- L'annotation `@return`
- Les annotations `@throws`, une par ligne
- Les annotations `@internal` ou `@deprecated` peuvent être utilisées
Chaque annotation est suivie d'une espace, sauf `@param`, qui est suivie de deux espaces pour une meilleure lisibilité.
```php
/**
* Finds a file in directory.
* @param string[] $options
* @return string[]
* @throws DirectoryNotFoundException
*/
public function find(string $dir, array $options): array
```
Fonctions et constantes globales
================================
Les fonctions et constantes globales s'écrivent sans barre oblique inverse initiale, donc `count($arr)` et non `\count($arr)`. Pour les fonctions que PHP sait optimiser, ajoutez `use function` au début du fichier, afin que le compilateur les traduise plus efficacement. Il s'agit de fonctions comme `count`, `strlen`, `is_array`, `is_string`, `is_scalar`, `sprintf`, etc. Les fonctions sont listées sur une seule ligne pour garder le bloc d'imports compact :
```php
use Nette;
use function count, is_array, is_scalar, sprintf;
```
Il nous arrive aussi d'importer des constantes dont la connaissance de la valeur peut aider le compilateur :
```php
use const PHP_OS_FAMILY;
```
Tabulations au lieu d'espaces
=============================
Les tabulations ont plusieurs avantages sur les espaces :
- La taille de l'indentation est réglable dans les éditeurs et sur le "web":https://developer.mozilla.org/en-US/docs/Web/CSS/tab-size
- Elles n'imposent pas au code la préférence d'indentation de leur auteur, ce qui rend le code plus portable
- Elles s'obtiennent d'une seule frappe (partout, pas seulement dans les éditeurs qui convertissent les tabulations en espaces)
- L'indentation est leur raison d'être
- Elles respectent les besoins des collègues malvoyants et aveugles
En utilisant des tabulations dans nos projets, nous permettons d'en régler la largeur, ce qui peut sembler superflu à la plupart des gens, mais qui est essentiel pour les personnes atteintes de déficience visuelle.
Pour les programmeurs aveugles qui utilisent un afficheur braille, chaque espace occupe une cellule braille. Si l'indentation par défaut est de 4 espaces, une indentation de 3e niveau gaspille donc 12 précieuses cellules braille avant même que le code ne commence. Sur un afficheur de 40 cellules, le plus courant pour les portables, c'est plus d'un quart des cellules disponibles gaspillé sans apporter la moindre information.
{{priority: -1}}
Standard de codage
Ce document décrit les règles et les recommandations pour le développement de Nette. Quand vous contribuez du
code à Nette, vous devez les respecter. Le plus simple est d'imiter le code existant. L'objectif est que tout le code paraisse
écrit par une seule personne.
Beaucoup de ces règles peuvent être vérifiées et corrigées automatiquement par l'outil Nette Coding Standard, vous n'avez donc pas à les contrôler à
la main.
Règles générales
Chaque fichier PHP doit contenir declare(strict_types=1)
Deux lignes vides séparent les méthodes, pour une meilleure lisibilité
La raison d'employer l'opérateur de silence (@) doit être documentée
: @mkdir($dir); // @ - directory may exist
Si un opérateur de comparaison faible est utilisé (==, !=, …), l'intention doit être
documentée : // == to accept null
Vous pouvez écrire plusieurs classes d'exception dans un seul fichier nommé exceptions.php, et plusieurs enums
dans enums.php
La visibilité des méthodes n'est pas précisée dans les interfaces, car elles sont toujours publiques
Chaque propriété, valeur de retour et paramètre doit avoir un type. À l'inverse, pour les constantes finales, nous ne
précisons jamais le type, car il est évident
Les chaînes se délimitent par des apostrophes, sauf lorsque le littéral contient lui-même des apostrophes
Conventions de nommage
Évitez les abréviations, sauf si le nom complet est excessif
Écrivez les abréviations de deux lettres en majuscules, et employez PascalCase/camelCase pour les plus longues
Employez un nom ou un groupe nominal pour le nom d'une classe
Un nom de classe doit contenir non seulement le spécifique (Array) mais aussi le générique
(ArrayIterator). Les attributs PHP font exception
Le Nette Coding Standard correspond au PSR-12 (ou PER Coding Style), mais le précise ou le modifie sur certains points :
Les fonctions fléchées s'écrivent sans espace avant la parenthèse, c'est-à-dire fn($a) => $b
Aucune ligne vide n'est exigée entre les différents types d'imports use
Le type de retour d'une fonction/méthode et l'accolade ouvrante sont toujours sur des lignes distinctes :
public function find(
string $dir,
array $options,
): array
{
// method body
}
L'accolade ouvrante sur une ligne à part est importante pour séparer visuellement la signature de la fonction/méthode de son
corps. Si la signature tient sur une ligne, la séparation est claire (image de gauche). Si elle s'étale sur plusieurs lignes, en
PSR la signature et le corps se confondent (au milieu), tandis que dans le standard de Nette ils restent séparés (à
droite) :
Blocs de documentation (phpDoc)
La règle principale : ne dupliquez jamais une information de la signature, comme le type d'un paramètre ou le type de
retour, sans apporter de valeur.
Bloc de documentation d'une définition de classe :
Commence par une description de la classe
Suivie d'une ligne vide
Suivie des annotations @property (ou @property-read, @property-write), une par ligne.
Syntaxe : annotation, espace, type, espace, $nom
Suivies des annotations @method, une par ligne. Syntaxe : annotation, espace, type de retour,
espace, nom(type $param, ...)
L'annotation @author est omise. La paternité est conservée dans l'historique du code source
Les annotations @internal ou @deprecated peuvent être utilisées
Un bloc de documentation de propriété ne contenant que l'annotation @var doit tenir sur une seule ligne :
/** @var string[] */
private array $name;
Bloc de documentation d'une définition de méthode :
Commence par une courte description de la méthode
Pas de ligne vide
Les annotations @param, une par ligne
L'annotation @return
Les annotations @throws, une par ligne
Les annotations @internal ou @deprecated peuvent être utilisées
Chaque annotation est suivie d'une espace, sauf @param, qui est suivie de deux espaces pour une meilleure
lisibilité.
/**
* Finds a file in directory.
* @param string[] $options
* @return string[]
* @throws DirectoryNotFoundException
*/
public function find(string $dir, array $options): array
Fonctions et constantes globales
Les fonctions et constantes globales s'écrivent sans barre oblique inverse initiale, donc count($arr) et non
\count($arr). Pour les fonctions que PHP sait optimiser, ajoutez use function au début du fichier, afin
que le compilateur les traduise plus efficacement. Il s'agit de fonctions comme count, strlen,
is_array, is_string, is_scalar, sprintf, etc. Les fonctions sont listées sur
une seule ligne pour garder le bloc d'imports compact :
use Nette;
use function count, is_array, is_scalar, sprintf;
Il nous arrive aussi d'importer des constantes dont la connaissance de la valeur peut aider le compilateur :
use const PHP_OS_FAMILY;
Tabulations au lieu d'espaces
Les tabulations ont plusieurs avantages sur les espaces :
La taille de l'indentation est réglable dans les éditeurs et sur le web
Elles n'imposent pas au code la préférence d'indentation de leur auteur, ce qui rend le code plus portable
Elles s'obtiennent d'une seule frappe (partout, pas seulement dans les éditeurs qui convertissent les tabulations en
espaces)
L'indentation est leur raison d'être
Elles respectent les besoins des collègues malvoyants et aveugles
En utilisant des tabulations dans nos projets, nous permettons d'en régler la largeur, ce qui peut sembler superflu à la
plupart des gens, mais qui est essentiel pour les personnes atteintes de déficience visuelle.
Pour les programmeurs aveugles qui utilisent un afficheur braille, chaque espace occupe une cellule braille. Si l'indentation
par défaut est de 4 espaces, une indentation de 3e niveau gaspille donc 12 précieuses cellules braille avant même que le code
ne commence. Sur un afficheur de 40 cellules, le plus courant pour les portables, c'est plus d'un quart des cellules disponibles
gaspillé sans apporter la moindre information.