StudipCsFormatierung

Coding Style Index?

UNGÜLTIG!!! VERALTET!!!

Bitte benutzen Sie die aktuellen Standards: CodingStyle?

Sprache

Die bevorzugte Sprache für Code und Kommentare ist Englisch.

Einrückungen und Zeilenlänge

Benutzen Sie Einrückungen mit 4 Leerzeichen, keine Tabulatoren. Damit helfen Sie, Probleme zu vermeiden, die mit Diffs, Patches und anderen CVS/SVN-Funktionen entstehen.

Rücke so tief ein wie notwendig, jedoch nicht mehr. Obwohl es keine Regel über die maximale Einrücktiefe gibt, wird empfohlen ab einer Einrücktiefe von 4 bis 5 Ebenen Quellcode zu faktorisieren.

Wir empfehlen einen Zeilenumbruch bei ca. 75 - 85 Zeichen durchzuführen, um die Lesbarkeit zu erhöhen. Maximale Zeilenlänge sollte bei 120 Zeichen erreicht sein. Zeilenumbruch nach fester Anzahl Zeichen muss bei Markup Sprachen wie HTML, XHML, XML, etc. nicht eingehalten werden.

PHP-Code-Tags

Benutzen Sie immer <?php ?> um Ihren PHP-Code zu markieren, niemals die Kurzform <? ?>. Die erste Variante funktioniert unabhängig vom Betriebssystem und der PHP-Konfiguration.

Kommentare

Verwende Kommentare im C-Stil (/* */) und von Standard-C++ (//). Kommentare im Perl/shell-Stil (#) vermeiden.

Dokumentationen & Tags folgen der PHPDoc Syntax. Für den Quellcode sollte eine vollständige Inline-Dokumentation bereitgestellt (Docblocks) und auch abseits der offziellen API-Dokumentation kommentiert werden. Geben Sie hilfreiche Zusatzinformationen und machen Sie dem Reviewer das Leben leichter. ;-)

Als Daumenregel gilt, wenn Sie auf einen Code-Abschnitt schauen und denken: „Wow, Ich würde nicht versuchen herauszufinden, wie es funktioniert“, sollten Sie auf jeden Fall einen Kommentar ergänzen, bevor Sie vergessen, wie es funktioniert.

Ergänzen Sie die Lizenzbestimmungen in jeder Datei innerhalb des Page-Level DocBlocks.

Genaueres über das Anfertigen von Dokumentationen entnehmen sie dem Dokumentationsabschnitt und dem Lizenzabschnitt des Coding Standards.

Operatoren

Falls sinnvoll für die Lesbarkeit sollten Operatoren rechts und links von einem Leerzeichen umgeben sein.

Bsp:

  1. $bar = 5;
  2. $foo = $bar % 5;

Kontrollstrukturen (if, for, while, switch usw.)

Bsp für if-Kosntruktionen:

  1. <?php
  2. if ((condition1) || (condition2)) {
  3.     action1;
  4. } elseif ((condition3) && (condition4)) {
  5.     action2;
  6. } else {
  7.     defaultaction;
  8. }
  9. ?>

Bei Kontroll-Ausdrücken ein Leerzeichen zwischen den Schlüsselwörtern und der öffnenden Klammer einfügen, um sie von Funktionsaufrufen unterscheiden zu können.

Generell unbedingt geschweifte Klammern verwenden, auch wenn sie technisch nur optional sind. Damit verbessern Sie die Lesbarkeit und vermeiden logische Fehler, wenn neue Zeilen hinzugefügt werden.

Bsp für switch-Ausdrücke:

  1. <?php
  2. switch (condition) {
  3.     case 1:
  4.         action1;
  5.         break;
  6.  
  7.     case 2:
  8.         action2;
  9.         break;
  10.  
  11.     default:
  12.         defaultaction;
  13.         break;
  14. }
  15. ?>

Funktionsaufrufe

