PHP: Was bedeutet dieses Zeichen?
Nach einem Sonderzeichen zu suchen ist mühsam. Genau deshalb stolpert man in fremdem PHP-Code immer wieder über Operatoren, die man nicht einordnen kann. Dieser Artikel geht die durch, bei denen das am häufigsten passiert.
Alle Ausgaben in diesem Artikel stammen aus einem Skript das ich gegen PHP 8.5.9 laufen lassen habe.
== und === (Type Juggling)
== vergleicht nach einer automatischen Typumwandlung, === vergleicht
zusätzlich den Datentyp:
'1' == '01' => true
'10' == '1e1' => true
100 == '1e2' => true
'1' === '01' => false
Zwei numerische Strings werden also als Zahlen verglichen. Achtung, ein Klassiker hat sich mit PHP 8 geändert:
0 == 'a' => false
Vor PHP 8 war das true. Der String wurde damals nach int umgewandelt, was 0
ergab. Seit PHP 8 wird stattdessen die Zahl in einen String umgewandelt. Steht
in einem älteren Tutorial etwas anderes, ist das der Grund.
Im Zweifelsfall nimmst du ===.
?: und ?? sind nicht dasselbe
Das ist der Punkt, bei dem die meisten hereinfallen, und er steht sogar auf
Stack Overflow falsch. Die Kurzschreibweise des Ternary (?:, oft “Elvis
Operator” genannt) prüft auf truthy. Der Null Coalescing Operator (??,
seit PHP 7) prüft auf null:
<?php
$zero = 0;
echo $zero ?: 'Ersatzwert'; // 'Ersatzwert' -- 0 ist falsy
echo $zero ?? 'Ersatzwert'; // 0 -- 0 ist nicht null
?>
Bei 0, '' oder [] verhalten sich die beiden also unterschiedlich. Dazu
kommt: ?? unterdrückt zusätzlich die Warnung bei nicht existierenden
Array-Schlüsseln, ?: nicht.
<?php
$arr = [];
echo $arr['fehlt'] ?? 'Standard'; // 'Standard', keine Warnung
?>
?? lässt sich auch verketten. Der erste Wert der existiert und nicht null
ist, gewinnt:
<?php
$name = $_GET['user'] ?? $_POST['user'] ?? 'niemand';
?>
Seit PHP 7.4 gibt es dazu die Zuweisung ??=. Sie setzt einen Wert nur dann,
wenn er noch nicht gesetzt ist:
<?php
$config = ['host' => 'localhost'];
$config['port'] ??= 3306; // wird gesetzt
$config['host'] ??= 'wird ignoriert'; // bleibt 'localhost'
?>
?-> Nullsafe Operator
Seit PHP 8.0. Der Operator bricht die Kette ab und liefert null, statt einen
Fehler zu werfen:
$mitName?->name?->first => 'Ada'
$ohneName?->name?->first => NULL
Damit ersparst du dir verschachtelte Prüfungen. Ein Detail: Auf Array-Schlüssel wirkt der Operator nicht, dort bekommst du weiterhin eine Warnung.
<=> Spaceship Operator
Seit PHP 7.0. Er vergleicht in eine Richtung und gibt 0, einen negativen oder
einen positiven Wert zurück:
1 <=> 2 => -1
2 <=> 1 => 1
"a" <=> "a" => 0
[1,2,3] <=> [1,2,4] => -1
Der Hauptanwendungsfall sind Vergleichsfunktionen, etwa bei usort():
<?php
$zahlen = [4, 2, 1, 3];
usort($zahlen, fn($a, $b) => $a <=> $b); // [1, 2, 3, 4]
?>
Ein häufiger Fehler ist es, stattdessen $a - $b zu schreiben. Das geht schief,
sobald Fließkommazahlen im Spiel sind, weil usort() den Rückgabewert nach int
wandelt. Der Unterschied zwischen 4 und 4.6 wird damit zu 0, also
“gleich”.
… die drei Punkte
Die drei Punkte machen je nach Position drei verschiedene Dinge.
Variadische Parameter (seit PHP 5.6), also beliebig viele Argumente:
<?php
function summe(int ...$zahlen): int {
return array_sum($zahlen);
}
echo summe(1, 2, 3); // 6
?>
Argument Unpacking, also ein Array auseinandernehmen:
summe(...[10, 20, 30]) => 60
Mit assoziativen Arrays funktioniert das wie benannte Argumente, die Reihenfolge spielt dann keine Rolle mehr:
fullName(...['last' => 'Lovelace', 'first' => 'Ada']) => 'Ada Lovelace'
First Class Callable Syntax (seit PHP 8.1). Damit machst du aus einer Funktion einen Wert:
<?php
$upper = strtoupper(...);
echo $upper('abc'); // ABC
?>
=> und -> und ::
Diese drei werden gerne verwechselt.
=> trennt in einem Array Schlüssel und Wert:
<?php
$arr = ['year' => 2026];
echo $arr['year']; // 2026
?>
-> greift auf etwas an einem Objekt zu, :: auf etwas an der Klasse
selbst (Konstanten, statische Methoden und Eigenschaften):
<?php
echo (new Counter)->value; // Instanz
echo Counter::START; // Konstante
echo Counter::make()->value; // statische Methode
?>
. und + bei Arrays
Der Punkt verkettet Strings. Bei Arrays ist + aber nicht dasselbe wie
array_merge():
[1,2] + [9,9,9] => [1, 2, 9]
array_merge([1,2], [9,9,9]) => [1, 2, 9, 9, 9]
+ ist die Vereinigungsmenge: Ein Schlüssel der links schon existiert, wird
rechts nicht übernommen. array_merge() nummeriert numerische Schlüssel neu
und verliert daher nichts.
@ Fehlerkontrolloperator
Das @ unterdrückt Fehlermeldungen eines Ausdrucks:
@file_get_contents('/gibt/es/nicht') => false
Die Warnung ist weg, aber der Aufruf ist trotzdem fehlgeschlagen. Genau das ist
das Problem: Man sieht nicht mehr, dass etwas schief gegangen ist, muss den
Rückgabewert aber weiterhin prüfen. Nutze @ also möglichst gar nicht.
«< Heredoc und Nowdoc
Beide erlauben mehrzeilige Strings. Der Unterschied liegt in den Anführungszeichen um den Bezeichner:
Heredoc (<<<TXT) => 'hello world'
Nowdoc (<<<'TXT') => 'hello $who'
Heredoc verhält sich wie ein String in doppelten Anführungszeichen und setzt Variablen ein. Nowdoc verhält sich wie einfache Anführungszeichen und lässt alles stehen.
|> Pipe Operator
Neu in PHP 8.5. Er reicht das Ergebnis nach rechts weiter, sodass man verschachtelte Aufrufe von links nach rechts lesen kann:
<?php
$titel = ' PHP 8.5 Released ';
$slug = $titel
|> trim(...)
|> (fn($s) => str_replace(' ', '-', $s))
|> (fn($s) => str_replace('.', '', $s))
|> strtolower(...);
// 'php-85-released'
?>
Vor PHP 8.5 musste man dasselbe von innen nach außen schreiben:
<?php
$slug = strtolower(str_replace('.', '', str_replace(' ', '-', trim($titel))));
?>
** und %
** ist die Potenz (seit PHP 5.6), % der Rest einer Division:
2 ** 10 => 1024
7 % 3 => 1
-7 % 3 => -1
Beim Modulo richtet sich das Vorzeichen des Ergebnisses nach dem linken Operanden. Wer den Rest immer positiv braucht, kommt daran nicht vorbei.
Und der Rest?
Die vollständige Liste aller Zeichen findest du in der
Liste der Parser-Token im PHP
Handbuch. Nicht behandelt haben wir hier bewusst die Bit-Operatoren
(&, |, ^, ~, <<, >>) und die variablen Variablen ($$) — dazu
später vielleicht mehr.
Hinweis zu Netcup (Werbung)
Der deutsche Hoster Netcup bietet unter anderem günstige und zugleich leistungsstarke Webhosting Pakete, KVM-basierte Root Server und dezidierte Server an. Mit unseren Gutscheincodes kannst du noch mehr Geld sparen (6€ bei deiner ersten Bestellung, 30% Rabatt auf alle KVM-basierten Root Server, ...).