Norme de codage

Ce document décrit les règles et recommandations pour le développement de Nette. Lorsque vous contribuez au code de Nette, vous devez les suivre. La façon la plus simple de le faire est d'imiter le code existant. L'idée est de faire en sorte que tout le code semble avoir été écrit par une seule personne.

La norme de codage de Nette correspond au style de codage étendu PSR-12 avec deux exceptions principales : il utilise des tabulations au lieu d'espaces pour l'indentation, et utilise PascalCase pour les constantes de classe.

Règles générales

  • Chaque fichier PHP doit contenir declare(strict_types=1)
  • Deux lignes vides sont utilisées pour séparer les méthodes pour une meilleure lisibilité.
  • La raison de l'utilisation de l'opérateur de fermeture doit être documentée : @mkdir($dir); // @ - directory may exist
  • Si un opérateur de comparaison faiblement typé est utilisé (par exemple ==, !=, …), l'intention doit être documentée : // == to accept null
  • Vous pouvez écrire plusieurs exceptions dans un seul fichier exceptions.php
  • La visibilité des méthodes n'est pas spécifiée pour les interfaces car elles sont toujours publiques.
  • Chaque propriété, valeur de retour et paramètre doit avoir un type spécifié. En revanche, pour les constantes finales, on ne précise jamais le type car il est évident.
  • Les guillemets simples doivent être utilisés pour délimiter la chaîne de caractères, sauf si le littéral lui-même contient des apostrophes.

Conventions de dénomination

  • Évitez d'utiliser des abréviations, sauf si le nom complet est excessif.
  • Utilisez les majuscules pour les abréviations de deux lettres, et les majuscules pascal/camel pour les abréviations plus longues.
  • Utilisez un nom ou une expression nominale pour le nom de la classe.
  • Les noms de classe doivent contenir non seulement la spécificité (Array) mais aussi la généralité (ArrayIterator). Les attributs PHP constituent une exception.
  • Les constantes de classe et les enums doivent utiliser les PascalCaps.
  • Les interfaces et les classes abstraites ne doivent pas contenir de préfixes ou de postfixes":https://blog.nette.org/…-d-interface comme Abstract, Interface ou I.

Encadrement et accolades

La norme de codage Nette correspond au PSR-12 (ou style de codage PER), en certains points elle le précise davantage ou le modifie :

  • les fonctions flèches sont écrites sans espace avant la parenthèse, c'est-à-dire que fn($a) => $b
  • aucune ligne vide n'est requise entre les différents types d'instructions d'importation use
  • le type de retour d'une fonction/méthode et l'accolade d'ouverture sont toujours sur des lignes séparées :
	public function find(
		string $dir,
		array $options,
	): array
	{
		// method body
	}

La parenthèse ouvrante sur une ligne distincte est importante pour séparer visuellement la signature de la fonction/méthode du corps. Si la signature est sur une seule ligne, la séparation est claire (image de gauche), si elle est sur plusieurs lignes, dans PSR les signatures et les corps se confondent (au milieu), alors que dans la norme Nette ils restent séparés (à droite) :

Blocs de documentation (phpDoc)

La règle principale : ne jamais dupliquer une information de signature comme le type de paramètre ou le type de retour sans valeur ajoutée.

Bloc de documentation pour la définition d'une classe :

  • Commence par une description de la classe.
  • Une ligne vide suit.
  • Les annotations @property (ou @property-read, @property-write) suivent, une par ligne. La syntaxe est : annotation, espace, type, espace, $name.
  • Les annotations @method suivent, une par une. La syntaxe est : annotation, espace, return type, espace, name(type $param, …).
  • L'annotation @author est omise. L'auteur est conservé dans un historique du code source.
  • Les annotations @internal ou @deprecated peuvent être utilisées.
/**
 * MIME message part.
 *
 * @property string $encoding
 * @property-read array $headers
 * @method string getSomething(string $name)
 * @method static bool isEnabled()
 */

Le bloc de documentation pour une propriété qui ne contient que l'annotation @var doit être sur une seule ligne :

/** @var string[] */
private array $name;

Bloc de documentation pour la définition d'une méthode :

  • Commence par une brève description de la méthode.
  • Pas de ligne vide.
  • Les annotations @param, une par ligne.
  • L'annotation @return.
  • Les annotations de @throws, une par ligne.
  • Les annotations @internal ou @deprecated peuvent être utilisées.

Chaque annotation est suivie d'un espace, sauf pour le @param qui est suivi 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

Tabulation à la place des espaces

Les tabulations présentent plusieurs avantages par rapport aux espaces :

  • la taille de l'indentation est personnalisable dans les éditeurs et sur le web.
  • elles n'imposent pas au code les préférences de l'utilisateur en matière de taille d'indentation, ce qui rend le code plus portable
  • vous pouvez les taper avec une seule touche (partout, pas seulement dans les éditeurs qui transforment les tabulations en espaces)
  • l'indentation est leur objectif
  • respecter les besoins des collègues malvoyants et aveugles

En utilisant les tabulations dans nos projets, nous permettons la personnalisation de la largeur, ce qui peut sembler inutile à la plupart des gens, mais qui est essentiel pour les personnes souffrant de déficiences visuelles.

Pour les programmeurs aveugles qui utilisent des écrans braille, chaque espace est représenté par une cellule braille et occupe un espace précieux. Ainsi, si l'indentation par défaut est de 4 espaces, une indentation de 3e niveau gaspille 12 cellules braille avant le début du code. Sur un écran de 40 cellules, qui est le plus couramment utilisé sur les ordinateurs portables, c'est plus d'un quart des cellules disponibles qui est gaspillé sans aucune information.