Coding Standard

Dieses Dokument beschreibt die Regeln und Empfehlungen für die Entwicklung von Nette. Wenn Sie Code zu Nette beisteuern, müssen Sie sich an sie halten. Am einfachsten gelingt das, indem Sie den bestehenden Code nachahmen. Das Ziel ist, dass der gesamte Code so aussieht, als hätte ihn eine einzige Person geschrieben.

Der Nette Coding Standard entspricht dem PSR-12 Extended Coding Style mit zwei wesentlichen Ausnahmen: Zum Einrücken verwendet er Tabulatoren statt Leerzeichen und für Klassenkonstanten PascalCase.

Viele dieser Regeln kann das Werkzeug Nette Coding Standard automatisch prüfen und korrigieren, Sie müssen sie also nicht von Hand kontrollieren.

Allgemeine Regeln

  • Jede PHP-Datei muss declare(strict_types=1) enthalten
  • Zur besseren Lesbarkeit werden Methoden durch zwei Leerzeilen getrennt
  • Der Grund für die Verwendung des Fehlerunterdrückungsoperators (@) muss dokumentiert werden: @mkdir($dir); // @ - directory may exist
  • Wird ein schwach typisierter Vergleichsoperator verwendet (also ==, !=, …), muss die Absicht dokumentiert werden: // == to accept null
  • Mehrere Exception-Klassen dürfen Sie in eine einzige Datei namens exceptions.php schreiben, mehrere Enums in enums.php
  • Bei Interfaces wird die Sichtbarkeit von Methoden nicht angegeben, denn sie sind immer public
  • Jede Property, jeder Rückgabewert und jeder Parameter muss einen Typ angegeben haben. Umgekehrt geben wir bei finalen Konstanten den Typ nie an, weil er offensichtlich ist
  • Zum Begrenzen von Strings sollen einfache Anführungszeichen verwendet werden, außer wenn das Literal selbst Apostrophe enthält

Benennungskonventionen

Umbrüche und Klammern

Der Nette Coding Standard entspricht PSR-12 (bzw. dem PER Coding Style), präzisiert oder verändert ihn aber in einigen Punkten:

  • Arrow-Funktionen werden ohne Leerzeichen vor der Klammer geschrieben, also fn($a) => $b
  • Zwischen verschiedenen Arten von use-Import-Anweisungen ist keine Leerzeile nötig
  • Der Rückgabetyp einer Funktion/Methode und die öffnende geschweifte Klammer stehen immer in getrennten Zeilen:
	public function find(
		string $dir,
		array $options,
	): array
	{
		// Rumpf der Methode
	}

Die öffnende geschweifte Klammer in einer eigenen Zeile ist wichtig, um die Signatur der Funktion/Methode optisch vom Rumpf zu trennen. Steht die Signatur in einer Zeile, ist die Trennung deutlich (Bild links), erstreckt sie sich über mehrere Zeilen, verschmelzen Signatur und Rumpf bei PSR miteinander (Mitte), während sie im Nette-Standard weiterhin getrennt bleiben (rechts):

Dokumentationsblöcke (phpDoc)

Die Hauptregel: Wiederholen Sie niemals Informationen aus der Signatur wie Parametertyp oder Rückgabetyp, ohne einen Mehrwert zu schaffen.

Dokumentationsblock für eine Klassendefinition:

  • Beginnt mit einer Beschreibung der Klasse
  • Danach folgt eine Leerzeile
  • Danach folgen Annotationen @property (oder @property-read, @property-write), eine pro Zeile. Syntax: Annotation, Leerzeichen, Typ, Leerzeichen, $name
  • Danach folgen Annotationen @method, eine pro Zeile. Syntax: Annotation, Leerzeichen, Rückgabetyp, Leerzeichen, name(type $param, ...)
  • Die Annotation @author entfällt. Die Autorschaft wird in der Historie des Quellcodes geführt
  • Die Annotationen @internal oder @deprecated dürfen verwendet werden
/**
 * MIME message part.
 *
 * @property string $encoding
 * @property-read array $headers
 * @method string getSomething(string $name)
 * @method static bool isEnabled()
 */

Ein Dokumentationsblock für eine Property, der nur die Annotation @var enthält, soll einzeilig sein:

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

Dokumentationsblock für eine Methodendefinition:

  • Beginnt mit einer kurzen Beschreibung der Methode
  • Keine Leerzeile
  • Annotationen @param, eine pro Zeile
  • Annotation @return
  • Annotationen @throws, eine pro Zeile
  • Die Annotationen @internal oder @deprecated dürfen verwendet werden

Nach jeder Annotation folgt ein Leerzeichen, außer bei @param, nach der zur besseren Lesbarkeit zwei Leerzeichen folgen.

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

Globale Funktionen und Konstanten

Globale Funktionen und Konstanten werden ohne führenden Backslash geschrieben, also count($arr) und nicht \count($arr). Bei Funktionen, die PHP optimieren kann, ergänzen Sie am Anfang der Datei use function, damit der Compiler sie effizienter übersetzen kann. Dazu gehören Funktionen wie count, strlen, is_array, is_string, is_scalar, sprintf usw. Die Funktionen werden in einer einzigen Zeile aufgeführt, damit der Import-Block kompakt bleibt:

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

Gelegentlich importieren wir auch Konstanten, bei denen die Kenntnis ihres Wertes dem Compiler helfen kann:

use const PHP_OS_FAMILY;

Tabulatoren statt Leerzeichen

Tabulatoren haben gegenüber Leerzeichen mehrere Vorteile:

  • Die Größe der Einrückung lässt sich in Editoren und im Web einstellen
  • Sie zwingen dem Code nicht die bevorzugte Einrückungsgröße des Benutzers auf, wodurch der Code portabler wird
  • Sie lassen sich mit einem einzigen Tastendruck eingeben (überall, nicht nur in Editoren, die Tabulatoren in Leerzeichen umwandeln)
  • Einrücken ist ihr Zweck
  • Sie berücksichtigen die Bedürfnisse sehbehinderter und blinder Kollegen

Indem wir in unseren Projekten Tabulatoren verwenden, ermöglichen wir eine Anpassung der Breite, die den meisten Menschen unnötig erscheinen mag, für Menschen mit Sehbehinderung aber wesentlich ist.

Für blinde Programmierer, die Braillezeilen verwenden, steht jedes Leerzeichen für eine Braillezelle. Beträgt die Standardeinrückung also 4 Leerzeichen, verschwendet eine Einrückung der 3. Ebene 12 wertvolle Braillezellen, bevor der Code überhaupt beginnt. Auf einer Zeile mit 40 Zellen, wie sie bei Laptops am häufigsten ist, ist das mehr als ein Viertel der verfügbaren Zellen, das ohne jede Information verschwendet wird.