Projekt

Allgemein

Profil

Coding Guidelines

Globale Programmierrichtlinen

  • Die Sprache für Bezeichner ist Englisch
  • Code muss in jeder unterstützen Umgebung laufen (Min.- und Max.-PHP, -MySQL beachten)
  • Alle Bezeichner werden aussagekräftig und eindeutig definiert
  • Auf keinen Fall Abkürzungen verwenden, die zweideutig sein können
  • Bezeichner einer Klasse werden mit Großbuchstaben voneinander getrennt (UpperCamelCase)
  • Keine magischen Zahlen
  • Variablen in for-Zählschleifen werden mit einem Buchstaben definiert
  • Code, der nicht benutzt wird, muss gelöscht werden
  • Das letzte Element eines Arrays darf nicht mit einem Komma enden
  • Nutzung von Gettern und Settern:
    • Getter (get<Variablenname>) sollten stets den unveränderten Inhalt der Klassenvariablen zurückgeben. Getter, die den Inhalt manipulieren, sollten namentlich nicht direkt vom Variablennamen abgeleitet sein (also z. B. getFormated<Variablenname>).
    • Setter (set<Variablenname>) sollten eine Validierung des übergebenen Wertes durchführen.
    • Innerhalb von Klassen sollten die Klasseneigenen Getter- und Setter-Methoden nicht genutzt werden, sondern direkt auf die Klassenvariablen zugegriffen werden. Ausnahme: Bei der Nutzung von Daten aus nicht refaktorierten Quellen (z.B. globale Variablen) darf innerhalb einer Klasse ein eigener Setter genutzt werden, um solche Variablen vor dem Setzen zu validieren.
  • AJAX-Response vom Server an den Client sollte möglichst im JSON-Format sein DRAFT: { 'success': true, 'payload' => data 'message' => 'messge' }
  • Dateinamen sind klein zu schreiben, es sei denn, es handelt sich um eine Klasse. Dann heißt die Datei wie die Klasse.
  • Bei neu erstellten Ordnern muss eine leere index.html Datei angelegt werden, damit der Ordner nicht aufrufbar ist. Sofern möglich auch einen .htaccess-Schutz für Ordner nutzen
  • Don't trust user input. Daten von außen sind zu valdieren und Fehlerfälle abzufangen.
  • Kommentare müssen aussagekräftig sein. Nicht etwa //START und //END
  • Alle Schlüsselwörter werden klein geschrieben, z. B. ''if, for, foreach, as, while''
  • Strings werden in einfachen Anführungszeichen ' geschrieben (Außnahme JSON, dort doppeltes Anführungszeichen vorgeschrieben sind)
  • ternäre Ausdrücke sind, sofern leserlich, erlaubt
  • Statement-Rümpfe sind in geschweifte Klammern zu setzen (auch einzeilige!)
  • Immer typsichere Vergleiche verwenden (=== oder !==). Ausnahme: Werte die unterschiedliche false-Werte enthalten können (z.B. wenn sowohl „null“ als auch „0“ als „false“ gewertet werden soll. Dann kann eine if-Bedingung wie folgt geschrieben werden: if(abc){...}
  • Als Default-False-Wert bei single-select-Feldern sollte „-1“ verwendet werden, sofern dies kein valider Wert für einen Datensatz ist.
  • Auf deprecated-Funktionen verzichten

Dokumentation

  • Die Sprache für Kommentare ist Englisch

PHP Programmierrichtlinen

  • Benennung von Variablen und Funktionen erfolgt in lowerCamelCase-Notation
  • Konstanten werden in Großbuchstaben defniert
  • es wird E_NOTICE-, E_STRICT- und E_DEPRECATED-sicher programmiert (während des Programmierens zu aktivieren mittels error_reporting(E_ALL); am Anfang des Scripts). Dabei gelten Meldungen aus der höchsten PHP-Version, die wir unterstützen
  • PHP-Short-Tags sind nicht erlaubt: <?php statt <?
  • Keinen schließenden PHP-Tag ?> in reinen PHP-Dateien, die keine Ausgabe erzeugen.
  • Globale Variablen sind verboten
  • Dateien, die PHP-Code enthalten, haben die Dateiendung .php
  • includete Dateien haben die Dateiendung .inc.php und liegen niemals im Haupt- oder admin-Verzeichnis
  • Funktionen gehören in den inc, nicht in den gm/inc-Ordner
  • Klassen gehören in den passenden system/GXEngine-Unterordner, nicht in den gm/classes-Ordner
  • ein xtc_db_fetch_array(), das nicht in einer while-Schleife ist, wird erst ausgeführt, wenn sichergestellt wurde, dass das result ein Ergebnis geliefert hat (xtc_db_num_rows() bietet sich da an).
  • kein exit oder die() ohne vorheriges Schließen der Datenbankverbindung (xtc_db_close())
  • jede PHP-Datei hat einen Gambio-GPL-Header
  • Dateien, wie z. B. Log-Dateien, die sensible Daten enthalten und von außen erreichbar sind, sind mit einem Token im Namen zu schützen (Token generieren mittels LogControl::get_secure_token())
  • Texte gehören in die Datenbank/Sprachdateien => keine hardgecodete Texte!!!
  • Leerzeichen in Datei- und Ordnernamen sind nicht erlaubt => erlaubte Zeichen sind a-Z, 0-9, -, _, .
  • Dateien, die Klassen oder Funktionen enthalten, sind mittels require_once oder include_once einzubinden => require und include sind Tabu!
  • Öffnende, geschweifte Klammern gehören in eine eigene Zeile
  • Beim Casten kommt zwischen Datentyp und Variable kein Leerzeichen

Dokumentation

  • PHPDoc ist Pflicht

Legacy-Code

  • Globale Variablen sollten in Funktionen/Methoden nicht genutzt werden, sondern stattdessen als Klassenvariable oder Parameter übergeben werden. Führt kein Weg drum herum, sollte das $GLOBALS-Array zum Ansprechen der Variable verwendet werden

Regeln aus "Objektorientierte Programmierung" von thePHP.cc, die wir so für neue Projekte übernehmen

Regel: Eine Bildschirmseite
Eine Methode darf nicht länger als eine Bildschirmseite sein. Längere Methoden müs-
sen in mehrere kleinere Methoden heruntergebrochen werden.

Regel: Kleine öffentliche APIs
Die öffentliche API einer Klasse ist immer so klein wie möglich. Methoden sind stan-
dardmäßig privat/protected und werden nur dann öffentlich gemacht, wenn ihre Funktionalität
auch tatsächlich außerhalb der Klasse benötigt wird.

Regel: Deklarierte Instanzvariablen
Alle Instanzvariablen werden am Beginn der Klasse deklariert.

Regel: Minimale Sichtbarkeit
Attribute sind immer privat/protected. Es gibt keine öffentlichen Attribute.

Regel: Keine echte Arbeit im Konstruktor
Im Konstruktor werden Objekte in einen sinnvollen Ausgangszustand versetzt. Es fin-
det keine produktive Arbeit statt, insbesondere wird nicht auf das Dateisystem oder
auf externe Prozesse oder Systeme zugegriffen.

Regel: Dokumentierte APIs
Die API jeder Klasse wird immer mit DocBlocks kommentiert, die neben einer @return-
Annotation für jeden Parameter eine @param-Annotation enthalten.

Regel: Type Hints
Für Arrays und Objekte als Methoden- und Konstruktorparameter werden immer Type
Hints verwendet.

Regel: Code-Duplikation vermeiden
Code-Duplikation wird vermieden, indem Funktionalität an ein kollaborierendes Ob-
jekt delegiert wird.

Regel: Interfaces dokumentieren
Jede in einem Interface definierte Methode wird mit DocBlocks kommentiert, die ne-
ben einer @return-Annotation für jeden Parameter eine @param-Annotation enthal-
ten.

Regel: Interfaces als Type Hints
Anstelle Klassen als Type Hints zu verwenden, definieren Sie ein Interface, das die auf-
zurufenden Methoden enthält, und verwenden dieses als Type Hint.

Regel: Durchgängig Autoload
Klassen werden immer per Autoload geladen. Ein Autoloader sucht nicht, sondern
weiß bereits, aus welchen Dateien der benötigte Code zu laden ist.

Regel: Dependency Injection
Alle Abhängigkeiten eines Objektes werden in der API explizit gemacht und mittels
Dependency Injection an die Objekte übergeben.

Regel: Pflichtabhängigkeiten als Konstruktorparameter
Diejenigen Abhängigkeiten, die ein Objekt immer benötigt, werden zu Konstruktorpa-
rametern.

Regel: Komposition statt Vererbung
Vererbung kommt zur Wiederverwendung von Code nur im Rahmen einer ”ist-ein”-
Beziehung zum Einsatz. Ansonsten ist Objektkomposition (kollaborierende Objekte)
der Vererbung vorzuziehen.

Regel: Sinnvolle Rückgabewerte oder Exception
Rückgabewerte müssen verlässlich sein. Wenn Code keinen sinnvollen Rückgabewert
liefern kann, dann muss er eine Exception werfen.

Regel: Fehlerfortpflanzung vermeiden
Rückgabewerte von Code, der keine Exceptions verwendet, müssen frühzeitig und
möglichst strikt geprüft werden, um Fehlerfortpflanzung zu vermeiden.

Regel: Spezifische Exceptions
Exceptions müssen durch Subklassenbildung oder Exception-Codes spezifisch genug
sein, dass der aufrufende Code den Fehler sinnvoll verabeiten kann.

Regel: Benachrichtigungen und Warnungen sind Fehler
Programme dürfen keinerlei Fehlermeldungen, Warnungen oder Benachrichtigungen
der Typen E_NOTICE, E_USER_NOTICE, E_WARNING, E_USER_WARNING, E_USER_ERROR,
E_STRICT, E_DEPRECATED und E_USER_DEPRECATED erzeugen.

Regel: Wertobjekte sind unveränderlich
Wertobjekte können nach Initialisierung durch den Konstruktor nicht mehr verändert
werden.

Regel: Keine Arbeit im Destruktor
In Destruktoren wird niemals produktive Arbeit erledigt.

Regel: Explizite APIs
Explizite APIs sind impliziten APIs vorzuziehen.

Regel: Keine Singletons
Es gibt in PHP keinen validen Anwendungsfall für Singletons. Ihre Verwendung ist da-
her verboten.

SQL Programmierrichtlinen

  • SQL-Befehle werden groß geschrieben
  • INSERT-Anweisungen müssen die einzelnen Spalten für die VALUES-Klausel enthalten (am besten die SET name = value, id = zahl Schreibweise nutzen)
  • SQL-Befehle werden erst in einem String gespeichert, bevor sie ausgeführt werden
  • Schlüsselworte (z. B. ''SELECT, AS, FROM, JOIN, WHERE, GROUP BY, ORDER BY, HAVING, LIMIT'') oder MySQL-Funktionen (z. B. ''NOW(), SUM(), IF'') werden groß geschrieben
  • Zeilenumbrüche in SQL-Befehlen nach jeder angesprochenen Spalte und jedem Schlüsselwort
  • Tabellenkonstanten müssen nicht mehr verwendet werden, da dies nicht konsequent im Shop angewendet wurde und somit der Nutzen nicht mehr gegeben ist
  • keine Variable kommt ungeprüft/-filtert in einem SQL-Befehl
  • Die Bezeichnung des Primärschlüssels ist im Singular und heißt, falls es sich um eine ID (Integer, i.d.R. auto_increment) handelt, meist id (kein Tabellennamen-Präfix).
  • Spaltenbezeichnungen sind möglichst kurz zu halten, also date statt my_table_date, Abkürzungen, wie prd, grp sind aber zu vermeiden

JavaScript Programmierrichtlinen

  • Benennung von Variablen und Funktionen erfolgen in der lowerCamelCase-Schreibweise
  • Konstanten sollten nicht verwendet werden (keine zuverlässige Browserunterstützung)
  • kein SQL in JavaScript
  • Wenn möglich "name" & "value" von form-Feldern keine Tabellen- oder Spaltennamen der Datenbank zuweisen
  • Es dürfen, bis auf für Funktions- oder Variablen-Sammlungen, welche die komplette Seite betreffen, keine globalen Variablen verwendet werden. Im Ausnahmefall ist eine Sammlung in Form eines JSONs zu verwenden, so dass das windows-Objekt möglichst klein bleibt.
  • jede JS-Datei hat einen Gambio-GPL-Header
  • JavaScripte sind sowohl komprimiert, als auch unkomprimiert auszuliefern (s. Javascript-Kompression)
  • AJAX-Schnittstellen müssen wie REST-konforme Webdienste implementiert werden => Daten lesen per GET, Daten schreiben per POST (Achtung: Manche IE-Versionen verwenden bei GET den Browser-Cache! JQuery "cache: false" nutzen). Das bedeutet auch, dass in einer POST-Antwort keine Daten landen, die zur Anzeige gebracht werden. Hierfür ist ein weiterer GET-Request notwendig. Rückgabewerte von POST-Requests (evtl. auch PUT, DELETE) werden über den Header übertragen, als Debug-Funktion auch als JSON
  • Texte gehören in die Sprachdateien => keine hardgecodete Texte!!!
  • Leerzeichen in Datei- und Ordnernamen sind nicht erlaubt => erlaubte Zeichen sind a-Z, 0-9, _
  • Öffnende Klammern gehören in dieselbe Zeile, wie das Statement
  • Wertzuweisungen mittels || sind erlaubt
  • Wenn möglich mit losen Kopplungen arbeiten. Keine Funktionen direkt aufrufen, welche nicht zur Funktionalität der eigentlichen Komponente gehören und deren Existenz nicht sichergestellt ist.
  • „use strict“ ist zu verwenden
  • wenn möglich in Closures arbeiten
  • Zwischen Statement und Signatur, sowie Signatur und öffnender geschweiften Klammer gehört ein Leerzeichen (z. B. if (true) { ...)

Variablen: Prä- und Suffixe

  • $-Präfix für bereits ausgeführte Selektoren (Bsp.: var $body = $(„body“);)
  • Interne Methoden, die nicht direkt von außen erreichbar sind, werden mit einem "_" als Präfix versehen

Beispiel

<?php
/* --------------------------------------------------------------
   MySampleClass.inc.php 2015-02-17 gm
   Gambio GmbH
   http://www.gambio.de
   Copyright (c) 2015 Gambio GmbH
   Released under the GNU General Public License (Version 2)
   [http://www.gnu.org/licenses/gpl-2.0.html]
   --------------------------------------------------------------
*/


/**
 * Class MySampleClass
 */
class MySampleClass
{
    /**
     * @var array
     */
    protected $multiselectArray = array();

    /**
     * @var xtcPrice
     */
    protected $xtcPrice;

    /**
     * @var string
     */
    protected $type;


    /**
     * @param array    $multiselectArray
     * @param xtcPrice $xtcPrice
     */
    public function __construct(array $multiselectArray, xtcPrice $xtcPrice)
    {
        $this->multiselectArray = $multiselectArray;
        $this->xtcPrice         = $xtcPrice;
        $this->type             = 'test';
    }


    /**
     * @param array $multiselectArray
     */
    public function setMultiselectArray(array $multiselectArray)
    {
        foreach($multiselectArray as $key => $id)
        {
            $this->multiselectArray[$key] = (int)$id;
        }
    }


    /**
     * execute random sql query build in MySampleClass::_getSampleQuery()
     */
    public function executeSampleQuery()
    {
        xtc_db_query($this->_getSampleQuery());
    }


    /**
     * @return string
     */
    protected function _getSampleQuery()
    {
        $query = 'UPDATE test 
                    SET
                            text = "value",
                            nummer = 1
                    WHERE 
                            id = 2 AND
                            date < NOW()';

        return $query;
    }


    /**
     * @return array
     */
    public function getMultiselectArray()
    {
        return $this->multiselectArray;
    }


    /**
     * @param xtcPrice $xtcPrice
     */
    public function setXtcPrice(xtcPrice $xtcPrice)
    {
        $this->xtcPrice = $xtcPrice;
    }


    /**
     * @return string
     */
    public function getType()
    {
        return $this->type;
    }
}

$mySampleClass    = MainFactory::create_object('MySampleClass', array($_POST['multiselect'], $xtcPrice));
$type             = $mySampleClass->getType();
$multiselectArray = $mySampleClass->getMultiselectArray();
$mySampleClass->executeSampleQuery();

Formatierung von Quellcode

Beispiel

so ziemlich alles falsch:

$t_flag=0;
$t_name = "Max";
$t_text = "\"".MY_TEXT."\" $t_name Mustermann";
$c_number=(double) $_POST["number"];
foreach ( $t_customer_data AS $t_value ) {
    $t_status = ( $t_value=="true" ) ? true : false;
    if( $t_status ) $t_flag = 1;
}
if ( !empty($t_flag) )
    echo "Tada";
if($_POST['truncate'] == '1') xtc_db_query("TRUNCATE table");

korrekt:

$flag = 0;
$name = 'Max';
$text = '"' . MY_TEXT . '" ' . $name . ' Mustermann';
$number = (double)$_POST['number'];

foreach($customerDataArray as $value)
{
    $status = false;

    if($value === 'true')
    {
        $status = true;
    }

    if($status)
    {
        $flag = 1;
    }
}

if(!empty($flag))
{
    echo 'Tada';
}

if(isset($_POST['truncate']) && $_POST['truncate'] === '1')
{
    $sql = 'TRUNCATE table';
    xtc_db_query($sql);
}