Funktionen sollten ohne Leerzeichen zwischen dem Funktionsnamen, der öffnenden Klammer und dem ersten Parameter aufgerufen werden. Leerzeichen sollten gesetzt werden zwischen Komma und jedem Parameter. Zwischen dem letzten Parameter, der schliessenden Klammer und Semikolon sollten keine Leerzeichen gesetzt werden.

Bsp:

  1. <?php
  2. $var = foo($bar, $baz, $quux);
  3. ?>

Wie im Abschnitt oben gezeigt, sollte ein Leerzeichen vor und hinter das Gleichheitszeichen gesetzt werden, wenn der Rückgabewert der Funktion einer Variable zugewiesen wird. Wenn ein Block zusammenhängender Zuweisungen durchgeführt wird, empfehlen wir mehrere Leerzeichen einzufügen, um die Lesbarkeit zu verbessern:

  1. <?php
  2. $short         = foo($bar);
  3. $long_variable = foo($baz);
  4. ?>

Klassen-Definition

Die öffnende Klammer einer Klassen-Deklaration beginnt auf einer neuen Zeile:

  1. <?php
  2. class FooBar
  3. {
  4.  
  5.     //... ihr Code
  6.  
  7. }
  8. ?>

Funktionsdefinitionen

Funktionsdeklarationen folgen dem „K&R-Stil“ (Programmierstil der C-Erfindern Brian W. Kernighan und Dennis Ritchie):

  1. <?php
  2. function fooFunction($arg1, $arg2 = '')
  3. {
  4.     if (condition) {
  5.         statement;
  6.     }
  7.     return $val;
  8. }
  9. ?>

Argumente mit Standardwerten werden am Ende der Argumentenliste platziert. Eine Funktion sollte immer einen aussagekräftigen Wert zurückliefern, soweit wie es möglich ist.

Bsp:

  1. <?php
  2. function connect(&$dsn, $persistent = false)
  3. {
  4.     if (is_array($dsn)) {
  5.         $dsninfo = &$dsn;
  6.     } else {
  7.         $dsninfo = DB::parseDSN($dsn);
  8.     }
  9.  
  10.     if (!$dsninfo || !$dsninfo['phptype']) {
  11.         return $this->raiseError();
  12.     }
  13.  
  14.     return true;
  15. }
  16. ?>

Codierung

Für die Codierung der HTML-Seiten wird im Seiten-Kopf ISO-8859-1/Latin1 benutzt und nie UTF-8. Damit es zu einer korrekten Darstellung kommt ist dies auf jeden Fall einzuhalten.

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8853-1" />

Konstanten / Keine Magic Numbers

Eine Magic Number ist eine Zahl mitten im Quellcode. Sie wird magisch genannt, weil niemand weiß was sie bedeutet. Statt Magische Zahlen zu benutzen definiere Konstanten mit define() oder Klassen-Konstanten mit const und gib ihnen aussagekräftige Namen.

Bsp:

  • define('SOME_CONSTANT_VALUE', 42)
  • const SOME_CONSTANT_VALUE = 42

Maximale Anzahl Klassen/Interfaces pro File

Es bietet sich zwar in PHP an mehrere Klassen/Interfaces in einem File unterzubringen, jedoch erschwert dies nicht nur die Suche bei der Wartung, sondern schafft auch Mehrdeutigkeiten bzgl. der Packages (Namensräume). Daher empfehlen wir Klassen in verschiedene Files zu zergliedern und diese in Packages anzuordnen.

Paket-Struktur auf Page- & Class-Level

Funktionen, Konstanten und Globale Variablen werden vom Filesystem in Files gruppiert, die wiederum mittels phpDocumentor Tag @package und @subackage innerhalb von Page-Level DocBlocks in Pakete und Unterpakete gegliedert werden sollen.

Methoden und Klassenvariablen werden von PHP in Klassen gruppiert, die wiederum mittels phpDocumentor Tag @package und @subpackage innerhlab von Class-Level DocBlocks in Pakete und Unterpakete gegliedert werden sollen.

Wird diese Paket-Struktur nicht eingehalten so hat phpDocumentor Probleme den Code zu parsen.

