Die sogenannten Coding-Standards sorgen dafür, dass der Quellcode jeder einzelner Datei von WordPress gleichbleibend ist. Als Programmierer kennen Sie den Missstand vielleicht: Jeder Entwickler hat seinen eigenen Programmierstil. Das wiederum bedeutet, dass nicht jeder Ihren Code ohne weiteres lesen kann.
Um den Code von WordPress zu vereinheitlichen, wurden die Coding-Standards geschaffen. Das soll die Qualität, insbesondere aber die Verständlichkeit und die Wartbarkeit erhöhen.
Im sogenannten Core Contributor Handbook sind alle Coding Standards zusammengefasst. Sie existieren nämlich nicht nur für PHP, sondern auch für HTML-, CSS- und JavaScript.
https://make.wordpress.org/core/handbook/best-practices/coding-standards/
Sich an die Coding-Standards zu halten, ist kein Muss. Ich habe schon Plugins eingereicht, die sich nicht daran gehalten haben. Und sie wurden immer ohne Wenn und Aber angenommen. Trotzdem: Guten und vor allem einheitlichen Code zu schreiben, hilft nicht nur Ihnen selbst, sondern auch der Community rund um WordPress. Der Vorteil ist, dass jeder von jedem lernen kann. Noch besser aber ist, dass jeder den Quellcode schnell lesen kann. Ob man ihn dann versteht ist natürlich eine andere Sache. Dafür sind dann Kommentare gut. Vorausgesetzt man versteht sie. Falls sie überhaupt vorhanden sind, gibt es auch für Kommentare – interessanterweise – eigene Regeln. Dazu gehört zum Beispiel die richtige Kommasetzung.
Natürlich möchte ich hier keinen Englisch-Unterricht anzetteln, deswegen stelle ich nur die gängigsten PHP-Standards kurz vor. Im nächsten Kapitel geht es dann allein um die Dokumentationen.
Einfache und doppelte Anführungszeichen
PHP erlaubt es Ihnen, Strings mit doppelten oder einfachen Anführungszeichen zu definieren. Das oben genannte Handbuch empfiehlt die Nutzung von einfachen Anführungszeichen, falls möglich. Im Grunde ersparen Sie sich das Escapen aller doppelten Anführungszeichen in einem etwaigen HTML Code. Dadurch wird der Quelltext einfacher zu lesen. Einen gigantischen Geschwindigkeitsvorteil haben Sie dadurch allerdings nicht.4
Erklärung:
„Escaping“ bedeutet, dass besondere Zeichen in PHP – meist mit einem Backslash (\
)- maskiert werden, da sie sonst fehlerhaft interpretiert werden würden (siehe Beispiel unten).
<?php
$url = 'http://beispiel.de';
// B1: Nicht empfohlen:
echo "<a href='$url'>Dies ist eine URL</a>";
// B2: Nicht empfohlen
echo "<a href=\"$url\">Dies ist eine URL</a>";
// B2: Empfohlen:
echo '<a href="'. $url .'">Dies ist eine URL</a>';
?>
Einrückung
Richtige Tabulatorsprünge sind hier gefragt. Keine Leerzeichen. Viele Programme lassen sich über das Menü so einstellen. Eine Ausnahme gibt es da nur bei solchem Code, der durch Leerzeichen lesbarer wird.
<?php
// Nicht empfohlen
$mein_array = array(
'foo' => 'wert1',
'foo12' => 'wert2',
'foo34' => 'wert3',
'foo567' => 'wert4',
);
// Empfohlen:
$mein_array = array(
'foo' => 'wert1',
'foo12' => 'wert2',
'foo34' => 'wert3',
'foo567' => 'wert4',
);
?>
Klammern
Auch die Klammern müssen angesprochen werden. Gerade sie werden von fast jedem Programmierer anders benutzt. Hier also die von WordPress vorgegebenen Regeln:
- Klammern sollten immer in der gleichen Zeile wie die Anweisung selbst stehen.
- Bei langen Blöcken sollte am Ende immer ein Kommentar auf das Ende hinweisen.
- Ultralange If-Else Blöcke sollten in eigene Funktionen ausgelagert werden.
Ein Beispiel:
<?php
// Nicht empfohlen:
if( $c1 )
{
action1();
}
elseif( $c2 )
{
action2();
}
elseif( $c3 )
{
action3();
}
else
{
action4();
}
// Empfohlen:
if ( $c1 ){
action1();
} elseif ( $c2 ) {
action2();
} elseif ( $c3 ) {
action3();
} else {
action4();
} // End of condition check
?>
Leerzeichen
Leerzeichen sollten immer nach Kommas und auf beiden Seiten von logischen Operationen stehen. Außerdem sollten Leerzeichen am Ende jeder Zeile entfernt werden.
<?php
// Nicht empfohlen
if($c1){
action(true);
}
// Empfohlen
if ( $c1 ) {
action( true );
}
?>
Weitere Beispiele, wie Leerzeichen benutzt werden sollen, finden Sie unter https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#space-usage.
Formatierung von SQL-Anweisungen
SQL-Anweisungen können schon manchmal sehr lang und dadurch unübersichtlich werden. Aus diesem Grund empfiehlt WordPress folgende Regeln:
- Lange Zeilen sollten auf mehrere kürzere Zeilen umgebrochen werden.
- Die “ausführenden” Teile einer SQL-Anweisung sollten immer groß geschrieben werden. Zum Beispiel eine
UPDATE
oderSELECT
Anweisung. - Der Sicherheit wegen sollten Variablen immer escaped werden. Das gelingt am besten mit der
$wpdb->prepare()
Funktion. Darüber hinaus übernimmt die Funktion die Quotierung und das Type-Casting für SQL-Anfragen.
Beispiel aus dem offiziellen Handbuch:
<?php
global $wpdb;
// Das einzelne Anführungszeichen am Ende sorgt für Probleme bei der SQL-Abfrage
$var = "dangerous'";
// Diese Funktion sollte einen Integer-Wert zurückgeben.
$id = some_foo_number();
$wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_title = %s WHERE ID = %d", $var, $id ) );
?>
Zur Erklärung: %s
wird als String-, %d
hingegen für Integer-Platzhalter benutzt. Die Werte selbst müssen nicht separat mit Anführungsstrichen versehen werden. Die prepare()
Funktion übernimmt dies automatisch.
Alternativ kann die Funktion esc_sql()
genutzt werden. Sie muss aber für jede Variable in der SQL-Abfrage einzeln aufgerufen werden und ist daher eher unpraktisch für Anfragen, die mehrere Variablen enthalten:
<?php
$name = esc_sql( $name );
$status = esc_sql( $status );
$wpdb->get_var( "SELECT etwas FROM tablenname WHERE foo = '$name' and status = '$status'" );
?>
Datenbank-Abfragen
Man sollte es tunlichst vermeiden, die Datenbank von WordPress manuell abzufragen. Die Nutzung vorhandener WordPress-Methoden (in der globalen Variable $wpdb
) sorgt dafür, dass Ihre Plugins auch mit zukünftigen Versionen kompatibel bleiben, ohne dass Sie sie verändern müssen.
Reguläre Ausdrücke
Zur Vereinheitlichung sollten nur die zu Perl kompatiblen regulären Ausdrücke (PCRE) Anwendung finden. Das bedeutet, dass nur die preg_*
Funktionen von PHP benutzt werden sollten. Seit 5.3.0 sind die POSIX Regex-Funktionen (ereg_*
) ohnehin als veraltet markiert und geben bei Verwendung eine Warnung aus.5
Des Weiteren soll der Suchmuster-Modifikator /e
nicht verwendet werden (dieser ist ab PHP 5.5.0 ebenfalls als veraltet markiert 6).
PHP-Öffnungs-Tags
Verwenden Sie immer <?php
sowie ?>
und nicht etwa die Kurzform davon (<?
bzw. ?>
). Dieser sogenannte Short-Tag ist nicht unbedingt bei jedem Webhoster aktiviert, was wiederum zu Problemen führen kann.
Tabu sind überdies natürlich auch die PHP-ASP Tags <%
und %>
. Sie wurden ab Version 7.0.0 von PHP entfernt und stehen nicht mehr zur Verfügung.
// Nicht empfohlen:
<% ... %>
<? ... ?>
<?= $var ?>
// Empfohlen
<?php ... ?>
<?php echo $var; ?>
Namenskonvention
Hier trennt sich erneut die Spreu vom Weizen, denn WordPress empfiehlt, alle Variablen und Funktionen klein zu schreiben. Dies steht im Gegensatz zu vielen PHP-Büchern, die genau das Gegenteil fordern: den sogenannten camelCase-Style.
<?php
// Nicht empfohlen:
function einSchoenerName( $eineVariable ) { ... }
// Empfohlen:
function ein_schoener_name( $eine_variable ) { ... }
?>
Einzig die Klassen-Bezeichnungen stellen eine Ausnahme dar. Hier sind Großbuchstaben ausdrücklich erlaubt. Allerdings müssen Wörter auch mit einem Unterstrich voneinander getrennt werden.
<?php
// Nicht Empfohlen:
class WalkerCategory extends Walker { ... }
class walker_category extends Walker { ... }
class walker_Category extends Walker { ... }
// Empfohlen:
class Walker_Category extends Walker { ... }
?>
Dateinamen sollten ebenso immer klein geschrieben werden. Einzelne Wörter werden mit Bindestrichen voneinander getrennt:
// Nicht empfohlen:
meinErstesPlugin.php
mein_erstes_plugin.php
// Empfohlen:
mein-erstes-plugin.php
Für Klassen gibt es wiederum eigene Regeln für die Dateinamen:
// Nicht empfohlen:
mein-klassenname.php
class.mein-klassenname.php
//Empfohlen:
class-mein-klassenname.php
Das vorangestellte class-
kann jedoch entfallen, wenn sich die Klassen-Dateien in einem separaten Unterordner befindet:
/classes/mein-klassenname.php
Selbsterklärender Code
true
und false
erlauben es uns, zwischen zwei verschiedenen Zuständen einfach zu unterscheiden. Trotzdem sind sie nicht immer von Vorteil. Gerade, wenn sie sich in der Parameterliste von Funktionen befinden.
<?php
// Nicht empfohlen:
function fahren( $fahrzeugart, $schnell = true ){ ... }
...
fahren( 'Pkw' );
fahren( 'Pkw', true );
fahren( 'Pkw', false )
?>
Im obigen Beispiel wird jedem schnell bewusst, dass man eigentlich nicht weiß, was true
oder false
im Funktionsaufruf bedeutet. Stattdessen wäre folgender Ansatz lesenswerter:
<?php
// Empfohlen:
function fahren( $fahrzeugart, $geschwindigkeit = 'schnell' ){ ... }
...
fahren( 'Pkw' );
fahren( 'Pkw', 'schnell' );
fahren( 'Pkw', 'langsam' )
?>
Alternativ könnte man auch Arrays nutzen:
<?php
// Empfohlen:
function fahren( $fahrzeugart, $options = array() ){ ... }
...
fahren( 'Pkw' );
fahren( 'Pkw', array(
'geschwindigkeit' => 'schnell',
) );
fahren( 'Pkw', array(
'geschwindigkeit' => 'langsam',
) );
?>
Ternärer Operator
Der ternäre Operator ist ein ideales Werkzeug, um if/else
Anweisungen auf eine Zeile zu verkürzen. Auf der anderen Seite kann es manchmal ein bisschen zu kompliziert werden. Man sollte immer überlegen, ob der eigene Code durch kurze Zeilen lesbar bleibt oder nicht. Im Zweifel sollte man if/else
-Blöcke lieber komplett ausschreiben.
Zudem ist eine Überprüfung auf true
meist besser als eine Überprüfung auf false
.
<?php
// Nicht empfohlen: Überprüfung auf false
$existiert = ( ! empty( $wert ) ) ? true : false;
// Empfohlen: Überprüfung auf true
$existiert = ( empty( $wert ) ) ? false : true;
?>
Davon abgesehen, dass es natürlich auch noch einfacher geht:
<?php
$existiert = ! empty( $wert );
?>
Ab PHP 7 gibt es auch den so genannten Null Coalesce Operator:
Anstatt:
<?php
$title = isset( $field['title'] ) ? $field['title'] : 'alternative';
?>
Lässt sich nun auch folgendes schreiben:
<?php
$title = $field['title'] ?? 'alternative';
?>
Yoda-Bedingungen
Klingt komisch, stimmt aber: Die Bedingungen nach “Yoda” haben tatsächlich etwas mit DEM Yoda aus der Star-Wars-Filmreihe zu tun.
<?php
// Nicht empfohlen
if ( $himmel == 'blau' ) eine_funktion();
// Empfohlen
if ( 'blau' == $himmel ) eine_funktion();
?>
Haben Sie es durchschaut? Die empfohlene Überprüfung spricht sich so: “Wenn blau Himmel, dann …”. Also in etwa so, wie Meister Yoda spricht. Zuerst klingt das natürlich etwas witzig und man fragt sich, warum man das so macht. Das Ganze hat aber einen sehr guten Hintergrund: Vergisst man nämlich einmal ein Istgleich-Zeichen bei einer if-Bedingung, wird in der nicht empfohlenen Schreibweise der Variablen $himmel
der Wert blau
zugewiesen:
<?php
// Ein Istgleich-Zeichen wurde vergessen. $himmel wird 'blau' zugewiesen.
if ( $himmel = 'blau' ) eine_funktion();
?>
Das Problem dabei ist, dass die if-Abfrage (meist unbeabsichtigt) immer true
ergibt, die Funktion eine_funktion()
also immer ausgeführt wird. Der Code gibt also keinen Fehler zurück und funktioniert einwandfrei, während hingegen der Yoda-Style einen PHP-Parse-Error erzeugen würde:
<?php
// Empfohlen: Hier wird das Script gestoppt
if ( 'blau' = $himmel ) eine_funktion();
?>
Weitere nützliche Code-Stile finden Sie z.B. hier: http://www.codinghorror.com/blog/2012/07/new-programming-jargon.html. Sie sind aber nicht Bestandteil des Core Contributor Handbuchs von WordPress und sind daher nur am Rande erwähnt.
- http://www.phpbench.com/ Stand: 2. Januar 2014. ↩︎
- http://www.php.net/ChangeLog-5.php#5.3.0 Stand: 3. Januar 2014 ↩︎
- http://www.php.net/ChangeLog-5.php#5.5.0 Stand: 3. Januar 2014 ↩︎
Ich habe hier ein Frage bezüglich der Funktionen. Im Internet habe ich des öfteren gelesen, dass die Funktion zuerst kommen muss bevor sie aufgerufen wird, weil sie sonst noch nicht geladen wurde. PHP ist ja eine Serverscriptsprache und dieses Statement würde aber meinen Kenntnissen von PHP wiedersprechen. Den es ist ja möglich alle funktionen zu Schluss, an Anfang zu schreiben oder auszulagern. Was stimmt hier?
So lange die Funktion in der selben Datei deklariert wurde, ist es egal, ob man sie vorher oder nachher aufruft. PHP liest nämlich zuerst die ganze Datei ein, parst sie und verarbeitet sie dann.
So etwas wie das hier würde also nicht funktionieren:
Während das hier einwandfrei klappt: