phpBB

Development Wiki

Difference between revisions of "Deutsch:Coding guidelines"

From phpBB Development Wiki

m (Reverted edits by GqqFf0 (Talk); changed back to last version by Highway of Life)
m (minor: added forgotten span, should be displayed in ie correctly)
Line 302: Line 302:
 
<php>$bool = (($i < 7) && (($j < 8) || ($k == 4)));</php>
 
<php>$bool = (($i < 7) && (($j < 8) || ($k == 4)));</php>
  
<span style="color: green">// Aber das hier ist noch besser, weil es noch lesbarer ist und trotzdem ist es klar was passiert.
+
<span style="color: green">// Aber das hier ist noch besser, weil es noch lesbarer ist und trotzdem ist es klar was passiert.</span>
 
<php>$bool = ($i < 7 && ($j < 8 || $k == 4));</php>
 
<php>$bool = ($i < 7 && ($j < 8 || $k == 4));</php>
  

Revision as of 20:33, 9 December 2007

Dies ist der Beginn der Übersetzung der Coding Guidelines der Version 1.22

Coding Guidelines

Vorgaben/Voreinstellungen

Editor-Einstellungen

Tabs vs. Leerzeichen Um das Lesen so einfach wie möglich zu machen, werden wir Tabs und keine Leerzeichen verwenden. Wir verwenden 4 (vier) Leerzeichen für ein Tab - deshalb müssen Sie Ihre Tab-Breite im Editor auf 4 Leerzeichen setzen. Stellen Sie sicher, dass, wenn Sie die Datei speichern, er Tabs und keine Leerzeichen speichert. Auf diese Weise kann der Code in der Art angezeigt werden wie wir es wollen, ohne das Layout der wirklichen Dateien zu stören.

Tabs vor in den Zeilen vor dem Code sind kein Problem, aber innerhalb eines Textes kann es zu einem Problem kommen, wenn ihre Einstellungen sich von unseren unterscheiden. Hier ein kurzes Beispiel wie es aussehen sollte:

{TAB}$mode{TAB}{TAB}= request_var('mode''');
{
TAB}$search_id{TAB}= request_var('search_id''');

Wenn mit Tabs eingegeben wird (ersetzen sie {TAB}), müssen beide gleichen Zeichen auf derselben Höhe sein.

Zeilenumbrüche:

Stellen Sie Sicher, dass Ihr Editor Dateien im UNIX-Format speichert. Das bedeutet, dass Zeilen mit einem newline gespeichert werden, nicht mit einer CR/LF Combo, wie unter Win32, oder dem, was auch immer ein Mac benutzt. Jeder anständige Editor sollte diese Einstellung bieten, aber es könnte nicht die Standard-Einstellung sein. Lernen Sie mit ihrem Editor umzugehen. Wenn Sie Rat über Windows-Editor wollen, können Sie einen der Entwickler fragen. Einige von ihnen arbeiten ebenfalls mit Win32.

File Header/Kopfzeilen

Standard Header für neue Dateien:

Diese Vorgabe für den Kopf muss an den Anfang aller phpBB Dateien eingefügt werden:

/**
*
* @package {Paketname}
* @version $Id: $
* @copyright (c) 2006 phpBB Group 
* @license http://opensource.org/licenses/gpl-license.php GNU Public License 
*
*/

Bitte schauen sie in den Abschnitt 'Datei Positionen' um den richtigen Paketnamen zu erfahren.

Dateien, die Code beinhalten:

Für diese Dateien müssen sie einen leeren Kommentar direkt nach dem Kopf/Header einfügen, um zu verhindern, dass automatische Dokumentationsprogramme den Kopfteil als Erläuterung für die ersten Code-Zeilen interpretieren.

/**
* {Kopfteil/Header}
*/

/**
*/
{CODE}

Dateien die nur Funktionen beinhalten:

Vergessen Sie nicht die Funktion zu kommentieren (insbesondere die erste Funktion die auf den Kopf/Header folgt). Jede Funktion sollte zumindest einen Kommentar haben, der erklärt was die Funktion macht. Für komplexere Funktionen wird empfohlen die Parameter ebenfalls zu kommentieren.

Dateien die nur Klassen enthalten:

Vergessen Sie nicht die Klasse zu kommentieren. Klassen benötigen eine separate @package-Definition, es ist die gleiche wie die im Kopfteil/Header. Abgesehen von diesem Sonderfall, gilt das gleiche für die Klassen, sowie deren Methoden wie für Dateien die nur Funktionen beinhalten.

Code der auf den Kopfteil/Header folgt in Dateien die nur Funktionen/Klassen enthalten:

Wenn dieser Fall zutrifft, ist die beste Methode die die Dokumentation vereinfacht, einen Kommentar mit einer ignore Anweisung zu verwenden, als Beispiel:

/**
* {Kopfteil/Header}
*/

/**
* @ignore
*/
Kleiner Codeabschnittmeistens nur ein oder zwei Definitionen oder eine if-Abfrage

/**
* {Dokumentation}
*/
class ...

Datei Positionen

Funktionen die von mehr als einer Seite benutzt wird, gehören in die Datei functions.php, Funktionen die speziell für eine Datei sind sollten in dieser Datei (am Ende) oder in die für den Bereich entsprechende Funktionsdatei. Manche Dateien in dem /includes Ordner sind für spezielle Bereiche zuständig. Zum Beispiel Datei-Uploads, das Anzeigen von etwas, Benutzerspezifische Funktionen und so weiter.

Die folgenden Pakete sind vordefiniert, und dazu passende Features/Funktionen sollten in den erwähnten Dateien/Positionen platziert werden, genauso wie der spezifische Paketname benutzt werden sollte. Die Paketnamen sind fett in der folgenden Liste:


  • phpBB3
Core/Basis Dateien und alle Dateien die nicht in ein separates Paket gehören
  • acm
/includes/acm, /includes/cache.php
Dateien für das Caching
  • acp
/adm, /includes/acp, /includes/functions_admin.php
Administrationsbereich
  • dbal
/includes/db
Abstrakte Datenbankschicht / Database Abstraction Layer.
Basis Klasse ist dbal
  • /includes/db/dbal.php
Basis Datenbank Abstraktions Klasse, definiert die Schnittstelle zur Datenbanken und für alle Datenbanktypen gültiges
  • /includes/db/firebird.php
Firebird/Interbase Datenbank Abstraktion
  • /includes/db/msssql.php
MSSQL Datenbank Abstraktion
  • /includes/db/mssql_odbc.php
MSSQL ODBC Datenbank Abstraktion für MSSQL
  • /includes/db/mysql.php
MySQL Datenbank Abstraktion für MySQL 3.x/4.0.x
  • /includes/db/mysql4.php

::MySQL4 Datenbank Abstraktion für MySQL 4.1.x/5.x

  • /includes/db/mysqli.php
MySQLi Datenbank Abstraktion
  • /includes/db/oracle.php
Oracle Datenbank Abstraktion
  • /includes/db/postgres.php
PostgreSQL Datenbank Abstraktion
  • /includes/db/sqlite.php
Sqlite Datenbank Abstraktion
  • docs
/docs
phpBB Dokumentation
  • images
/images
Alle allgemeinen Bilder, die nicht zu einem Style gehören
  • install
/install
Installationssystem
  • language
/language
Alle Sprachdateien
  • login
/includes/auth
Plugins für den Login und die Authentifizierung
  • VC
/includes/captcha
CAPTCHA
  • mcp
mcp.php, /includes/mcp, report.php
Moderationsbereich
  • ucp
ucp.php, /includes/ucp
Benutzerbereich
  • search
/includes/search, search.php
Suchsystem
  • styles
/styles, style.php
phpBB Styles/Templates/Themes/Imagesets

Code Layout/Guidelines

Bitte denken sie daran, das diese Richtlinien auf alle php, html, javascript und css Dateien angewendet werden sollen

Variablen-/Funktions-Namensgebung

Wir werden keine Form der ungarischen Notation verwenden. Viele von uns glauben das diese Notation eine der verworrensten Techniken die benutzt wird ist.

Variablen Namen:

Variablennamen sollten komplett kleingeschrieben werden, die Wörter durch den Unterstrich getrennt, Beispiel:

$current_user ist richtig, aber $currentuser und $currentUser sind es nicht

Namen sollten beschreibend, aber knapp sein. Wir wollen keine langen Sätze als Variablennamen, aber ein paar Buchstaben extra sind immer besser als sich zu fragen wofür die Variable denn nun verwendet wird.

Schleifen-Zähl-Variablen:

Die einzige Situation wo Variablen aus einem Buchstaben bestehen dürfen sind die Schleifen-Variablen. In diesem Fall sollte die Variable der äußerten Schleife immer $i sein. Wenn Schleifen innerhalb der Schleife sind, sollten deren Variablen $j, gefolgt von $k und so weiter sein. Wenn die Schleifenvariablen schon aussagekräftig sind, sollte diese Regel nicht angewendet werden, Beispiel:

for ($i 0$i $outer_size$i++)
{
   for (
$j 0$j $inner_size$j++)
   {
      
foo($i$j);
   }
}

Funktionsnamen:

