Standard di codifica

Questo documento descrive le regole e i consigli per lo sviluppo di Nette. Quando contribuite al codice di Nette dovete rispettarli. Il modo più semplice per farlo è imitare il codice esistente. L'obiettivo è che tutto il codice sembri scritto da una sola persona.

Il Nette Coding Standard corrisponde a PSR-12 Extended Coding Style con due eccezioni principali: usa le tabulazioni invece degli spazi per l'indentazione e usa il PascalCase per le costanti di classe.

Molte di queste regole si possono controllare e correggere automaticamente con lo strumento Nette Coding Standard, quindi non dovete verificarle a mano.

Regole generali

  • Ogni file PHP deve contenere declare(strict_types=1)
  • Per separare i metodi si usano due righe vuote, per una migliore leggibilità
  • Il motivo per cui si usa l'operatore di soppressione (@) va documentato: @mkdir($dir); // @ - directory may exist
  • Se si usa un operatore di confronto debole (cioè ==, !=, …), l'intenzione va documentata: // == to accept null
  • Potete scrivere più classi di eccezione in un unico file chiamato exceptions.php e più enum in enums.php
  • Per le interfacce non si indica la visibilità dei metodi, perché sono sempre pubblici
  • Ogni proprietà, valore di ritorno e parametro deve avere il tipo indicato. Al contrario, per le costanti final non indichiamo mai il tipo, perché è ovvio
  • Per delimitare le stringhe si usano gli apici singoli, tranne quando il letterale stesso contiene apostrofi

Convenzioni di denominazione

A capo e parentesi

Il Nette Coding Standard corrisponde a PSR-12 (o PER Coding Style), ma lo precisa o lo modifica in alcuni punti:

  • Le arrow function si scrivono senza spazio prima della parentesi, cioè fn($a) => $b
  • Tra i diversi tipi di istruzioni di import use non serve una riga vuota
  • Il tipo di ritorno di una funzione o di un metodo e la parentesi graffa di apertura stanno sempre su righe separate:
	public function find(
		string $dir,
		array $options,
	): array
	{
		// corpo del metodo
	}

La parentesi graffa di apertura su una riga separata è importante per separare visivamente la firma della funzione o del metodo dal corpo. Se la firma sta su una riga, la separazione è chiara (immagine a sinistra). Se sta su più righe, in PSR la firma e il corpo si fondono (al centro), mentre nello standard Nette restano separati (a destra):

Blocchi di documentazione (phpDoc)

La regola principale: non duplicate mai un'informazione della firma, come il tipo di un parametro o il tipo di ritorno, senza aggiungere valore.

Blocco di documentazione per la definizione di una classe:

  • Inizia con la descrizione della classe
  • Segue una riga vuota
  • Seguono le annotazioni @property (oppure @property-read, @property-write), una per riga. Sintassi: annotazione, spazio, tipo, spazio, $nome
  • Seguono le annotazioni @method, una per riga. Sintassi: annotazione, spazio, tipo di ritorno, spazio, nome(tipo $param, ...)
  • L'annotazione @author si omette. La paternità è conservata nella storia del codice sorgente
  • Si possono usare le annotazioni @internal oppure @deprecated
/**
 * MIME message part.
 *
 * @property string $encoding
 * @property-read array $headers
 * @method string getSomething(string $name)
 * @method static bool isEnabled()
 */

Un blocco di documentazione di una proprietà che contiene solo l'annotazione @var dovrebbe stare su una sola riga:

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

Blocco di documentazione per la definizione di un metodo:

  • Inizia con una breve descrizione del metodo
  • Nessuna riga vuota
  • Annotazioni @param, una per riga
  • Annotazione @return
  • Annotazioni @throws, una per riga
  • Si possono usare le annotazioni @internal oppure @deprecated

Dopo ogni annotazione c'è uno spazio, tranne dopo @param, dopo la quale ce ne sono due per una migliore leggibilità.

/**
 * Finds a file in directory.
 * @param  string[]  $options
 * @return string[]
 * @throws DirectoryNotFoundException
 */
public function find(string $dir, array $options): array

Funzioni e costanti globali

Le funzioni e le costanti globali si scrivono senza la barra rovesciata iniziale, cioè count($arr) e non \count($arr). Per le funzioni che PHP sa ottimizzare aggiungete all'inizio del file use function, così il compilatore le può tradurre in modo più efficiente. Si tratta di funzioni come count, strlen, is_array, is_string, is_scalar, sprintf ecc. Le funzioni si elencano su una sola riga, per mantenere compatto il blocco degli import:

use Nette;
use function count, is_array, is_scalar, sprintf;

Ogni tanto importiamo anche le costanti la cui conoscenza del valore può aiutare il compilatore:

use const PHP_OS_FAMILY;

Tabulazioni invece di spazi

Le tabulazioni hanno diversi vantaggi rispetto agli spazi:

  • La dimensione dell'indentazione è personalizzabile negli editor e sul web
  • Non impongono al codice la preferenza dell'utente sulla dimensione dell'indentazione, il che rende il codice più portabile
  • Si digitano con un solo tasto (ovunque, non solo negli editor che convertono le tabulazioni in spazi)
  • L'indentazione è il loro scopo
  • Rispettano le esigenze dei colleghi ipovedenti e non vedenti

Usando le tabulazioni nei nostri progetti permettiamo di personalizzare la larghezza, cosa che alla maggior parte delle persone può sembrare superflua, ma che per le persone con disabilità visive è essenziale.

Per i programmatori non vedenti che usano display braille, ogni spazio rappresenta una cella braille. Se quindi l'indentazione predefinita è di 4 spazi, un'indentazione di terzo livello spreca 12 preziose celle braille prima ancora che cominci il codice. Su un display da 40 celle, il più diffuso per i portatili, è più di un quarto delle celle disponibili sprecato senza fornire alcuna informazione.