Objekt-orientiertes Design

Seit PHP 5 gibt es die Möglichkeit der Objekt-orientierten Programmierung. Die damit verbundenen Konzepte bieten viele Vorteile für das Software-Design, der Wiederverwendbarkeit und Wartbarkeit. Konstrukte & Schlüsselwörter, die deprecated sind, sind zu vermeiden.

Klassen

Zentral ist das Konzept der Klassen und Klassenhierarchie. Funktionalität soll gekapselt werden, damit Klassen einfach wiederzuverwenden und wartbar sind.

Konstruktor und Destruktor

Für die Erzeugung und Freigabe eines Objektes gibt es die speziellen Methoden Konstruktor __constuctor und Destruktor __destructor. Aus Kompatibilitätsgründen zu älteren Versionen wird aber auch eine Methode mit dem Namen der Klasse als Konstruktor akzeptiert.

Sichtbarkeitsschlüsselwörter

Für Methoden und Klassenvariablen gibt es die Sichtbarkeitsschlüsselwörter public, protected, private. Schlüsselwort var ist deprecated.

Methoden-/Funktionsargumente

Referenzen als Argumente sollten nur benutzt werden, wenn es sich nicht vermeiden lässt, d.h. wenn die Funktion auch wirklich den Inhalt der Variablen verändern muss. Die Performance von Übergaben als Referenz ist zwar manchmal schneller, jedoch wird sich dies nur bei umfangreichen Schleifen oder bei der Übertragung von grossen Arrays oder Objekten bemerkbar machen.

Konstruktoren

Konstruktoren nur für die Initialisierung von Variablen benutzen und/oder für Aktionen, die nicht fehlschlagen können. Implementiere weitere Methoden für alle anderen Aktionen und rufe diese nach der Objekt-Instanziierung auf.

Inkludierte Dateien

Dateien, die inkludiert werden, enden auf "*.inc.php" und/oder liegen in einem Unterverzeichnis "inc". Es ist besser ein Unterverzeichnis ("include" oder "inc") für die Dateien anzulegen, die mit include() oder ähnlichen Befehlen inkludiert werden.

Code einbinden

Immer wenn eine Klassendatei unbedingt inkludiert werden muss, benutze require_once. Bei auftretenden Fehlern wird der Programmfluss angehalten. Wird hingegen eine Datei nur bedingt benötigt, z.B. in Factory-Methoden, verwende include_once. Hier werden nur Warnungen ausgegeben, der Programmfluss jedoch nicht unterbrochen. Beide stellen sicher, dass die Datei nur einmal eingebunden wird. Beide Funktionen benutzen die gleiche Liste zur Verwaltung der bereits eingebundenen Dateien. Sie müssen sich über eine Mischung aus beiden Funktionsaufrufen keine Gedanken machen - eine Datei, die per require_once eingebunden wurde, wird nicht erneut eingebunden mit include_once.

Es wird jedoch empfohlen stets require_once zu benutzen, da i.A. ein Script nicht weiterlaufen sollte, wenn Files nicht vorhanden sind oder Filenamen nicht korrekt sind.

Anmerkung: include_once und require_once sind Anweisungen, nicht Funktionen. Deshalb sollten die Dateinamen nicht in Klammern eingeschlossen werden.

Switch-Statements

Für den Fall, dass der Programmfluss von einem Case-Statement ins nächste Case-Statement fällt, d.h. kein Break-Statement enthalten ist, muss dies kommentiert werden. Desweiteren sollte immer ein Default-Statement geschrieben werden, um Fehler abzufangen. Falls Variablen in einem Case-Statement erzeugt werden müssen, schreibe alles in einen Block.

Generierter HTML-Code

Für die Trennung von Layout und Programmlogik wird der zu erzeugenden HTML-Code mit Templates generiert statt direkt aus PHP-Dateien heraus. Falls es doch in wenigen Einzelfällen notwendig ist aus PHP-Dateien heraus HTML-Code zu generieren, so ist es aus Gründen der Übersichtlichkeit (Debugging!) zu empfehlen ausreichend und sinnvoll platzierte Zeilenende ("\n") eingefügt werden. Eine Einrückung des HTML-Codes kann durch vorangestellte "\t" erzeugt werden.