Funktionsnamen sollten beschreibend sein. Wir programmieren ja kein C hier, wir wollen keine Funktionen schreiben die "stristr()" heißen. Wieder gilt: Kleinschreibung und Unterstriche als Trennung zwischen den Worten. Funktionen sollten ein Verb im Namen haben. Gute Funktionsnamen sind zum Beispiel print_login_status(), get_user_data(), usw.

Funktionsparameter:

Parameter sind Bestandteil derselben Richtlinien wie Variablennamen. Wir wollten keine Parameter wie do_stuff($a, $b, $c). In den meisten Fällen wollen wir in der Lage sein, zu wissen wie eine Funktion benutzt wird, indem wir auf die Funktionsdeklaration schauen.

Zusammenfassung:

Die grundlegende Philosophie hier ist die Lesbarkeit des Codes nicht zugunsten der Faulheit zu beeinträchtigen. Dies muss mit dem gesunden Menschenverstand gemacht werden, aber; print_login_status_for_a_given_user() ist zu lang, als Beispiel -- diese Funktion sollte besser print_user_login_status()', oder einfach print_login_status() heißen.

Spezielle Namen:

Für alle Emotions/Smilies gilt der Ausdruck smiley im Singular und smilies im Plural.

Code Layout

Immer geschweifte Klammern benutzen:

Dies ist ein anderes Beispiel für die Faulheit zwei extra Zeichen einzugeben, die die Code Lesbarkeit nicht vereinfachen. Selbst in dem Teil von manchen Abschnitten in den nur eine Zeile lang ist, vergesst die geschweiften Klammern nicht. Denkt einfach dran, Beispiel

// These are all wrong.

