1. Einleitung
Ein häufig wiederkehrendes Problem im Programmieralltag ist das Zuweisen von Default-Werten, falls Variablen nicht definiert sind oder inkorrekte Werte haben. Das Problem lässt sich wiederum aufsplitten in
- Variablen, die potenziell NULL sein können (typisch für optionale Funktionsparameter).
- Variablen, die potenziell nicht definiert sein können (typisch für $_GET und $_POST).
Es gibt für beide Szenarien mehrere Wege, um Default-Werte einfach zuzuweisen. Das Mittel der Wahl ist jedoch in beiden Fällen der bedingte Ausdruck, da dieser flexibel und gleichzeitig gut lesbar ist:
<?php $var = null; $var = ($var!==null ? $var : 'default-Wert'); $_GET['var'] = (isset($_GET['var']) ? $_GET['var'] : 'default-Wert'); var_dump($var, $_GET['var']); ?>
string(12) "default-Wert" string(12) "default-Wert"
2. Default-Werte für Variablen, die NULL sein können
2.1. Bedingter Ausdruck
<?php // Variable hat NULL als Wert, soll auf default gesetzt werden $valueNull = null; $a = ($valueNull ? $valueNull : 1000); $b = ($valueNull!==null ? $valueNull : 1000); var_dump($valueNull, $a, $b); // Variable hat NICHT den Wert NULL und soll daher unveraendert bleiben $valueNotNull = 123; $a = ($valueNotNull ? $valueNotNull : 1000); $b = ($valueNotNull!==null ? $valueNotNull : 1000); var_dump($valueNotNull, $a, $b); ?>
NULL int(1000) int(1000) int(123) int(123) int(123)
2.2. Bedingter Ausdruck (verkürzte Syntax)
Seit PHP 5.3 gibt es den verkürzten bedingten Ausdruck. Die Schreibweise lautet: $var = ($var ?: default-Wert); Wichtig ist, dass der Default-Wert immer zugewiesen wird, wenn die Variable $var einen false-ähnlichen Wert annimmt. Diese Werte sind: (bool)false, (int)0, NULL, (string)"", (string)"0". Einen Ausdruck als Bedingung zu verwenden, wie man es aus dem normalen bedingten Ausdruck kennt, erzeugt unerwartete Ergebnisse und sollte daher vermieden werden (siehe Beispiel gegen Ende).
<?php // Variable hat NULL als Wert, soll auf default gesetzt werden $valueNull = null; $a = ($valueNull ?: 1000); $b = ($valueNull!==null ?: 1000); var_dump($valueNull, $a, $b); // Variable hat NICHT den Wert NULL und soll daher unveraendert bleiben $valueNotNull = 123; $a = ($valueNotNull ?: 1000); $b = ($valueNotNull!==null ?: 1000); // funktioniert nicht wie erwartet var_dump($valueNotNull, $a, $b); ?>
NULL int(1000) int(1000) int(123) int(123) bool(true)
2.3. if-else-Abfrage
<?php // Variable hat NULL als Wert, soll auf default gesetzt werden $valueNull = null; if ($valueNull===null) { $a = 1000; } else { $a = $valueNull; } var_dump($valueNull, $a); // Variable hat NICHT den Wert NULL und soll daher unveraendert bleiben $valueNotNull = 123; if ($valueNotNull===null) { $a = 1000; } else { $a = $valueNotNull; } var_dump($valueNotNull, $a); ?>
NULL int(1000) int(123) int(123)
2.4. OR-Syntax
PHP verfügt über einen speziellen logischen ODER-Operator „or”. Das besondere ist, dass er sehr schwach gewichtet ist und daher in einem Ausdruck nur „aktiv wird” wenn alles vor dem Operator fehlschlägt, also einen false-ähnlichen Wert zurückgibt. Daher lässt er sich verwenden, um Default-Werte festlegen zu können.
<?php // Variable hat NULL als Wert, soll auf default gesetzt werden $valueNull = null; $valueNull or $valueNull = 1000; var_dump($valueNull); $valueNull = null; $b = $valueNull or $b = 1000; var_dump($valueNull, $b); // Variable hat NICHT den Wert NULL und soll daher unveraendert bleiben $valueNotNull = 123; $valueNotNull or $valueNotNull = 1000; var_dump($valueNotNull); $valueNotNull = 123; $b = $valueNotNull or $b = 1000; var_dump($valueNotNull, $b); ?>
int(1000) NULL int(1000) int(123) int(123) int(123)
2.5. Eigene Funktion
Das Zuweisen eines Default-Werts kann gut in eine Funktion ausgelagert werden. Im nachfolgenden Beispiel nimmt die Funktion ifNull() eine Variable und einen Default-Wert entgegen. Ist die Variable NULL, gibt die Funktion den Default-Wert zurück, sonst den Wert der Variablen.
<?php function ifNull($var, $default) { return ($var===null ? $default : $var); } $valueNull = null; $valueNotNull = 123; $a = ifNull($valueNull, 1000); $b = ifNull($valueNotNull, 1000); var_dump($a, $b); ?>
int(1000) int(123)
2.6. Beispielhafte Anwendung
Das nächste Beispiel dient zur Darstellung eines möglichen Anwendungsfalls des Zuweisens von Default-Werten. Die Funktion echoMessage() im Beispiel dient dazu, eine Nachricht in beliebiger Farbe auszugeben. Dazu wird die Nachricht und die Farbe von der Funktion entgegen genommen. Der Parameter für die Farbe ($color) ist optional. Ist er nicht gesetzt, dann wird automatisch rot verwendet. Mit einem kleinen bedingten Ausdruck in verkürzter Syntax wird nun beim Aufruf der Funktion geprüft, ob der Parameter übergeben wurde. Falls nicht wird der Variable „red” zugewiesen, sonst wird sie beibehalten.
<?php function echoMessage($msg, $color=null) { $color = $color ?: 'red'; echo('<span style="color:'.$color.';">'.$msg.'</span>'."\n"); } echoMessage('Nachricht in blau', 'blue'); echoMessage('Nachricht in rot', 'red'); echoMessage('Nachricht mit Standardfarbe'); ?>
<span style="color:blue;">Nachricht in blau</span> <span style="color:red;">Nachricht in rot</span> <span style="color:red;">Nachricht mit Standardfarbe</span>
3. Default-Werte für Variablen, die evt. nicht definiert sind ($_GET/$_POST)
3.1. Bedingter Ausdruck
<?php // GET-Parameter ist nicht definiert, soll auf default gesetzt werden $id = (isset($_GET['id']) ? $_GET['id'] : -1); var_dump($id); // GET-Parameter ist definiert, soll nicht veraendert werden $_GET['id2'] = '115'; $id2 = (isset($_GET['id2']) ? $_GET['id2'] : -1); var_dump($id2); ?>
int(-1) string(3) "115"
3.2. Bedingter Ausdruck (verkürzte Syntax)
Der verkürzte bedingte Ausdruck lässt sich bei potenziell nicht definierten Variablen nicht anwenden. Verwendet man die Form „$var = ($var ?: default-Wert)”, dann erzeugt PHP einen Fehler, falls $var nicht definiert ist. Verwendet man stattdessen die Form „$var = (isset($var) ?: default-Wert)”, dann wird der Variable (bool)true zugewiesen, falls sie definiert ist.
<?php error_reporting(E_ALL); // --- mit isset() --- // (isset($var) ?: default) // GET-Parameter ist nicht definiert, soll auf default gesetzt werden $_GET['id'] = (isset($_GET['id']) ?: -1); var_dump($_GET['id']); // GET-Parameter ist definiert, soll nicht veraendert werden $_GET['id2'] = '115'; $_GET['id2'] = (isset($_GET['id2']) ?: -1); // funktioniert nicht wie erwartet var_dump($_GET['id2']); // --- ohne isset() --- // ($var ?: default) // GET-Parameter ist nicht definiert, soll auf default gesetzt werden $_GET['id3'] = ($_GET['id3'] ?: -1); // erzeugt einen Fehler, da der Index nicht gesetzt ist var_dump($_GET['id3']); // GET-Parameter ist definiert, soll nicht veraendert werden $_GET['id4'] = '115'; $_GET['id4'] = ($_GET['id4'] ?: -1); var_dump($_GET['id4']); ?>
int(-1) bool(true) <br /> <b>Notice</b>: Undefined index: id3 in <b>...\test.php</b> on line <b>21</b><br /> int(-1) string(3) "115"
3.3. if-else-Abfrage
<?php // GET-Parameter ist nicht definiert, soll auf default gesetzt werden if (!isset($_GET['id'])) { $_GET['id'] = -1; } var_dump($_GET['id']); // GET-Parameter ist definiert, soll nicht veraendert werden $_GET['id2'] = '115'; if (!isset($_GET['id2'])) { $_GET['id2'] = -1; } var_dump($_GET['id2']); ?>
int(-1) string(3) "115"
3.4. OR-Syntax
Wie im nächsten Beispiel zu sehen ist, lässt sich die OR-Syntax nicht zuverlässig bei potenziell nicht definierten Variablen verwenden. Ist eine so geprüfte Variable nicht definiert, erzeugt PHP automatisch eine Fehlermeldung.
<?php // GET-Parameter ist nicht definiert, soll auf default gesetzt werden $_GET['id'] or $_GET['id'] = -1; // erzeugt einen Fehler $_GET['id2'] = $_GET['id2'] or $_GET['id2'] = -1; // erzeugt einen Fehler var_dump($_GET['id'], $_GET['id2']); // GET-Parameter ist definiert, soll nicht veraendert werden $_GET['id3'] = '115'; $_GET['id3'] or $_GET['id3'] = -1; $_GET['id4'] = $_GET['id4'] or $_GET['id4'] = -1; // erzeugt einen Fehler var_dump($_GET['id3'], $_GET['id4']); ?>
<br /> <b>Notice</b>: Undefined index: id in <b>...\test.php</b> on line <b>3</b><br /> <br /> <b>Notice</b>: Undefined index: id2 in <b>...\test.php</b> on line <b>4</b><br /> int(-1) int(-1) <br /> <b>Notice</b>: Undefined index: id4 in <b>...\test.php</b> on line <b>10</b><br /> string(3) "115" int(-1)
3.5. Eigene Funktion
Nachfolgend wird versucht, eine Funktion aufzustellen, die einzelnen GET-Parametern Default-Werte zuweist. Die Funktion ifNotSet() erwartet eine eventuell nicht gesetzte Variable und einen Default-Wert. Sie gibt den Default-Wert zurück, falls die Variable nicht gesetzt ist und gibt sie andernfalls zurück. Wie man sich denken kann und wie auch im Beispiel zu sehen ist, entstehen bei der Anwendung Fehler, denn um die Variable zu übergeben muss diese zunächst einmal definiert sein. Entsprechend beklagt sich PHP darüber, dass das nicht immer der Fall ist.
<?php function ifNotSet($var, $default) { return (isset($var) ? $var : $default); } // GET-Parameter ist nicht definiert, soll auf default gesetzt werden $_GET['id'] = ifNotSet($_GET['id'], -1); // erzeugt einen Fehler // GET-Parameter ist definiert, soll nicht veraendert werden $_GET['id2'] = '115'; $_GET['id2'] = ifNotSet($_GET['id2'], -1); var_dump($_GET['id'], $_GET['id2']); ?>
<br /> <b>Notice</b>: Undefined index: id in <b>...\test.php</b> on line <b>7</b><br /> int(-1) string(3) "115"
Die nachfolgende Funktion dient zum Setzen von Default-Werten im GET-Array. Sie nimmt den Namen des Schlüssels im GET-Array und einen Default-Wert entgegen. Anschließend prüft sie, ob der übergebene Schlüssel im GET-Array bereits einen Wert hat und lässt diesen unverändert, falls das der Fall ist. Andernfalls wird der Default-Wert zugewiesen. Im Gegensatz zu den anderen Funktionen wird also kein Wert per „return” zurückgegeben.
<?php function defaultGET($key, $default) { if (!isset($_GET[$key])) { $_GET[$key] = $default; } } $_GET['id2'] = '115'; defaultGET('id', -1); defaultGET('id2', -1); var_dump($_GET['id'], $_GET['id2']); ?>
int(-1) string(3) "115"