Internationalisierung

Generell wird zur Darstellung sprachspezifischer Strings das gettext- (oder auch i18n) -System verwendet.

Alle Strings im System dürfen nicht in den HTML-Teilen der Sourcedateien stehen, sondern müssen aus PHP-Abschnitten heraus geschrieben werden. Die zu übersetzenden Zeichenfolgen werden im Programmcode in die spezielle Funktion gettext() eingeschlossen. Benutzt werden sollte nur die Kurzform, in PHP realisiert als _().

echo _("Meine Veranstaltungen")

In die zu übersetzenden Strings sollte reiner Text, keine HTML-Struktur der Seite und kein Programmcode wie z.B. Variablennamen eingeschlossen werden.

Falsch:

echo _("<tr><td>Meine Veranstaltungen</td></tr>");

Richtig:

echo "<tr><td>" . _("Meine Veranstaltungen") . "</td></tr>";

Oder Richtig:

printf("<tr><td>%s</td></tr>", _(" Meine Veranstaltungen "));

Falsch:

print _("error§Keine Berechtigung!§");

Richtig:

printf("error§%s§", _("Keine Berechtigung!"));

Falsch:

echo _("Sie haben $count neue Nachrichten.");

Auch falsch:

echo _("Sie haben ") . $count . _(" neue Nachrichten.");

Richtig:

printf(_("Sie haben %s neue Nachrichten."), $count);

Die in einen gettext() eingeschlossenen Strings sollten vollständige Sätze bzw. Informationsblöcke enthalten, also kein Zusammenstückeln aus einzelnen Teilstrings (siehe oben).

Schliessen sich die beiden vorangegangenen Vorschriften gegenseitig aus, weil z.B. ein Teil eines Satzes formatiert wird, so hat die letztere Regel Vorrang (der Übersetzer braucht sowieso html-Grundlagenkenntnisse.

Falsch:

echo _("Sie können diese Datei ") . "<b>" . _("nicht") . "</b>" . _(" löschen");

Richtig:

echo _("Sie können diese Datei <b>nicht</b> löschen");

Komplizierte html-Ausdrücke, wie z.B. ein klickbares Icon im Text sollten dagegen via %s aus dem String herausgezogen werden

Richtig:

printf(_("Unter %s gelangen Sie zu Ihren Terminen."), "<a href><img src = \"pictures/icon-lit.gif\"></a>");

Text-Buttons

Beschriftete und damit zu übersetzende Formular-Buttons werden generell nicht direkt in den Code eingebunden, sondern immer über die Funktion "makeButton()" erzeugt, diese kümmert sich dann um die Lokalisierung.

CVS/SVN-Nutzung

Ergänzen Sie das $Id$-CVS/SVN-Schlüsselwort in jeder Datei.

E_STRICT-kompatibler Code

Jeder Code muss E_STRICT-kompatibel sein. Das heisst, er darf keine Fehler oder Warnungen erzeugen, wenn das Fehler-Reporting von PHP auf E_STRICT eingestellt ist.

Die Entwicklung existierender Packages, die dieser Konvention noch nicht entsprechen, müssen dies auch noch nicht.

Fehlerbehandlung

Mit PHP 5 ist es nun möglich die Fehlerbehandlung vom eigentlichen Programmfluss zu trennen. Dies hat große Vorteile für das Debugging und die Wartbarkeit und verbessert darüberhinaus die Lesbarkeit des Quellcodes.

Da Fehlercodes als Rückgabewerte oft sehr kryptisch sind und den Programmfluss komplizierter machen, sind diese zu vermeiden.

Genaueres über gute Fehlerbehandlung ist dem Abschnitt über Fehlerbehandlung in diesem Coding Standard zu entnehmen.

Letzte Änderung am 20.04.2010 17:59 Uhr von mriehe.