if (Bedingungdo_stuff();

if (
Bedingung)
    
do_stuff();

while (
Bedingung)
    
do_stuff();

for (
$i 0$i size$i++)
    
do_stuff($i);

// These are all right.

if (Bedingung)
{
    
do_stuff();
}

while (
Bedingung
{
    
do_stuff();
}

for (
$i 0$i size$i++) 
{
    
do_stuff();
}

Wo die geschweiften Klammern hingehören:

Um diese Frage wird häufig gestritten, wir haben es einfach gehalten: Geschweifte Klammern in ihre eigene Zeile, die schließende Klammer dazu sollte immer genau so weit eingerückt sein, Beispiel:

if (Bedingung
{
    while (
Bedingung2)
    {
        ...
    }
}
else 
{
    ...
}

for (
$i 0$i $size$i++) 
{
    ...
}
        
while (
Bedingung
{
    ...
}
        
function 
do_stuff() 
{
    ...
}

Benutzen Sie Leerzeichen zwischen den Ausdrücken/Tokens:

Dies ist ein weiterer, einfacher Schritt um Code ohne große Mühe lesbarer zu halten. Wann auch immer Sie eine Zuweisung, einen Ausdruck, oder ähnliches benutzen... Lassen sie immer ein Leerzeichen zwischen den Tokens. Schreiben Sie den Code immer so als wäre es die Englische(Deutsche) Sprache. Setzen sie Leerzeichen zwischen Namen und Operanden. Benutzen Sie keine Leerzeichen nach öffnenden oder vor schließenden Klammern. Setzen sie keine Leerzeichen vor ein Komma oder Semikolon. Dies kann man am besten an ein paar Beispielen zeigen.

// Jedes Paar zeigt erst die falsche, dann die richtige Schreibweise.''

$i=0;
$i 0;
        
if(
$i<7) ...
if (
$i 7) ...
        
if ( (
$i 7)&&($j 8) ) ...
if (
$i && $j 8) ...
        
do_stuff$i'foo'$b );
do_stuff($i'foo'$b);
        
for(
$i=0$i<$size$i++) ...
for (
$i 0$i $size$i++) ... 
        
$i=($j $size)?0:1;
$i = ($j $size) ? 1;

Operatoren Rangfolge:

Kennen Sie die exakte Rangfolge der Operatoren in PHP? Vermutlich genauso wenig wie ich. Raten Sie nicht. Machen sie es immer mit Klammern deutlich, wie die Reihenfolge aussieht, so dass sie wissen was passiert. Denken Sie daran es nicht zu übertreiben, da es die Lesbarkeit erschweren kann. Grundsätzlich sollten sie nicht jeden einzelnen Ausdruck in Klammern setzen. Beispiel:

// Was ist das Ergebnis? Wer weiß das schon...

$bool = ($i && $j || $k == 4);

// Jetzt können Sie sicher sein, was ich hier mache

$bool = (($i 7) && (($j 8) || ($k == 4)));

// Aber das hier ist noch besser, weil es noch lesbarer ist und trotzdem ist es klar was passiert.

$bool = ($i && ($j || $k == 4));

Strings im Quellcode:

Es gibt 2 verschiedene Wege in PHP Strings zu schreiben - entweder mit einfachen oder doppelten Anführungszeichen. Der Hauptunterschied ist, das der Parser Variablen innerhalb eines Strings mit doppeltem Anführungszeichen ersetzt, bei einfachen Anführungszeichen nicht. Aufgrund dieser Tatsache sollten Sie immer die einfachen Anführungszeichen bevorzugen, wenn sie nicht unbedingt eine Variable innerhalb des Strings verwenden wollen. Mit dieser Methode ersparen wir dem Parser die Arbeit jeden String nach Variablen zu durchsuchen.

Auch wenn sie eine Variable als Teil eines Funktionsaufrufes ist, sollten sie doppelte Anführungszeichen vermeiden. Beachten Sie, das fast alle Maskierungs-/Escape-Verfahren die für doppelte Anführungszeichen existieren nicht mit einfachen Anführungszeichen funktionieren. Seien Sie vorsichtig, und betrachten Sie dieses als Regeln die sie brechen dürfen, wenn die Lesbarkeit des Codes dadurch gefördert wird. Beispiel:

// falsch

$str "";

do_stuff("$str");

// richtig

$str 'Dies ist ein wirklich langer String ohne Variablen die der Parser finden könnte.';

do_stuff($str);

// Manchmal sind einfache Anführungszeichen aber einfach nicht richtig

$post_url $phpbb_root_path 'posting.' $phpEx '?mode=' $mode '&amp;start=' $start;


// Manchmal braucht man doppelte Anführungszeichen um die Zeilen nicht zu sehr mit String-Verknüpfungen zu überladen

$post_url "{$phpbb_root_path}posting.$phpEx?mode=$mode&amp;start=$start";

Bei SQL Anweisungen ist das mischen von einfachen und doppelten Anführungszeichen teilweise erlaubt (Näheres finden Sie in den Richtlinien für die SQL-Formatierungshinweisen), oder es sollte versucht werden nur eine Methode zu nutzen - wenn möglich einfache Anführungszeichen.

Assoziative Array Schlüssel:

In PHP ist es möglich Strings als Schlüssel von assoziativen Arrays ohne Anführungszeichen zu verwenden. Wir wollen das nicht machen -- die Strings sollten immer in Anführungszeichen um Verwirrungen zu vermeiden. Beachten sie das dies nur gilt wenn ausgeschriebene Strings verwendet werden, Beispiel:

// falsch

$foo $assoc_array[blah];

// richtig

$foo $assoc_array['blah'];

// falsch

$foo $assoc_array["$var"];

// richtig

$foo $assoc_array[$var];

Kommentare:

Jeder komplexen Funktion sollte ein Kommentar vorhergehen die dem Programmierer alles erklärt was er braucht um zu wissen wie die Funktion funktioniert. Die Bedeutung jedes Parameters, die erwarteten Werte, und die Rückgabe Werte sind minimale Voraussetzung. Das Verhalten der Funktion in Fehlerfällen (und welche Bedingungen dafür nötig sind) sollte genauso vorhanden sein - aber meist zusammen mit den Rückgabewerten.

Besonders wichtig zu kommentieren sind alle Voraussetzungen die der Code macht, oder Vorbedingungen für die einwandfreie Ausführung. Jeder Entwickler sollte in der Lage sein, jeden Teil der Anwendung anzusehen und in einem angemessenen Zeitraum zu verstehen was in ihm vorgeht.

Vermeiden sie die Verwendung von /* */ Kommentarblöcken für Einzeiler, // sollten für ein/zweizeilige Kommentare verwendet werden.

Magische Nummern:

Benutzen Sie diese nicht. Benutzen Sie Konstanten für alle bestimmten Zeichen, außer wenn der Sinn offensichtlich ist. Grundsätzlich ist es möglich mit der 0 abzufragen ob ein Array 0 Elemente hat. Es ist aber nicht erlaubt Zahlen besondere Bedeutungen zu geben, wenn sie als Zeichen verwendet werden. Dies stört die Lesbarkeit und die Wartbarkeit. Die Konstanten true und false sollten anstelle von 1 und 0 verwendet werden -- auch wenn sie die gleichen Inhalte haben (nicht aber den Typ!), denn mit Konstanten ist es offensichtlich was der Code macht. Wenn nötig casten Sie die Variablen, vertrauen Sie nicht auf den Typ (PHP nimmt es da nicht so genau, was zu Sicherheitsproblemen führen kann wenn der Entwickler nicht sehr genau drauf achtet).

Verkürzte Operatoren:

Der einzige verkürzte Operator der die Lesbarkeit nicht einschränkt, sind das Inkrement $i++ und Dekrement $j--. Diese Operatoren sollten aber nicht als Teil eines Ausdruckes sein. Sie sollten, wann immer möglich in eine eigene Zeile geschrieben werden. Sie innerhalb eines Ausdruckes zu benutzen ist die Kopfschmerzen beim Debuggen nicht wert, Beispiel:

// falsch

$array[++$i] = $j;
$array[$i++] = $k;

// richtig

$i++;
$array[$i] = $j;

$array[$i] = $k;
$i++;

Alternative Kontrollstrukturen:

Alternative Kontrollstrukturen sollten nur bei sehr einfachen Anweisungen verwendet werden. Insbesondere wenn sie für Zuweisungen, und nicht für Funktionsaufrufe oder andere komplexe Anweisungen, genutzt werden. Sie können sich bei falscher Anwendung nachteilig für die Lesbarkeit auswirken, also verwenden Sie diese nicht um ein paar Zeichen einzusparen, Beispiel:

// Schlechte Anwendung

($i $size && $j $size) ? do_stuff($foo) : do_stuff($bar);

// Gute Anwendungsbeispiele

$min = ($i $j) ? $i $j;

Verwenden Sie keine nicht initialisierten Variablen.

Für phpBB3 versuchen wir einen höheren Level von Laufzeitfehlern zu erreichen. Das bedeutet dass das Verwenden von nicht initialisierten Variablen eine Warnung hervorrufen wird. Diese Warnungen können durch die eingebaute Funktion isset() umgangen werden - aber sie sollten besser immer existieren. Um zu prüfen ob ein Array einen Schlüssel hat kann geschickt sein, Beispiel:

// Falsch

if ($forum) ...

// Richtig

if (isset($forum)) ...

// genauso möglich

if (isset($forum) && $forum == 5)

Die Funktion empty() ist praktisch wenn Sie überprüfen wollen ob eine Variable nicht existiert oder leer ist (ein leerer String, 0 als Integer, NULL, false, ein leeres Array oder eine deklarierte aber nicht initialisierte Variable). Folglich sollte empty() benutzt werden. Anstelle von isset($array) && sizeof($array) > 0 kann viel kürzer !empty($array) geschrieben werden.

Switch Anweisungen:

Switch/Case Code-Blöcke können schnell lang werden. Um die Kontrolle zu behalten gelten die Regeln von geschweiften Klammern (welche zur besseren Lesbarkeit jeweils in einer eigenen Zeile sind), auch für die Switch, Case und break-Anweisungen. Ein Beispiel:

// Falsch

switch ($mode)
{
    case 
'mode1':
        
// Irgendwelche Anweisungen
        
break;
    case 
'mode2':
        
// Irgendwelche anderen Anweisungen
        
break;
}

// Richtig

switch ($mode)
{
    case 
'mode1':
        
// Irgendwelche Anweisungen
    
break;

    case 
'mode2':
        
// Irgendwelche anderen Anweisungen
    
break;

    default:
        
//  Gehen Sie immer davon aus das nicht alle Sachen abgedeckt sind
    
break;
}

// Auch richtig, wenn sie mehr Code zwischen dem Case und break haben

switch ($mode)
{
    case 
'mode1':

        
// Irgendwelche Anweisungen

    
break;
    
    case 
'mode2':
    
        
// Irgendwelche anderen Anweisungen

    
break;

    default:

        
//  Gehen Sie immer davon aus das nicht alle Sachen abgedeckt sind

    
break;
}

Selbst wenn der Standardfall nicht benötigt wird, ist es besser diesen zu verwenden - für bessere Lesbarkeit und der Vollständigkeit halber.

Wenn kein break zwischen den Cases vorkommen soll, kommentieren sie es an der Stelle, Beispiel:

// Beispiel ohne break-Anweisung

switch ($mode)
{
    case 
'mode1':
    
        
// Ich mache irgendetwas

    // no break here

    
case 'mode2':

        
// Ich mache irgendetwas anderes

    
break;

    default:

        
// Gehen Sie immer davon aus das nicht alle Sachen abgedeckt sind

    
break;
}

SQL/SQL-Anweisungen

Allgemeine SQL Richtlinien:

Alle SQL-Anweisungen sollten Datenbank übergreifend kompatibel sein, wenn Datenbank spezifische SQL Anweisungen verwendet werden, müssen auch alternative Möglichkeiten geboten werden die mit allen anderen Datenbanken funktionieren (MySQL3/4/5, MSSQL (7.0 und 2000), PostgreSQL (7.0+), Firebird, SQLite, Oracle8, ODBC (generalisiert wenn möglich)).

Alle SQL Anweisungen sollten die Datenbank Abstraktion (DBAL <-DataBase Abstraction Layer) benutzen.

SQL Code Layout:

SQL Anweisungen sind oft unformatiert unlesbar, weil sie manchmal dazu tendieren umfangreich zu sein. Durch das Formatieren von SQL Anweisungen soll die Lesbarkeit stark erhöht werden. SQL Anweisungen sollten auf folgende Weise formatiert werden:

$sql 'SELECT *
<-one tab->FROM ' 
SOME_TABLE '
<-one tab->WHERE a = 1
<-two tabs->AND (b = 2
<-three tabs->OR b = 3)
<-one tab->ORDER BY b'
;
Hier ein Beispiel mit angewendeten Tabs
$sql 'SELECT * 
    FROM ' 
SOME_TABLE 
    WHERE a = 1 
        AND (b = 2 
            OR b = 3) 
    ORDER BY b'
;

SQL Anführungszeichen:

Doppelte Anführungszeichen wo sie benötigt werden (Die Variablen in diesen Beispielen wurden vorher als Integer gecastet) ... Beispiel:

// Falsch

"UPDATE " SOME_TABLE " SET something = something_else WHERE a = $b";

'UPDATE ' SOME_TABLE ' SET something = ' $user_id ' WHERE a = ' $something;

// richtig

'UPDATE ' SOME_TABLE " SET something = something_else WHERE a = $b";

'UPDATE ' SOME_TABLE " SET something = $user_id WHERE a = $something";

In anderen Worten: benutzen Sie einfache Anführungszeichen wo keine Variablen vorkommen. Ansonsten verwenden Sie doppelte Anführungszeichen.

Vermeiden Sie DB spezifisches SQL:

Der ungleich Operator ist in SQL:2003 standardmäßig als "<>" definiert

// falsch

$sql 'SELECT *
    FROM ' 
SOME_TABLE '
    WHERE a != 2'
;

// richtig

$sql 'SELECT *
    FROM ' 
SOME_TABLE '
    WHERE a <> 2'
;

Allgemeine DBAL Methoden:

sql_escape():
Benutzen Sie bei Strings in SQL Anweisungen immer $db->sql_escape() (selbst wenn sie sicher sind, das die Variablen keine einfachen Anführungszeichen enthalten können - vertrauen Sie nie auf ihre Eingaben), Beispiel:
$sql 'SELECT *
    FROM ' 
SOME_TABLE "
    WHERE username = '" 
$db->sql_escape($username) . "'";
sql_query_limit():
Wir fügen keine Grenzen/Limits an die Anweisungen an, aber stattdessen benutzen wir $db->sql_query_limit(). Sie sollten dem Query grundsätzlich die erwartete Zeilenanzahl und den Startpunkt mitgeben.
Achtung: Weil Oracle Limits anders handhabt und es anders implementiert, müssen Sie bei der Verwendung von sql_query_limit() bei einem Ergebnis aus mehreren Tabellen besondere Vorsicht walten lassen.
Stellen Sie sicher wenn wie etwas wie "SELECT x.*, y.jars" das keine Zeile jars in x existiert; stellen Sie sicher das es keine Überschneidungen zwischen impliziten und expliziten Spalten gibt.
sql_build_array():
Wenn sie UPDATE oder INSERT Anweisungen verwenden, benutzen Sie die $db->sql_build_array() Funktion. Diese Funktion escaped/maskiert Strings und überprüft andere Typen, so dass das in diesem Falle nicht mehr nötig ist. Die Daten die als Array hinzugefügt werden sollen gehören in $sql_ary - oder direkt in die Anweisung wenn ein oder zwei Variablen hinzugefügt oder upgedatet werden müssen. Als Beispiel für eine INSERT-Anweisung:
$sql_ary = array(
    
'somedata'        => $my_string,
    
'otherdata'        => $an_int,
    
'moredata'        => $another_int
);

$db->sql_query('INSERT INTO ' SOME_TABLE ' ' $db->sql_build_array('INSERT'$sql_ary));
Um das Beispiel zu vervollständigen, hier ein Beispiel wie eine UPDATE-Anweisung aussehen sollte:
$sql_ary = array(
    
'somedata'        => $my_string,
    
'otherdata'        => $an_int,
    
'moredata'        => $another_int
);

$sql 'UPDATE ' SOME_TABLE 
    SET ' 
$db->sql_build_array('UPDATE'$sql_ary) . '
    WHERE user_id = ' 
. (int) $user_id;
$db->sql_query($sql);
Die $db->sql_build_array() Funktion unterstützt die folgenden Modi: INSERT (Beispiel s.o.), INSERT_SELECT (erstellen einer INSERT INTO table (...) SELECT value, column ... Anweisung), MULTI_INSERT (für die Rückgabe erweiterter INSERT's), UPDATE (Beispiel s.o.) und SELECT (für das bilden von WHERE und AND Anweisungen).
sql_in_set():
Die $db->sql_in_set() Funktion sollte für IN () und NOT IN () Konstrukte verwendet werden. Weil (insbesondere) MySQL dazu tendiert bei nur einem Wert bei = und <> Operatoren schneller zu sein, verwenden wir die DBAL die entscheidet was benutzt wird. Ein typisches Beispiel für eine Suche nach einer Übereinstimmung gegen eine Anzahl von Werten würde Beispielsweise so aussehen:
$sql 'SELECT *
    FROM ' 
FORUMS_TABLE '
    WHERE ' 
$db->sql_in_set('forum_id'$forum_ids);
$db->sql_query($sql);
Basierend auf der Anzahl der Anzahl der Werte der $forum_ids, kann die Anweisung unterschiedlich betrachtet werden.
// SQL Anweisung wenn $forum_ids = array(1, 2, 3);
SELECT FROM phpbb_forums WHERE forum_id IN (123)

// SQL Anweisung wenn $forum_ids = array(1) or $forum_ids = 1
SELECT FROM phpbb_forums WHERE forum_id 1
Natürlich ist es genauso möglich für das Ausschließen einer Anzahl von Werten:
$sql 'SELECT *
    FROM ' 
FORUMS_TABLE '
    WHERE ' 
$db->sql_in_set('forum_id'$forum_idstrue);
$db->sql_query($sql);
Basierend auf der Anzahl der Anzahl der Werte in $forum_ids, kann die Anweisung hier auch anders aussehen:
// SQL Anweisungen wenn $forum_ids = array(1, 2, 3);
SELECT FROM phpbb_forums WHERE forum_id NOT IN (123)

// SQL Anweisung wenn $forum_ids = array(1) or $forum_ids = 1
SELECT FROM phpbb_forums WHERE forum_id <> 1
Wenn das gegebene Array leer ist wird ein Fehler produziert.
sql_build_query():
Die $db->sql_build_query() Funktion ist verantwortlich für das erstellen von sql-Anweisungen bei SELECT, SELECT DISTINCT, wenn benötigt JOIN für mehr als eine Tabelle oder bei Ergebnissen von mehr als einer Tabelle während der Benutzung von JOIN. Es muss benutzt werden um sicherzugehen das die resultierende Anweisung auf allen unterstützten Datenbanken funktioniert. Anstelle von Beispielen für jeden nur denkbaren Fall will ich nur ein kurzes Beispiel geben:
$sql_array = array(
    
'SELECT'    => 'f.*, ft.mark_time',

    
'FROM'        => array(
        
FORUMS_WATCH_TABLE    => 'fw',
        
FORUMS_TABLE        => 'f'
    
),

    
'LEFT_JOIN'    => array(
        array(
            
'FROM'    => array(FORUMS_TRACK_TABLE => 'ft'),
            
'ON'    => 'ft.user_id = ' $user->data['user_id'] . ' AND ft.forum_id = f.forum_id'
        
)
    ),

    
'WHERE'        => 'fw.user_id = ' $user->data['user_id'] . 
        AND f.forum_id = fw.forum_id'
,

    
'ORDER_BY'    => 'left_id'
);

$sql $db->sql_build_query('SELECT'$sql_array);
der optionale, erste Parameter bei sql_build_query() ist SELECT oder SELECT_DISTINCT. Wie Sie sehen können, ist die Logik selbsterklärend. Um LEFT_JOIN zu verwenden, fügen Sie beispielsweise einfach ein weiteres Arras hinzu. Der zusätzliche Nutzen beim Benutzen dieses Konstrukts ist, dass Sie in der Lage sind Anweisungen abhängig von Bedingungen zu erstellen - als Beispiel wenn LEFT JOIN nur bei aktiviertem Topic-Tracking verwendet werden soll; dann würde eine kleine Anpassung reichen:
$sql_array = array(
    
'SELECT'    => 'f.*',

    
'FROM'        => array(
        
FORUMS_WATCH_TABLE    => 'fw',
        
FORUMS_TABLE        => 'f'
    
),

    
'WHERE'        => 'fw.user_id = ' $user->data['user_id'] . 
        AND f.forum_id = fw.forum_id'
,

    
'ORDER_BY'    => 'left_id'
);

if (
$config['load_db_lastread'])
{
    
$sql_array['LEFT_JOIN'] = array(
        array(
            
'FROM'    => array(FORUMS_TRACK_TABLE => 'ft'),
            
'ON'    => 'ft.user_id = ' $user->data['user_id'] . ' AND ft.forum_id = f.forum_id'
        
)
    );

    
$sql_array['SELECT'] .= ', ft.mark_time ';
}
else
{
    
// Hier werden die Cookie Daten gelesen
}

$sql $db->sql_build_query('SELECT'$sql_array);

Optimierungen

Operatoren in Schleifenköpfen:

Versuchen Sie immer ihre Schleifen zu optimieren wenn die Abbruchsbedingung eine Funktion enthält, weil dieser Teil jeden Durchlauf ausgeführt wird. For Anweisungen sollten deskriptive Namen gewählt werden. Beispiel:

// Bei jedem Durchgang wird die sizeof Funktion aufgerufen

for ($i 0$i sizeof($post_data); $i++)
{
    
mache_irgendwas();
}

// Sie sind in der Lage (nicht wechselnde) Bedingungen in der Schleife selbst zu definieren

for ($i 0$size sizeof($post_data); $i $size$i++)
{
    
mache_etwas();
}

Benutzung von in_array():

Versuchen Sie die Verwendung von in_array() bei großen Arrays zu vermeiden, und versuchen Sie die Anweisungen nicht innerhalb von Schleifen zu benutzen, wenn das Array auf mehr als 20 Einträge überprüft werden soll. in_array() kann sehr Zeit- und Leistungsintensiv sein. Bei kleineren Überprüfungen fällt es kaum auf, aber bei Überprüfungen mit einer Schleife in großen Arrays können alleine dafür einige Sekunden Bearbeitungszeit entstehen. Wenn sie diese Funktionalität benötigen, versuchen sie isset() für Array Schlüssel zu benutzen, sogar wenn Werte und Schlüssel vertauscht werden müssen. Als Beispiel: Ein Aufruf von isset($array[$var]) ist viel schneller als in_array($var, array_keys($array)).

Allgemeine Richtlinien

Allgemeines:

Vertrauen Sie nie auf Benutzereingaben (das betrifft auch Server Variablen und Cookies).

Versuchen Sie die von einer Funktion zurückgelieferten Werte zu bereinigen.

Versuchen Sie alle Variablen in der Funktion zu bereinigen.

Die auth Klasse sollte für alle Berechtigungsprüfungen benutzt werden.

Es sollte kein Versuch gemacht werden Copyright Informationen zu entfernen (egal ob im Quellcode oder auf dem Display), genauso wenig wie das Copyright verändert werden sollte (es kann etwas hinzugefügt werden).

Variablen:

Benutzen Sie die request_var() Funktion für alles außer für das überprüfen auf submit oder Variablen, von denen nur die Existenz überprüft wird.

Die request_var() Funktion bestimmt den Typ der Variable vom zweiten Parameter (welcher auch den Standardwert setzt). Wenn Sie einen skalaren Variablen Typ bekommen wollen, müssen Sie das der request_var Funktion explizit sagen. Beispiele:

// Alte Methode, verwenden Sie diese nicht mehr

$start = (isset($HTTP_GET_VARS['start'])) ? intval($HTTP_GET_VARS['start']) : intval($HTTP_POST_VARS['start']);
$submit = (isset($HTTP_POST_VARS['submit'])) ? true false;

// Benutzen Sie request_var und bestimmen sie den richtigen Typ und Standardwert

$start request_var('start'0);
$submit = (isset($_POST['submit'])) ? true false;

// $start ist ein int, die folgende Benutzung von request_var ist dementsprechend falsch

$start request_var('start''0');

// Beim Array: Schlüssel sind Zahlen, Werte sind standardmäßig 0

$mark_array request_var('mark', array(0));

// Beim Array: Schlüssel sind Strings, Werte sind standardmäßig 0

$action_ary request_var('action', array('' => 0));

Login Überprüfungen/Weiterleitungen:

Um die Login Box zu zeigen benutzen Sie login_forum_box($forum_data), oder die login_box() Funktion.

Die login_box() Funktion kann eine Weiterleitung als ersten Parameter haben. Die Faustregel: Verwenden Sie einen leeren String wenn Sie den Benutzer zur aktuellen Seite leiten wollen, sonst hängen sie die $SID nicht an den redirect String an (als Beispiel innerhalb von ucp/login leiten wir auf den Board-Index um, weil der Benutzer sonst zu dem login geleitet wird).

Heikle Handlungen:

Bei heiklen Handlungen lassen Sie den Benutzer immer die Handlung bestätigen. Für die Bestätigungsanzeige verwenden Sie die confirm_box() Funktion.

Sessions:

Sessions sollten auf jeder Seite initialisiert werden, so nah am Anfang wie möglich. Verwenden Sie dafür folgenden Code:

$user->session_begin();
$auth->acl($user->data);
$user->setup();

Der $user->setup() Aufruf kann verwendet werden um weitere Sprachdateien einzubinden oder einen anderen Style anzuzeigen (verwendet in viewforum).

Fehler und Meldungen:

Alle Meldungen/Fehler Ausgaben sollten trigger_error() verwenden, dazu benutzen Sie den passenden Meldungstyp und einen Sprach-String. Beispiel:

trigger_error('NO_FORUM');
    
trigger_error($user->lang['NO_FORUM']);
    
trigger_error('NO_APPROPRIATE_MODE'E_USER_ERROR);

URL Formatierungen:

Alle URLs die zu internen Dateien verlinken, benötigen eine Vorbereitung durch die $phpbb_root_path Variable. Innerhalb des Administrationspanels müssen alle URLs die zu URLs innerhalb des Admin Bereiches verlinken mit der $phpbb_admin_path Variable vorbereitet werden. Dies stellt sicher dass der Pfad immer richtig ist und Benutzer in der Lage sind den Admin Ordner umzubenennen ohne die Funktionalität einzuschränken (trotzdem werden einige Links nicht immer funktionieren, kleinere Anpassungen können nötig sein).

Die append_sid() Funktion von 2.0.x ist ebenfalls verfügbar, aber Änderungen geschehen dort nicht automatisch. Bitte schauen Sie in die Code-Dokumentation wenn Sie weitere Details zu der Benutzung von append_sid() erhalten wollen. Ein Beispiel Aufruf mit append_sid() kann so aussehen:

append_sid("{$phpbb_root_path}memberlist.$phpEx"'mode=group&amp;g=' $row['group_id'])

Allgemeine Benutzung der Funktionen:

Manche der folgenden Funktionen sind nur aufgrund persönlicher Vorlieben gewählt worden und haben keinen anderen Sinn als den Code einheitlich zu gestalten.

  • Benutzen Sie sizeof anstelle von count
  • Benutzen Sie strpos anstelle von strstr
  • Benutzen Sie else if anstelle von elseif
  • Benutzen Sie false (kleingeschrieben) anstelle von FALSE
  • Benutzen Sie true (kleingeschrieben) anstelle von TRUE

Styling

Allgemeine Dinge

Templates sollten in einer übereinstimmenden Weise erstellt werden. Sie sollten auf einer Kopie einer bereits existierenden Seite basieren, Beispielsweise index, viewforum oder viewtopic (diese Kombination hat ein breites Spektrum an Bedingungen und Variablen). Bitte beachten Sie das die Einrückungen und Coding Guidelines genauso auf Templates angewendet werden sollen wo es möglich ist.

Die äußere Tabellenklasse forumline wurde durch tablebg ersetzt.

Wenn der <table>-Tag verwendet wird, sorgt die Reihenfolge <table class="" cellspacing="" cellpadding="" border="" align=""> für Konsistenz und erlaubt allen einfach zu erkennen wie die Tabelle aussieht. Das gleiche gilt für die meisten anderen Tags wo optionale Parameter benutzt werden können, Konsistenz ist das Hauptziel.

Jedes Block-Element sollte mit einem TAB eingerückt werden, das gleiche gilt für Tabellen-Elemente wie zum Beispiel <tr><td> usw., wobei der <table>- und <tr>-Tag gleich weit eingerückt sein sollten. Das gilt natürlich nicht für <div>-Tags. Benutzen sie <span> so selten wie möglich… die CSS Definitionen wie beispielsweise Textgröße sind abhängig von der Eltern-Klasse. So bewirkt die Zeile <span class="gensmall"><span class="gensmall">TEST</span></span> sehr, sehr kleine Schrift. Verwenden sie keine span wenn ein anderes Element die Klassen-Definition bekommen kann, Bsp.

<td><span class="gensmall">TEST</span></td>

kann auch einfach folgendermaßen geschrieben werden:

<td class="gensmall">TEST</td>

Versuchen Sie die gleiche Klassen zu verwenden wie in den existierenden Dateien, verwenden Sie beispielsweise kein nav wenn viewtopic gensmall verwendet.

Zeilenfarben und –klassen werden nun vom Template definiert, verwenden Sie IF_S_ROW_COUNT wie es in viewtopic und viewforum zu sehen ist.

Denken Sie daran das die Anordnung von Block-Elementen wichtig ist… trotz das nicht alle Seiten als XHTML 1.0 validiert werden können, versuchen wir dies noch zu erreichen.

Benutzen Sie, wie im Standard auch, cellpadding 2 und cellspacing 0 bei äußeren Tabellen. Innere Tabellen können von 0 bis 3 variiert werden, selbst 4 ist möglich wenn es nötig ist.

Benutzen Sie div Container/CSS für Styling und table für Daten Repräsentation.

Die separaten catXXXX und thXXX Klassen sind weg. Wenn sie ein Feld des Kopfbereiches definieren benutzen Sie einfach <th> anstelle von <th class="thHead">, etc. Das gleiche gilt für cat, benutzen sie <td class="cat"> anstelle von <td class="catLeft"> etc.

Versuchen Sie die Konsistenz vom Standard-Layout und dem benutzen der CSS-Klassen zu bewahren, als Beispiel _EXPLAIN sollte immer unterhalb des Titels stehen, den es erklärt, ein typisches Beispiel hierfür wäre {L_POST_USERNAME}<br /><span class="gensmall">{L_POST_USERNAME_EXPLAIN}</span>... es kann natürlich Ausnahmen geben.

Versuchen Sie die Template-Bedingungen und anderen Anweisungen gleichweit einzurücken wie den Block den es betrifft.

Das ist richtig

<!-- BEGIN test -->
    <
tr>
        <
td>{test.TEXT}</td>
    </
tr>
<!-- 
END test -->

Das ist genauso richtig

<!-- BEGIN test -->
<
tr>
    <
td>{test.TEXT}</td>
</
tr>
<!-- 
END test -->

so können Sie sofort erkennen was genau in einer Schleife ist - hier entscheidet die Lesbarkeit des Codes.

Templates

Benennen von Dateien:

Zuerst: Templates haben jetzt das Suffix ".html" anstelle von ".tpl". Das wurde einfach gemacht um das Leben mancher Leute mit Syntax-Highlighting zu erleichtern, usw.

Variablen:

Alle Template Variablen sollten passend benannt werden (mit Unterstrichen für Leerzeichen), Spracheinträge sollte ein L_, Systemdaten ein S_, URL's ein U_, JavaScript-URL's ein UA_ und JavaScript-Spracheinträgen ein LA_ vorangestellt werden, für den Rest gilt 'wie es halt heißt'.

L_* Template Variablen werden automatisch durch die entsprechenden Spracheinträge ersetzt, wenn der Code keine Zuweisung (und damit überschreibt) macht. Als Beispiel {L_USERNAME} wird durch $user->lang['USERNAME'] ersetzt. Die LA_* Template Variablen werden in der gleichen Weise gehandhabt, jedoch escaped um in den JavaScript Code zu passen. Das sollte den Aufwand für das Laden neuer Sprachvariablen durch Mods reduzieren.

Blöcke und Schleifen:

Die Standardblöcke der Schleifen bleiben und sehen folgendermaßen aus:

<!-- BEGIN loopname -->
    
markup, {loopname.X_YYYYY}, etc.
<!-- 
END loopname -->

Fortgeschrittene Schleifen werden später erklärt. Um Sie nicht zu irritieren: Bedingungen werden dort genauso erklärt, wie weitere Anweisungen.

Dateien einfügen:

Etwas das in 2.0.x existierte, aber nun in 3.0.x nicht mehr existiert, ist die Möglichkeit ein Template einer Variablen zuzuweseisen. Dies wurde benutzt (zum Beispiel) um die jumpbox auszugeben. Stattdessen (vielleicht besser, vielleicht nicht, auf jeden Fall aber flexibler) existiert nun INCLUDE. Das sieht einfach so aus:

<!-- INCLUDE filename -->

Sie werden sicher bemerken das die Hauptseiten mit <!-- INCLUDE overall_header.html --> oder <!-- INCLUDE simple_header.html --> starten, in 2.0.x war im Code definiert welcher Kopf benutzt wurde. In 3.0.x können die Templatedesigner ausgeben was sie wollen. Beachten Sie, dass sie neue Variablen einführen können (beispielsweise andere als im Standard) und benutzen können wie Sie wollen... vielleicht ist dies sinnvoll für ein gemeinsames Menü oder so. Es besteht keine Notwendigkeit mehr so viele Dateien zu verändern wie bei 2.0.x.

PHP:

Eine umstrittene Entscheidung war die Möglichkeit PHP im Template einzufügen. Dies wird ermöglicht indem man den PHPCode in die relevanten Tags einfügt:
<!-- PHP -->
    echo 
"hello!";
<!-- 
ENDPHP -->

Sie können genauso PHP durch externe Dateien einfügen:

<!-- INCLUDEPHP somefile.php -->

dies wird dann vor Ort eingefügt und ausgeführt.

Hinweis: Template Designer sollten auf diese Möglichkeit verzichten. Die Möglichkeit PHP Code einzufügen, existiert hauptsächlich um Banner Code und ähnliches einzufügen, ohne viele Dateien bearbeiten zu müssen (wie in 2.0.x). Es ist nicht für den generellen Gebrauch gedacht... daher wird auf www.phpbb.com kein Template verfügbar gemacht, das PHP benutzt. Außerdem wird PHP in Templates standardmäßig deaktiviert sein (der Administrator wird PHP speziell für Templates aktivieren müssen).

Bedingungen und Kontrollstrukturen:

Die signifikanteste Erweiterung in 3.0.x sind die Bedingungen oder Kontrollstrukturen, "wenn etwas dann mache dies sonst mache jenes". Dieses System ist dem von Smarty sehr ähnlich. Dies mag einige Leute zuerst verwirren, aber es hat ein großes Potential und viel Flexibilität mit nur wenig Vorstellungskraft. In der einfachsten Form sieht ein Konstrukt so aus:

<!-- IF bedingung -->
    
mache
<!-- ENDIF -->

die Bedingung kann viele Formen annehmen, zum Beispiel:

<!-- IF loop.S_ROW_COUNT is even -->
    
mache
<!-- ENDIF -->

Dies wird das mache ausgeben wenn die S_ROW_COUNT Variable in der aktuellen Iteration der Schleife gerade ist (die Anweisung ist TRUE). Sie können verschiedene Vergleiche machen (Standardvergleiche genauso wie äquivalente textuelle Versionen in den eckigen Klammern), eingeschlossen (not, or, and, eq, neq, is sollten benutzt werden wenn die Lesbarkeit gesteigert wird):

== [eq]
!= [
neqne]
<> (
das gleiche wie !=)
!== (
nicht gleich im Typ oder Wert)
=== (
gleich im Typ und Wert)
> [
gt]
< [
lt]
>= [
gte]
<= [
lte]
&& [and]
|| [or]
% [
mod]
! [
not]
+
-
*
/
,
<< (
bitweise shift nacht links)
>> (
bitweise shift nach rechts)
| (
bitweise or)
^ (
bitweise xor)
& (
bitweise and)
~ (
bitweise not)
is (can benutzt werden um Vergleiche zu verbinden)

Standard Paranthesen können genauso genutzt werden um die guten alten BODMAS Regeln geltend zu machen. Zusätzlich sind einige Standard Vergleiche definiert:

even
odd
div

Neben diesen einfachen Verwendungen von IF können sie auch Sequenzen von Vergleichen benutzen wie im folgendem Beispiel:

<!-- IF bedingung1 -->
    
mache
<!-- ELSEIF bedingung2 -->
    
mache
    
.
    .
    .
<!-- ELSEIF 
bedingungN -->
    
mache
<!-- ELSE -->
    
mache
<!-- ENDIF -->

Jede Bedingung wird geprüft und die relevanten Daten ausgegeben wenn eine Bedingung erfüllt wird. Es ist nicht nötig immer ELSEIF zu verwenden, ELSE kan benutzt werden um alles andere abzudecken.

Also was können Sie alles damit machen? Also nehmen wir das Beispiel das die Farbgebung in viewforum. In 2.0.x waren die Zeilenfarben im Code als row color1, row color2 oder row class1, row class2 angegeben. In 3.0.x ist das in das Template verschoben. es sieht vermutlich erst ein wenig abschreckend aus, aber erinnern Sie sich an den Kontrollfluss von oben nach unten, und es nicht nicht mehr so schwer:

<table>
    <!-- IF 
loop.S_ROW_COUNT is even -->
        <
tr class="row1">
    <!-- ELSE -->
        <
tr class="row2">
    <!-- ENDIF -->
    <
td>HELLO!</td>
</
tr>
</
table>

Dies wird dazu führen, dass die Ausgabe der Zeilenfelder die Klasse row1 verwendet wenn die Zeilenzahl gerade ist, und row2 im anderen Fall. Der S_ROW_COUNT Parameter wird automatisch bei Schleifen angelegt. Ein weiteres Beispiel ist folgendes:

<table>
    <!-- IF 
loop.S_ROW_COUNT 10 -->
        <
tr bgcolor="#FF0000">
    <!-- ELSEIF 
loop.S_ROW_COUNT -->
        <
tr bgcolor="#00FF00">
    <!-- ELSEIF 
loop.S_ROW_COUNT -->
        <
tr bgcolor="#0000FF">
    <!-- ELSE -->
        <
tr bgcolor="#FF00FF">
    <!-- ENDIF -->
    <
td>hello!</td>
</
tr>
</
table>

Dies wird die Zeilenfelder in den ersten beiden Reihen lila, blau in den Zeilen 2 bis 5, grün in den Zeilen 5 bis 10 und rot für alle weiteren ausgeben. Also, Sie können einen "schönen" Farbverlauf erstellen, als Beispiel.

Was können Sie noch machen? Also, Sie können IF benutzen um allgemeine Überprüfungen zu machen wie dem Login Status eines Users:

<!-- IF S_USER_LOGGED_IN -->
    
mache
<!-- ENDIF -->

Dies ersetzt die existierende (erschummelte) Methode in 2.0.x eines leeren Arrays und BEGIN/END.

Übersetzungsrichtlinien (i18n/L10n)

Standardisierung

Grund:

phpBB ist einer der am meisten übersetzten Open-Source Projekten, mit über 60 Lokalisierungen in der aktuellen, stable Version. Trotz das die aus dem Stegreif entstandene Methode für die Benennung der Sprachpakete funktionierte, hoffen wir diesen Prozess für phpBB3 und nachfolgende Versionen durchdachter zu gestalten, um eine bessere Unterstützung für aktuelle und zukünftige WebBrowser zu bieten.

Encoding:

Mit phpBB3 wird die Ausgabe Encodierung für das Forum auf UTF-8, einem universellem Zeichensatz vom Unicode Consortium, umgestellt, welches eine Zusammenfassung aus US-ASCII und ISO-8859-1 ist. Durch die Verwendung dieses Zeichensatzes wird ermöglicht Scripts auszuführen, die früher verschiedene Zeichensätze benötigten (beispielsweise ISO-8859-1 bis ISO-8859-15 (Latein, Griechisch, kyrillisch, thailändisch, hebräisch, arabisch); GB2312 (vereinfachtes Chinesisch); Big5 (Traditionelles Chinesisch), EUC-JP (Japanisch), EUC-KR (koreanisch), VISCII (vietnamesisch); und weitere). Dadurch entfällt das konvertieren zwischen den verschiedenen Zeichensätzen und verbessert die Zugänglichkeit für mehrsprachige Foren.

Deshalb müssen die Sprachdateien für phpBB jetzt als UTF-8 Dokumente gespeichert werden, mit dem Vorbehalt das die Dateien kein BOM enthalten dürfen, aufgrund der nicht-Unicode-fähigen PHP Versionen. Für Foren mit dem Lateinischem Zeichensatz (gilt für fast alle europäischen Sprachen), ist diese Änderung am einfachsten, da UTF-8 eine Erweiterung des US-ASCII und ISO-8859-1 ist.

Sprach-Tags:

Die IETF hat kürzlich die RFC 4646 die Tags zur Identifizierung herausgegeben, welche in Kombination mit den RFC 4647 den älteren RFC 3006 und noch älteren RFC 1766 ersetzt. RFC 4646 benutzt ISO 639-1/ISO 639-2, ISO 3166-1 alpha-2, ISO 15924 und UN M.49 um einen Sprach Tag zu definieren. Jeder komplette Tag ist eine Zusammenstellung von Sub-Tags, welche Groß- und Kleinschreibung nicht beachten und leer sein können.

Die Reihenfolge der Sub-Tags wenn alle vorhanden sind ist: Sprache-Schriftsystem-Region-Variante-Erweiterung-private Nutzung. Sollte ein Sub-Tag leer sein, so wird der zugehörige Bindestrich ebenfalls weggelassen. Deshalb wäre der Sprach-Tag für Englisch en und nicht en-----.

Die meisten Sprach-Tags bestehen aus zwei oder drei Zeichen (von ISO 639-1/ISO 639-2). Manchmal folgt diesem eine zwei- bis dreistellige Zahl als Regions-Sub-Tag (von ISO 3166-1 alpha-2 oder UN M.49). Einige Beispiele sind:

Sprach-Tag Beschreibung Sub-Tag Komponenten
en Englisch Sprache
mas Masai(?) Sprache
fr-CA Französisch wie es in Kanada benutzt wird Sprache+Region
en-833 Englisch wie es auf der "Isle of Man" benutzt wird Sprache+Region
zh-Hans Chinesisch in einfacher Schrift geschrieben Sprache+Schriftsystem
zh-Hant-HK Chinesisch in traditioneller Schrift wie es in Hong Kong benutzt wird Sprache+Schriftsystem+Region
de-AT-1996 Deutsch wie es in Österreich benutzt wird, Rechtschreibung von 1996 Sprache+Region+Variante

Das wichtigste Ziel der Sprach-Tags ist es die kennzeichnenden Informationen zu transportieren, und diese trotzdem so kurz wie möglich zu halten. Als Beispiel wird en, fr und ja als Gegenstück zu en-GB, fr-FR, ja-JP verwendet, weil wir wissen das englisch, französisch und japanisch ihren Ursprung in Großbritannien, Frankreich und Japan haben.

Das nächste ist der ISO 15924 Sprachsystem Code und wann man es verwendet, und wann nicht. Als Beispiel en-Latin ist syntaktisch korrekt um Englisch mit lateinischen Zeichen zu beschreiben, aber in der Welt wird englisch eigentlich fast immer in Lateinischen Buchstaben geschrieben. Für solche Sprachen wie englisch die überwiegend nur mit einem Schriftsystem geschrieben werden, hat die IANA Language Subtag Registry ein "Suppress-Script" (unterdrücken/weglassen) Feld, das bedeutet das der Schriftsystem-Sub-Tag in solchen Fällen weggelassen werden sollte, außer ein spezifisches Schriftsystem benötigt dies. Manche Sprachen werden in mehr als einem Schriftsystem geschrieben und in solchen Fällen wird der Schriftsystem-Sub-Tag bestärkt, da manche Benutzer die Sprache in einem Schriftsystem lesen können, aber nicht in einem anderen. Einige Beispiele sind:

Sprach-Tag Beschreibung Sub-Tag Komponenten
en-Brai englisch in Blindenschrift Sprache+Schriftsystem
en-Dsrt englisch in "Deseret" (Mormonen) Sprache+Schriftsystem
sr-Latn serbisch mit lateinischer Schrift Sprache+Schriftsystem
sr-Cyrl serbisch mit kyrillischen Schriftzeichen Sprache+Schriftsystem
mn-Mong mongolisch in mongolischen Schriftzeichen Sprache+Schriftsystem
mn-Cyrl mongoliisch in kyrillischen Schrifzeichen Sprache+Schriftsystem
mn-Phag mongolisch in "Phags-pa" geschrieben Sprache+Schriftsystem
az-Cyrl-AZ Aserbaidschanisch in kyrillischer Schrift wie sie in Aserbaid benutzt wird Sprache+Schriftsystem+Region
az-Latn-AZ Aserbaidschanisch in lateinischer Schrift wie sie in Aserbaid benutzt wird Sprache+Schriftsystem+Region
az-Arab-IR Aserbaidschanisch in arabischer Schrift wie sie im Iran benutzt wird Sprache+Schriftsystem+Region

Der dreistellige UN M.49 Code over sollte anstelle des zwei-stelligen ISO 3166-1 alpha-2 Code verwendet werden wenn ein makro-geographische Unterscheidung benötigt wird und/oder ISO 3166-1 alpha-2 mehrdeutig ist.

Beispiele für englisch mit makro-geographischen Regionen:

ISO 639-1/ISO 639-2 + ISO 3166-1 alpha-2 ISO 639-1/ISO 639-2 + UN M.49 (Beispielhafte makro Regionen)
en-AU englisch wie es in Australien benutzt wird en-053 englisch wie es in Australien & Neuseeland benutzt wird en-009 englisch wie es in Ozeanien benutzt wird
en-NZ englisch wie es in Neuseeland benutzt wird
en-FJ englisch wie es in Fidschi benutzt wird en-054 englisch wie es in Melanesien benutzt wird

Beispiele mit Spanisch und makro-geographische Regionen:

ISO 639-1/ISO 639-2 + ISO 3166-1 alpha-2 ISO 639-1/ISO 639-2 + UN M.49 (Beispielhafte makro Regionen)
es-PR spanisch wie es in Puerto Rico genutzt wird es-419 spanisch wie es in Latein Amerika & der Karibik genutzt wird es-019 spanisch wie es in Amerika genutzt wird
es-HN spanisch wie es in Honduras genutzt wird
es-AR spanisch wie es in Argentinien genutzt wird
es-US spanisch wie es in der USA genutzt wird es-021 spanisch wie es in Nordamerika genutzt wird

Beispiele bei den ISO 3166-1 alpha-2 mehrdeutig ist und UN M.49 bevorzugt werden sollte:

CS Zuweisung vor 1994 CS Zuweisung nach 1994
CS Tschechoslowakei (ISO 3166-1)
200 Tschechoslowakei (UN M.49)
CS Serbienn & Montenegro (ISO 3166-1)
891 Serbien & Montenegro (UN M.49)
CZ Tschechische Republik (ISO 3166-1)
203 Tschechische Republik (UN M.49)
SK Slowakei (ISO 3166-1)
703 Slowakei (UN M.49)
RS Serbien (ISO 3166-1)
688 Serbien (UN M.49)
ME Montenegro (ISO 3166-1)
499 Montenegro (UN M.49)

Makro-Sprachen & örtliche Prägungen:

RFC 4646 vorausschauende Features welche in ISO 639-3 verfügbar gemacht werden sollen (derzeit nur Entwurf), zielen darauf ab eine so vollständige Auflistung der Sprachen verfügbar zu machen, einschließlich lebender, toter, altertümlicher und konstruierter Sprachen, egal ob Haupt-, Neben- oder ungeschriebener Sprache. Ein neues Feature von ISO 639-3 verglichen zu den zwei Vorgängern ist das Konzept der Makrosprachen, arabisch und chinesisch sind hierfür zwei Beispiele. In solchen Fällen ist der jeweilige Code von ar und zh sehr vage bei den Dialekten/Prägungen oder vielleicht zu knapp und damit zu schwer für alle außer den besonders gebildeten Benutzern. Für solche Makro-Sprachen wird empfohlen das der Sprach-Sub-Tag als Suffix für das Makro-Sprach-Tag genutzt wird, Beispiel:

Sprach-Tag Beschreibung Sub-Tags Komponenten
zh-cmn Mandarin ("Putonghau"/"Guoyu") chinesisch Makro-Sprache+Prägung
zh-yue "Yue" (kantonesisch) chinesisch Makro-Sprache+Prägung
zh-cmn-Hans Mandarin ("Putonghau"/"Guoyu") chinesisch in vereinfachter Schrift Makro-Sprache+Prägung+Schriftsystem
zh-cmn-Hant Mandarin ("Putonghau"/"Guoyu") chinesisch in traditioneller Schrift Makro-Sprache+Prägung+Schriftsystem
zh-nan-Latn-TW Minnan ("Hoklo") chinesisch in lateinischer Schrift ("POJ Romanisation") wie es in Taiwan genutzt wird Makro-Sprache+Prägung+Schriftsystem+Region

Weitere Erwägungen

Normalisierung der Sprach-Tags für phpBB:

Für phpBB werden die Sprach-Tags nicht in ihrer Originalform benutzt, sondern kleingeschrieben und der Bindestrich - wird wenn es angemessen ist durch den Unterstrich _ ersetzt, hier ein paar Beispiele:

Original Sprach Tag Beschreibung Wert der USER_LANG in ./common.php Sprachpaketname im Verzeichnis /language/
en britisches Englisch en en
de-AT Deutsch wie es in Österreich benutzt wird de-at de_at
es-419 Spanisch wie es in Latein Amerika & der Karibik verwendet wird en-419 en_419
zh-yue-Hant-HK kantonesisch in traditionellen Schriftzeichen wie es in Hong Kong benutzt wird zh-yue-hant-hk zh_yue_hant_hk

Benutzung der iso.txt:

Die iso.txt Datei ist eine kleine vollständig in UTF-8 kodierte Datei die drei Zeilen enthält:

  • 1. Englischer Name der Sprache
  • 2. Name in der Sprache in eben dieser Sprache
  • 3. Informationen zum Autoren

Die iso.txt wird automatisch beim einstellen auf phpBB.com generiert. Sie brauchen diese Datei also nicht erstellen wenn Sie diese auf phpBB.com veröffentlichen wollen, aber denken Sie daran das phpBB diese Datei benötigt um die Sprache zu erkennen.

Weil die Sprach-Tags selber maschinell gelesen werden, können diese auf Menschen verwirrend wirken und weil die beschreibenden Strings in der iso.txt benötigt werden. Trotz das en-US noch sehr einfach in "Englisch wie es in der USA benutzt wird" aufgelöst werden kann, ist de-CH schon schwieriger, weniger Menschen wissen das das de von "Deutsch" kommt, German für "German" und CH die offizielle Abkürzung für die Schweiz oder auch die "Confoederatio Helvetica" ist.

Für jede englische Beschreibung kommt der Sprachname zuerst und dann zusätzliche Informationen zur Beschreibung der Sub-Tags des Sprach Codes hintereinander aufgelistet, mit Kommas getrennt in Klammern, Beispiel:

Original Sprach-Tag Englische Beschreibung in der iso.txt
en British English
en-US English (United States)
en-053 English (Australia & New Zealand)
de German
de-CH-1996 German (Switzerland, 1996 orthography)
gws-1996 Swiss German (1996 orthography)
zh-cmn-Hans-CN Mandarin Chinese (Simplified, Mainland China)
zh-yue-Hant-HK Cantonese Chinese (Traditional, Hong Kong)

Für die übersetzte Sprachbeschreibung, übersetzen Sie einfach die englische Version, und benutzen Sie was für die Zeichensetzung in der Sprache benutzt wird, vorausgesetzt die Sprache besitzt überhaupt eine Zeichensetzung.

Überlegen zu bidirektionalem Unicode:

Da phpBB jetzt UTF-8 verwendet, müssen alle Übersetzer nun in Kauf nehmen das bestimmte Strings in der umgekehrten Direktionalität angezeigt wird, oder die Ausgabe ungewiss ist.

Die verschiedenen Unicode Kontrollzeichen für bidirektionalen Text und ihre HTML Äquivalente wenn entsprechend sind die folgenden:

Unicode Zeichen Abkürzung Unicode Code-Punkt Unicodezeichen Name HTML äquivalente Zeichen/Entities
LRM U+200E Left-to-Right Mark (links-nach-rechts Kennzeichnung)
RLM U+200F Right-to-Left Mark (recht-nach-links Kennzeichnung)
LRE U+202A Left-to-Right Embedding (links-nach-rechts Einschub) dir="ltr"
RLE U+202B Right-to-Left Embedding (rechts-nach-links Einschub) dir="rtl"
PDF U+202C Pop Directional Formatting </bdo>
LRO U+202D Left-to-Right Override (links-nach-rechts überschreiben)
RLO U+202E Right-to-Left Override (rechts-nach-links überschreiben)

In der iso.txt kann Textrichtung explizit mit den Unicode Zeichen werden, die 3 Methoden bieten links-nach-rechts/rechts-nach-links Kennzeichnungen/Einschübe/überschreibungen, ohne sie wird die Anordnung der Zeichen falsch, beispielsweise:

Direktionalität Unbearbeitete Zeichenfolge Anzeigen der lokalisierten Beschreibung der iso.txt Anordnung
dir="ltr" English (Australia & New Zealand) English (Australia & New Zealand) Korrekt
dir="rtl" English (Australia & New Zealand) (English (Australia & New Zealand Inkorrekt
dir="rtl" mit LRM English (Australia & New Zealand)U+200E English (Australia & New Zealand)‎ Korrekt
dir="rtl" mit LRE & PDF U+202AEnglish (Australia & New Zealand)U+202C ‪English (Australia & New Zealand)‬ Korrekt
dir="rtl" mit LRO & PDF U+202DEnglish (Australia & New Zealand)U+202C ‭English (Australia & New Zealand) Korrekt

Bei der Wahl der drei Methoden wird es meist LRM oder RLM sein, um ein "starkes" Zeichen welches die die eindeutigen Punktierungszeichen vollständig umspannt und daher die korrekte Direktionalität ausreichend vererbt.

In einigen Fällen kann das Script links-nach-rechts und rechts-nach-links Direktionalitäten mischen, da kann LRE & RLE mit PDF besser passen. Zum Schluss, in sehr seltenen Fällen wo die Direktionalität erzwungen werden muss, benutzen Sie LRO & RLO mit PDF.

Für weitere Informationen bei den Techniken der Bidirektionalität, schauen Sie bitte in das W3C Tutorial zu den Techniken bei XHTML Seiten mit bidirektionalem Text (englisch).

Arbeiten mit Platzhaltern:

Da phpBB in mehrere Sprachen mit unterschiedlichen Textrichtungen als deutsch arbeitet, ist es möglich das bestimmte Werte in einer anderen Reihenfolge kommen. Nehmen Sie das simple "Seite X von Y" als Beispiel, in deutsch kann dies einfach folgendermaßen geschrieben werden:

...
'PAGE_OF'    =>    'Seite %s von %s',
        
/* Einfach die Werte schnappen und einsetzen und
        hoffen das sie in der richtigen Reihenfolge kommen */
    
...

… ein besserer Weg um explizit die Reihenfolge bei dem Ersetzen festzulegen ist:

...
'PAGE_OF'    =>    'Seite %1$s von %2$s',
        
/* Explizite Reihenfolge der Ersetzungen,
        selbst wenn sie in der gleichen Reihenfolge wie in deutsch sind */
    
...

Warum damit herumschlagen? Weil manche Sprachen das zurück in das Deutsche übersetzt sowas geschrieben haben könnten wie:

...
'PAGE_OF'    =>    'Gesamt %2$s Seiten, gerade auf Seite %1$s',
        
/* Explizite Reihenfolge der Ersetzungen, zurückübersetzt verglichen
        mit dem deutschen zeigt das die Gesamtzahl der Seiten zuerst kommt */
    
...

Schreibstil

Verschiedene Tipps und Kniffe:

Da die Sprachdateien PHP-Dateien sind, indem die verschiedenen Strings für phpBB als Array gespeichert werden, welche wiederum für das Anzeigen auf der HTML Seite genutzt werden, sind Syntax-Regeln nötig. Potentielle Problem Zeichen sind: ' (gerades Apostroph), " (Anführungszeichen), < (kleiner-als Zeichen), > (größer-als Zeichen) und & (kaufmännisches Und).

// Schlecht - Das nicht maskiert Apostroph wird einen PHP parse Fehler hervorrufen

...
'CONV_ERROR_NO_AVATAR_PATH'
    
=>    'Note to developer: you must specify $convertor['avatar_path'] to use %s.',
    ...

// Gut - Apostrophe sollten mit dem Backslash maskiert werden, beispielsweise mit: \

...
'CONV_ERROR_NO_AVATAR_PATH'
    
=>    'Note to developer: you must specify $convertor[\'avatar_path\'] to use %s.',
    ...

Wie auch immer, da phpBB3 jetzt UTF-8 als Kodierung nutzt, können wir das zu unserem Vorteil nutzen und müssen nicht mehr daran denken das Apostroph zu maskieren:

// Schlecht - Das nicht maskiert Apostroph wird einen PHP parse Fehler hervorrufen

...
'USE_PERMISSIONS'    =>    'Test out user's permissions',
    ...

// Okay - nicht-Programmierer würden "user\'s" nicht automatisch benutzen

...
'USE_PERMISSIONS'    =>    'Test out user\'s permissions',
    ...

// Am besten - Benutzten Sie das rechtsliegende Apostroph

...
'USE_PERMISSIONS'    =>    'Test out user’s permissions',
    ...

Das " (Anführungszeichen), < (kleiner-als Zeichen) und > (größer als Zeichen) Zeichen können alle als Bildzeichen oder als HTML Entity angezeigt werden, als Beispiel:

// Schlecht - Kein gültiges HTML, da Segmente die nicht Teil eines Tags sind nicht als Entity geschrieben sind

...
'FOO_BAR'    =>    'PHP version < 4.3.3.<br />
    Visit "Downloads" at <a href="http://www.php.net/">www.php.net</a>.'
,
    ...

// Okay - Kein ungültiges HTML mehr, aber $quot;$amp;quot;$quot; ist sehr unschön

...
'FOO_BAR'    =>    'PHP version &lt; 4.3.3.<br />
    Visit &quot;Downloads&quot; at <a href="http://www.php.net/">www.php.net</a>.'
,
    ...

// Am besten - kein ungültiges HTML und die Benutzung typographisch-korrekter Anführungszeichen

...
'FOO_BAR'    =>    'PHP version &lt; 4.3.3.<br />
    Visit “Downloads” at <a href="http://www.php.net/">www.php.net</a>.'
,
    ...

Zum Schluss: das & (kaufmännische Und) muss immer als Entity geschrieben werden, unabhängig davon wo es benutzt wird:

// Schlecht - kein gültiges HTML, keines der &'s ist als Entity geschrieben

...
'FOO_BAR'    =>    '<a href="http://somedomain.tld/?foo=1&bar=2">Foo & Bar</a>.',
    ...

// Gut - Gültiges HTML, das & ist in allen Fällen als Entity geschrieben

...
'FOO_BAR'    =>    '<a href="http://somedomain.tld/?foo=1&amp;bar=2">Foo &amp; Bar</a>.',
    ...

Um zu erfahren wie diese Zeichen eingegeben werden lesen sie bitte http://en.wikipedia.org/wiki/Unicode#Input_methods da dies sehr stark vom Betriebssystem, der aktuellen Tastatursprache und den nativen Fähigkeiten des Editors zum bearbeiten der phpBB Sprachdateien abhängt.

Rechtschreibung, Punktierung, Grammatik und ähnliches:

Die Standardsprache mit der phpBB ausgeliefert wird ist britisches Englisch, welches die Rechtschreibung der Cambridge University Press verwendet und dem Sprachcode en zugeordnet ist. Der Schreibstil tendieren zu dem formalen und Übersetzungen sollten versuchen dies nachzuahmen. Zumindest die Varianten mit den kompaktesten Sprachcodes. Weniger formale Übersetzungen oder die mit Umgangssprache müssen als solche gekennzeichnet werden, entweder mit der Erweiterung oder dem private Nutzung Sprachcode.

Guidelines Changelog

Revision 1.16

  • Added 5. Translation (i18n/L10n) Guidelines section to explain expected format and authoring considerations for language packs that are to be created for phpBB.

Revision 1.11-1.15

  • Various document formatting, spelling, punctuation, grammar bugs.

Revision 1.9-1.10

  • Added sql_query_limit to 2.iii. SQL/SQL Layout.

Revision 1.8

  • Some adjustements to wordings
  • Updated paragraph 1.iii. File Locations to reflect recent changes
  • Extended paragraph 2.ii. Code Layout.
  • Added sql_in_set and sql_build_query explanation to 2.iii. SQL/SQL Layout.
  • Updated paragraph 3. Styling.
  • Updated paragraph 4. Templating to explain loop checking, loop breaking and other changes we recently made.

Revision 1.5

  • Changed General function usage paragraph in 2.v. General Guidelines