1. Programmierrichtlinien / Coding Style Guides

    Stefan · 15.09.08, 16:46 Uhr · Programmierstil · Tags: , ,

    Heute ist der Zeitpunkt gekommen, unsere Coding Styleguides für unsere Projekte neu anzupassen und neu zu definieren. Im Laufe der Zeit und mit der Anzahl der Projekte kamen immer neue Anforderungen auf uns zu, so dass ich heute die Styles mal wieder aktualisiert und vereinheitlicht habe.
    Wen es interessiert, dem habe ich den Styleguide hier reingepostet:

    Grundsätzliches

    • Einrückungen nur per Leerzeichen
    • Tabulatoren 4 Zeichen, als Leerzeichen
    • Kein schließendes ?> am Ende der Datei
    • Standard Encoding: UTF-8
    • Kommentare für PHPdoc
    • Klassen > 1000 Zeilen möglichst refactoren
    • Möglichst Nutzung von Klassen statt Funktionen

    Bitte um Einhaltung dieser Richtlinien, um automatisierte Tests (CodeSniffer) laufen zu lassen. So führt z.B. jedes falsch geschriebene if-Statement zu Fehlermeldungen.

    Schreibweise Operatoren/Bedingungen/Klassen

    Operatoren

    Alle Operatoren werden mit einem Leerzeichen zwischen den Werten geschrieben:

    $foo = $bar + $baz;
    $foo = 'foo';
    $foo = 'bar' . 'baz';
    $foo.= 'bar';

    Bedingungen, Schleifen, Funktionen, Klassen

    Abfrage-, Schleifenbedingungen und Funktions-/Klassen-Übergabeparameter werden sofort nach der öffnenden runden Klammer ohne Leerzeichen davor/danach geschrieben. Die geschweifte Klammer wird bei Funktionen/Methoden/Klassen in eine neue Zeile gesetzt, bei Schleifen, Bedingungen, Switches etc. mit einem Leerzeichen getrennt, hinter die schließende runde Klammer der Schleifenbedingung gesetzt.
    Der Inhalt danach wird mit einen Tabulatorschritt eingerückt.

    Bei Funktionen/Methoden wird die runde Klammer direkt an den Funktions-/Methodennamen geschrieben, bei Bedingungen, Schleifen, Switches etc. wird die runde Klammer mit einem Leerzeichen vom Schlüsselwort abgetrennt:

    if ($foo > $bar) {
        // do anything
    }
    
    foreach ($array as $key => $val) {
       print $val;
    }
    
    function myFunction($foo, $bar = null) 
    {
        // do anything
    }
    
    class My_Class 
    {
        public function myMethod($foo)
        {
            return $foo;
        }
    }
    
    $class = myClass::myMethod($parameter);

    Namenskonventionen

    Die Namenskonventionen gelten für alle Namen, Variablenbezeichner etc. – Programmier-/Scriptsprachenübergreifend:

    • Immer in Englisch
    • CamelCased, klein geschrieben beginnend:
      myFunction, $article, $companyName, <lastModified>
    • Konstanten werden in Versalien geschrieben, mit _ als logischen Trenner im Namensraum:
      METHOD_GET, DB_NAME, DEBUG
    • Sprechende Namen, allerdings nicht zu Lang (Bezeichner sollten im Idealfall 32 Zeichen nicht übersteigen)
    • Es wird kein Zusatz vor Variablennamen geschrieben, was für ein Inhalt sich in der Variablen befindet:
      Falsch:
      $intArticleId = 1;
      $oArticle = new Article();

      Richtig:
      $articleId = 1;
      $article = new Article();

    Variablen

    • Variablen werden im Typ nicht geändert! Also z.B. einer String-Variable wird später kein Integer Wert zugewiesen!
    • In assoziativen Arrays werden die Bezeichner grundsätzlich in einfachen Anführungszeichen geschrieben
    • Text-Strings werden immer mit einfachen Anführungszeichen geschrieben
    • Userübergebenen Integer-Werten werden in MySQL-Queries immer (int) vorangestellt, um die Konvertierung sicherzustellen, im Idealfall mit PDO oder mysqli mit Bindings arbeiten.
      'SELECT foo FROM bar WHERE baz = ' . (int)$value
    • Es werden keine Variablen einfach in Strings geschrieben, sondern immer verkettet:
      Falsch: "hallo $username"
      Richtig: 'hallo ' . $username
    • String-Verkettungen werden immer mit einem Leerzeichen vor und nach dem Punkt geschrieben

    Konstanten

    • Wichtige Konstanten werden auch als solche definiert! Je nach Projekt können das sein:
      • Datenbankbezeichner
      • Tabellennamen
      • Datenbankprefixe
      • Globale Systemeinstellungen
      • Debug-Einstellungen
      • Feste, zu includierende Dateien/Dateinamen des Scriptes
      • Verzeichnispfade
    • Konstantenbezeichner enthalten grundsätzlich an erster Stelle den Typ des Inhaltes
      • PATH_ (Jeder fest vorgeschrieben Pfad)
      • FILE_ (Jede Datei)
      • TAB_ (Tabellennamen)
      • DB_ (Datenbankwerte wie User, Prefix, Host, Passwort und Name)
    • Konstantenbezeichner-Namensräume sind grundsätzlich durch _ zu trennen:
      • FILE_USER_VIEWPROFILE (Dateiname für Benutzerprofil)
      • TAB_USER (Tabellenname user)

    Funktionen

    • Jeder Funktion ist ein aussagekräftiger Kommentar im PHPdoc Format voranzustellen (siehe Kommentare)
    • Funktionen enthalten wie alles andere auch aussagekräftige Namen (siehe Namenskonventionen)
    • Globals werden sparsam bis gar nicht benutzt, wenn überhaupt genutzt, dann Schreibweise mit der Superglobal $GLOBALS['name']
    • Alle notwendigen Werte werden als Parameter an die Funktion übergeben
    • Eine Funktion sollte möglichst immer etwas über return zurück geben
    • Werden einer Funktion/Methode falsche Parameter übergeben, wird eine Exception geworfen, statt z.B. return false. Somit kann man Fehler besser eingrenzen.
    • Geschweifte Klammern immer in einer neuen Zeile (siehe Schreibweise Operatoren)

    Beispiele für Funktionsnamen:

    /**
     * Plausibility check for filenames
     *
     * @param string $filename filename to check
     * @return boolean success 
     */
    function isValidFile($filename)
    {
        // do something
    }
    
    function getWebSafeFilename($filename)
    {
        // do something
    }
    
    function createUrl($url, $arguments = Array())
    {
        // do something
    }

    Klassen

    • Klassennamen werden grundsätzlich in Englisch gehalten (siehe Namenskonventionen)
    • Klassen enthalten wie alles andere auch aussagekräftige Namen (siehe Namenskonventionen)
    • Jeder Klasse ist ein aussagekräftiger PHPdoc Kommentar voranzustellen (siehe Kommentare)
    • Jede Klasse liegt in einer eigenen Datei
    • Bei Klassennamen wird der erste Buchtabe jedes Bereiches immer groß geschrieben
    • Klassennamen enthalten die Pfadstruktur des Bibliothekverzeichnisstruktur:
      Burda_Oci_Article, Zend_Db_Table, Burda_Webservice_Rest_Client, Article
    • Klassen werden im PHP5-Stil geschrieben, dementsprechend ist immer der Geltungsbereich einer Methode oder Variable anzugeben (public, private, protected, static)
    • Private oder protected Methoden/Eigenschaften beginnen immer mit einem _:
      private $_property;
      private static function _customMethod()
    • Klassen-Properties werden genauso wie Methoden oder der Klasse selbst, korrekte Kommentare im PHPdoc Stil hinzugefügt (siehe Kommentare)

    HTML-Tags/Formulare in PHP-Scripten

    • Prinzipiell keine hardcoded HTML Codes in einzelnen Klassen oder Funktionen, die nicht mit der Generierung selbiger zu tun haben! Nach Möglichkeit immer eine Templateengine wie Smarty nutzen, um Logik von Design zu trennen
    • Formularfelder von HTML-Forms, Links etc. werden durch Klassen und Funktionen generiert, z.B. Zend_Form oder ähnliche freien Scriptbibliotheken
    • Wir verwenden ausschließlich XHTML, daher gelten die XHTML-Bestimmungen

    XML

    • Die Generierung von XML wird in Klassen nach Möglichkeit über DomDocument gelöst, XML wird immer im UTF-8 Encoding gespeichert.
    • Zusammengesetzte XML-Elemente werden CamelCase geschrieben:
      <lastModified> oder <publisherUri>

    URIs

    • Keine Verwendung von handgeschriebenen URIs
    • Alle URIs werden nach Möglichkeit über einen im MVC befindlichen Controller mit den zur Verfügung stehenden Hilfsmitteln oder aber durch entsprechende Klassen/Funktionen zur Erzeugung einer korrekten URI generiert. Die Ziele werden als entsprechende Parameter übergeben. Notwendig wird dies duch eine optionale (und bevorzugte) Verwendung von „sprechenden URIs“ die durch ModRewrite interpretiert werden können.

    MySQL-Queries

    • Nach Möglichkeit Nutzung von mysqli oder besser PDO bzw. die darauf aufsetzenden DB Funktionen entsprechender PHP Frameworks (wie z.B. Zend_Db). Aus Sicherheitsgründen nutzen wir keine normalen mysql-Funktionen mehr, es sei denn es wird kein PHP5 unterstützt.
    • Nutzung mysqli: Queries durch mysqli::prepare() und mysqli::bind_param() aufbauen
    • Nutzung PDO: Queries durch PDO::prepare() und PDO::execute() ausführen
    • Nutzung PHP4: Bei PHP4 werden alle übergebenen Paramater durch mysql_real_escape_string() korrekt maskiert
    • MySQL-Queries werden grundsätzlich immer in einfachen Anführungszeichen geschrieben, wobei MySQL-Interne Befehle grundsätzlich in Versalien geschrieben werden, Datenfelder, Tabellen und Werte grundsätzlich klein.
    • Ergebnisse werden im Idealfall als Objekt zurückgegeben, kann aber je nach Anwendungsfall auch als Array zurückgeliefert werden
    • Projektübergreifend einheitliche Aliase bei Tabellennamen – z.B. immer:
      • Table user => u
      • Table user_permissions => up
      • Table user_groups => ug
    • Möglichst keine SELECT * FROM table Statements nutzen! Alle benötigten Feldnamen werden auch ausgeschrieben, um die Lesbarkeit zu erhöhen
    • Alle Werte in der Query werden in doppelte Anführungszeichen gefasst, falls nicht von Usern übergeben (dann ? oder andere Parameter-Bindings bei PHP5)
    • Alle Ressource-Ergebnisse, mit denen danach gearbeitet werden soll, werden grundsätzlich mit PDOStatement::rowCount, mysqli_stmt::num_rows oder mysql_num_rows auf Inhalte überprüft
    • Die Variablen für MySQL-Queries sind nach Möglichkeit immer sprechend zu schreiben, nicht einfach nur $stmt sondern, wenn mehrere Queries vorhanden sind $stmtUsers

    Kommentare

    • Grundsätzlich arbeiten wir nach dem PHPdoc Schema, um schnellstmöglich auch eine Dokumentation der Dateiinhalte zu erhalten. Die Richtlinien von PHPdoc sind also zwingend einzuhalten.
    • Die Hauptdevise lautet: Lieber einmal zu häufig kommentiert als zu wenig
    • Jede Klassendatei erhält einen Kommentar, in dem die Lizenz, Pakete, Autoren etc. stehen:
    /**
     * Zend Framework
     *
     * LICENSE
     *
     * This source file is subject to the new BSD license that is bundled
     * with this package in the file LICENSE.txt.
     * It is also available through the world-wide-web at this URL:
     * http://framework.zend.com/license/new-bsd
     * If you did not receive a copy of the license and are unable to
     * obtain it through the world-wide-web, please send an email
     * to license@zend.com so we can send you a copy immediately.
     *
     * @category   Zend
     * @package    Zend_Db
     * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
     * @license    http://framework.zend.com/license/new-bsd     New BSD License
     */
    • Trennungen Einzelbereiche bei PHPdoc erfolgen mit jeweils einem Leerzeichen nach dem längsten Element – alle anderen Elemente richten sich nach diesen Elementen:
     * @param string $filename   filename for linkage
     * @param array  $parameters parameter to append
    Kommentare vor Klassen

    Jeder Klasse wird unabhängig vom Dateikommentar ein PHPdoc Kommentar wie folgt vorangestellt, der die Klasse näher erläutert. Folgende PHPdoc Elemente sind zwingend:

    • category
    • package
    • copyright
    • licence
    /**
     * @category   Burda_Webservice
     * @package    Burda_Webservice_Rest
     * @subpackage Client
     * @copyright  2008 Hubert Burda Media, Marketing & Communications GmbH (http://www.burda.com)
     * @license    Closed Source, All Rights Reserved
     */
    Kommentare vor Klassen-Eigenschaften

    Wenn in einer Klasse Eigenschaften definiert werden, so müssen diese ebenfalls einen PHPdoc-Kommentar erhalten. Zwingend ist das PHPdoc-Element var:

    /**
     * Valid request methods
     * @var array
     */
    protected $_methods = array(
        Zend_Http_Client::GET,
        Zend_Http_Client::POST,
    );
    Kommentare vor Funktionen/Klassen-Methoden

    Jede Funktion oder Klassenmethode bekommt einen Kommentar! Auch simple Methoden wie Constructor, Getter und Setter müssen definiert sein, damit eine korrekte automatische Erkennung möglich wird. Folgende PHPdoc-Elemente sind zwingend:

    • Kurzbeschreibung
    • Param
    • Return (Wird nichts zurückgegeben, so muss bei return void stehen)
    /**
     * Send a REST Request
     *
     * @param string $method  request method
     * @param string $path    path for request
     * @param mixed  $data    given data for request
     * @param mixed  $headers additional headers (authorization etc)
     * @return Zend_Http_Response
     */
    public function request($method, $path = '/', $data = null, $headers = null)
    {
    • Einzeilige Kommentare in Funktionen oder Methoden werden mit // eingeleitet, mehrzeilige Kommentare werden mit /* und */ eingefasst
    • Bei größeren Logikmodifikationen und anderen wichtigen Änderungen immer eine Kommentarzeile mit dem Namen oder Initialen des Autors der Modifikation und dem aktuellen Datum hinzufügen:
    /* bug fix user permissions - SSE 080624 */
        // do something
    /* end bug fix user permissions */

    Fehlermeldungen

    Durch Nutzung von PHP5 verwenden wir möglichst oft, bei kritischen Codes immer, try-catch-Blöcke, die im Idealfall Modul-/Featureweit eigene Exceptions werfen.

    Durch Nutzung solcher Exceptions ist ein besseres Logging und Error-Tracking möglich. Im Idealfall werden Fehler klassifiziert um nach schwere des Fehlers anders reagieren zu können (Kritisch, Warnung, Hinweis)

    CSS

    Erstellung von CSS sollte möglichst speichersparend geschehen. Wichtige Regeln sind:

    • Möglichst wenige Ids, Klassen im HTML-Quellcode
    • Allgemeine Regeln ganz an den Anfang setzen
    • Vererbung von CSS-Stilen unbedingt nutzen
    • Möglichst Speichersparend schreiben, z.B. keine unnötigen Zeilenumbrüche oder Leerzeichen
    • Alle Statements pro Auszeichnung in eine Zeile setzen, nicht jede Eigenschaft in eine Zeile:
      Falsch:
      element {
      color:#f60;
      font-weight:12px;
      padding-top:5px;
      }

      Richtig:
      #element{color:#f60;font-weight:12px;padding-top:5px;}

    • Elemente möglichst durch HTML-Tags identifizieren:
      body#articles div ul li {}
    • Möglichst kurze Schreibweisen für Statements finden:
      Falsch:
      #element {
      padding-top:5px;
      padding-left:10px;
      padding-right:20px;
      padding-bottom:10px;
      }

      Richtig:
      #element{padding:5px 20px 10px 10px;}

    • Sinnvoll nach Seitenbereichen gruppieren und über jede Gruppe einen kurzen Kommentar
    • Möglichst immer Body-Klassen nutzen, um vom Body abwärts zu vererben: Ziel: möglichst wenige Ids oder Klassen zu nutzen. So sollte jede Seitenart eine eigene Klasse im Body bekommen (z.B. article, profile, overview etc.).
    • Klassen wiederverwenden und abstrahieren. Wenn z.B. Boxen in einer Spalte genutzt werden, so kann man jeder Box eine Klasse box geben und zusätzlich eine weitere Klasse für Detailinformationen: z.B: <div class="box about">. Im Idealfall wird der kompletten Spalte eine Id gegeben, so dass man den Container der Boxen kennt, um dann den Boxen nur noch Klassen oder Ids mit den Detailinformationen, die sich vom Standard unterscheiden, zu geben.
  2. Kommentare

    1. Flip · 27.11.08, 17:09 Uhr

      Coole Richtlinien!
      Werde ich mal berücksichtigen in meinen Projekten ;) !

      gruß Flip

  3. Kommentar schreiben

    XHTML: Du kannst diese Tags nutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Gehe zur polyCODER Startseite