## Vergleichs-Operatoren

Vergleichs-Operatoren erlauben es – wie der Name schon sagt – zwei Werte zu vergleichen. Wenn Sie an Beispielen verschiedener auf Typen bezogener Vergleiche interessiert sind, können Sie sich die PHP Typvergleich-Tabellen anschauen.

Vergleichsoperatoren
Beispiel Name Ergebnis
\$a == \$b Gleich Gibt `true` zurück, wenn nach der Typumwandlung \$a gleich \$b ist.
\$a === \$b Identisch Gibt `true` zurück, wenn \$a gleich \$b ist und beide denselben Typ haben.
\$a != \$b Ungleich Gibt `true` zurück, wenn nach der Typumwandlung \$a nicht gleich \$b ist.
\$a <> \$b Ungleich Gibt `true` zurück, wenn nach der Typumwandlung \$a nicht gleich \$b ist.
\$a !== \$b Nicht identisch Gibt `true` zurück, wenn \$a nicht gleich \$b ist, oder wenn beide nicht denselben Typ haben.
\$a < \$b Kleiner als Gibt `true` zurück, wenn \$a kleiner als \$b ist.
\$a > \$b Größer als Gibt `true` zurück, wenn \$a größer als \$b ist.
\$a <= \$b Kleiner oder gleich Gibt `true` zurück, wenn \$a kleiner oder gleich \$b ist.
\$a >= \$b Größer oder gleich Gibt `true` zurück, wenn \$a größer oder gleich \$b ist.
\$a <=> \$b Raumschiff Eine Ganzzahl (int), die kleiner als, gleich oder größer als 0 ist, wenn \$a kleiner als, gleich oder größer als \$b ist.

Falls beide Operanden numerische Zeichenketten sind oder ein Operand eine Zahl ist und der andere eine numerische Zeichenkette, dann wird der Vergleich numerisch durchgeführt. Diese Regel gilt ebenfalls für die switch-Anweisung. Die Typumwandlung wird nicht durchgeführt, wenn der Vergleichsoperator `===` oder `!==` ist, da hier sowohl der Typ als auch der Wert verglichen werden.

Warnung

Vor PHP 8.0.0 wurde bei einem Vergleich einer Zeichenkette mit einer Zahl oder einer numerischen Zeichenkette die Zeichenkette vor dem Vergleich in eine Zahl umgewandelt und der Vergleich numerisch durchgeführt.

``` <?phpvar_dump(0 == "a");var_dump("1" == "01");var_dump("10" == "1e1");var_dump(100 == "1e2");switch ("a") {case 0: echo "0"; break;case "a": echo "a"; break;}?> ```

Das oben gezeigte Beispiel erzeugt mit PHP 7 folgende Ausgabe:

```bool(true)
bool(true)
bool(true)
bool(true)
0
```

Das oben gezeigte Beispiel erzeugt mit PHP 8 folgende Ausgabe:

```bool(false)
bool(true)
bool(true)
bool(true)
a
```

``` <?php// Ganzzahlenecho 1 <=> 1; // 0echo 1 <=> 2; // -1echo 2 <=> 1; // 1// Gleitkommazahlenecho 1.5 <=> 1.5; // 0echo 1.5 <=> 2.5; // -1echo 2.5 <=> 1.5; // 1// Zeichenkettenecho "a" <=> "a"; // 0echo "a" <=> "b"; // -1echo "b" <=> "a"; // 1echo "a" <=> "aa"; // -1echo "zz" <=> "aa"; // 1// Arraysecho [] <=> []; // 0echo [1, 2, 3] <=> [1, 2, 3]; // 0echo [1, 2, 3] <=> []; // 1echo [1, 2, 3] <=> [1, 2, 1]; // 1echo [1, 2, 3] <=> [1, 2, 4]; // -1// Objekte\$a = (object) ["a" => "b"];\$b = (object) ["a" => "b"];echo \$a <=> \$b; // 0\$a = (object) ["a" => "b"];\$b = (object) ["a" => "c"];echo \$a <=> \$b; // -1\$a = (object) ["a" => "c"];\$b = (object) ["a" => "b"];echo \$a <=> \$b; // 1// nicht nur die Werte werden verglichen; die Schlüssel müssen übereinstimmen\$a = (object) ["a" => "b"];\$b = (object) ["b" => "b"];echo \$a <=> \$b; // 1?> ```

Für die verschiedenen Typen wird der Vergleich gemäß der folgenden Tabelle durchgeführt (in der angegebenen Reihenfolge).

Vergleich mit verschiedenen Typen
Typ des 1. Operanden Typ des 2. Operanden Ergebnis
null oder string string Umwandlung von `null` nach "", dann numerischer oder lexikalischer Vergleich
bool oder null anything Umwandlung beider Werte nach bool, dann `false` < `true`
object object Eingebaute Klassen können eigene Vergleichsregeln definieren; verschiedene Klassen können nicht verglichen werden; für den Vergleich von Objekten derselben Klasse siehe Objektvergleiche
string, resource, int oder float string, resource, int oder float Umwandlung von Zeichenketten und Ressourcen in Zahlen, dann numerischer Vergleich
array array Das Array mit weniger Elementen ist kleiner; wird ein Schlüssel vom ersten Operanden nicht im zweiten gefunden, dann sind die Arrays nicht vergleichbar, andernfalls wird Element für Element verglichen (siehe folgendes Beispiel)
object anything object ist immer größer
array anything array ist immer größer

Beispiel #1 Boolesche und null-Vergleiche

``` <?php// Boolesche Werte und null werden immer als Boolesche Werte verglichenvar_dump(1 == TRUE); // TRUE - dasselbe wie (bool)1 == TRUEvar_dump(0 == FALSE); // TRUE - dasselbe wie (bool)0 == FALSEvar_dump(100 < TRUE); // FALSE - dasselbe wie (bool)100 < TRUEvar_dump(-10 < FALSE);// FALSE - dasselbe wie (bool)-10 < FALSEvar_dump(min(-100, -10, NULL, 10, 100)); // NULL - (bool)NULL < (bool)-100 ist FALSE < TRUE?> ```

Beispiel #2 Umschreibung von Standard-Array-Vergleichen

``` <?php// Arrays werden mit den normalen Vergleichsoperatoren sowie dem Raumschiff-Operator wie folgt verglichenfunction standard_array_compare(\$op1, \$op2){ if (count(\$op1) < count(\$op2)) { return -1; // \$op1 < \$op2 } elseif (count(\$op1) > count(\$op2)) { return 1; // \$op1 > \$op2 } foreach (\$op1 as \$key => \$val) { if (!array_key_exists(\$key, \$op2)) { return 1; } elseif (\$val < \$op2[\$key]) { return -1; } elseif (\$val > \$op2[\$key]) { return 1; } } return 0; // \$op1 == \$op2}?> ```

Warnung

# Vergleich von Gleitkommazahlen

Aufgrund der Art wie Gleitkommazahlen (float) intern dargestellt werden, sollten zwei Gleitkommazahlen nicht auf Gleichheit getestet werden.

Weitere Informationen sind der Dokumantation von float zu entnehmen.

Hinweis: Es ist wichtig zu beachten, dass die Typumwandlung von PHP nicht immer offensichtlich ist, wenn Werte unterschiedlichen Typs verglichen werden, insbesondere beim Vergleich von Integern mit Booleans oder Integern mit Strings. Daher ist es im Allgemeinen in den meisten Fällen ratsam, `===` und `!==` für Vergleiche zu verwenden, anstatt `==` und `!=`.

### Nicht vergleichbare Werte

Während der Identitätsvergleich (`===` und `!==`) auf beliebige Werte angewendet werden kann, sollten die anderen Vergleichsoperatoren nur auf vergleichbare Werte angewandt werden. Wenn nicht vergleichbare Werte verglichen werden, ist das Ergebnis undefiniert und sollte nicht als verlässlich eingestuft werden.

### Ternärer Operator

Ein weiterer Vergleichs-Operator ist der "?:" (oder ternäre) Operator.

Beispiel #3 Zuweisen eines Standardwerts

``` <?php// Beispielanwendung für den ternären Operator\$action = (empty(\$_POST['action'])) ? 'standard' : \$_POST['action'];// Obiges ist mit dieser if/else-Anweisung identischif (empty(\$_POST['action'])) { \$action = 'standard';} else { \$action = \$_POST['action'];}?> ```
Der Ausdruck `(ausdr1) ? (ausdr2) : (ausdr3)` wird zu ausdr2 ausgewertet, wenn ausdr1 als `true` ausgewertet wird, und zu ausdr3, wenn ausdr1 zu `false` ausgewertet wird.

Beim ternären Operator kann der mittlere Teil weggelassen werden. Der Ausdruck `(ausdr1) ?: (ausdr3)` wird zum Ergebnis von ausdr1 zurück, wenn ausdr1 zu `true` ausgewertet wird, und zu ausdr3 andernfalls. ausdr1 wird in diesem Fall nur einmal ausgewertet.

Hinweis: Es ist zu beachten, dass der ternäre Operator ein Ausdruck ist und nicht als Variable, sondern als Wert eines Ausdrucks ausgewertet wird. Dies ist unbedingt zu berücksichtigen, wenn eine Variable per Referenz zurückgegeben werden soll. Die Anweisung ```return \$var == 42 ? \$a : \$b;``` in einer Funktion, die per Referenz zurückgibt, wird daher nicht funktionieren und eine Warnung erzeugen.

Hinweis:

Es wird empfohlen, die "Verschachtelung" von ternären Ausdrücken zu vermeiden. Das Verhalten von PHP bei der Verwendung von mehr als einem nicht einkgeklammerten ternären Operator innerhalb eines einzigen Ausdrucks ist im Vergleich zu anderen Sprachen nicht eindeutig. In der Tat wurden ternäre Ausdrücke vor PHP 8.0.0 links-assoziativ (von links nach rechts) ausgewertet, und nicht rechts-assoziativ wie in den meisten anderen Programmiersprachen. Die Links-Assoziativität ist seit PHP 7.4.0 veraltet. Seit PHP 8.0.0 ist der ternäre Operator nicht-assoziativ.

Beispiel #4 Ungewöhnliches Verhalten des ternären Operators

``` <?php// auf den ersten Blick scheint das folgende 'true' auszugebenecho (true ? 'true' : false ? 't' : 'f');// allerdings wird vor PHP 8.0.0 tatsächlich 't' ausgegeben// das kommt daher, dass ternäre Ausdrücke links-assoziativ ausgewertet werden// das Folgende ist eine augenfälligere Variante desselben Codes wie obenecho ((true ? 'true' : false) ? 't' : 'f');// hier kann man sehen, dass der erste Ausdruck zu 'true' ausgewertet wird,// was wiederum zu (bool)true ausgewertet wird, und daher wird der Wahr-Zweig// des zweiten ternären Ausdrucks zurückgegeben.?> ```

Hinweis:

Die Verkettung von kurzen ternären Operatoren (`?:`) ist jedoch stabil und verhält sich plausibel. Sie wird zum ersten Argument ausgewertet, das einen nicht-falschen Wert ergibt. Es ist zu beachten, dass undefinierte Werte immer noch eine Warnung auslösen.

Beispiel #5 Verkettung kurzer ternärer Operatoren

``` <?phpecho 0 ?: 1 ?: 2 ?: 3, PHP_EOL; //1echo 0 ?: 0 ?: 2 ?: 3, PHP_EOL; //2echo 0 ?: 0 ?: 0 ?: 3, PHP_EOL; //3?> ```

### Null-Koaleszens-Operator

Eine weitere nützliche Kurzform eines Operators ist der Operator "??" (null-Koaleszenz-Operator, etwa: Zuweisungsoperator für die Kombination mit null).

Beispiel #6 Zuweisung eines Standardwerts

``` <?php// Beispiel für die Verwendung des null-Koaleszenz-Operators\$action = \$_POST['action'] ?? 'standard';// Obiges ist mit dieser if/else-Anweisung identischif (isset(\$_POST['action'])) { \$action = \$_POST['action'];} else { \$action = 'standard';}?> ```
Der Ausdruck `(ausdr1) ?? (ausdr2)` wird zu ausdr2 ausgewertet, wenn ausdr1 `null` ist, und zu ausdr1 andernfalls.

Insbesondere gibt dieser Operator keinen Hinweis und keine Warnung aus, wenn der Wert auf der linken Seite nicht existiert, genau wie isset(). Dies ist besonders für Array-Schlüssel nützlich.

Hinweis: Es ist zu beachten, dass der null-Koaleszenz-Operator ein Ausdruck ist und nicht als Variable, sondern als Wert eines Ausdrucks ausgewertet wird. Dies ist unbedingt zu berücksichtigen, wenn eine Variable per Referenz zurückgegeben werden soll. Die Anweisung ```return \$foo ?? \$bar;``` in einer Funktion, die per Referenz zurückgibt, wird daher nicht funktionieren, und eine Warnung erzeugen.

Hinweis:

Der null-Koaleszenz-Operator hat eine niedrige Priorität. Das heißt, wenn er mit anderen Operatoren (z. B. Verkettung von Zeichenketten oder arithmetische Operatoren) kombiniert wird, sind wahrscheinlich Klammern erforderlich.

``` <?php// Löst die Warnung aus, dass \$name undefiniert ist.print 'Mr. ' . \$name ?? 'Anonymous';// Gibt "Mr. Anonymous" ausprint 'Mr. ' . (\$name ?? 'Anonymous');?> ```

Hinweis:

Es ist zu beachten, dass der null-Koaleszenz-Operator einfach verschachtelt werden kann:

Beispiel #7 Verschachtelung des null-Koaleszenz-Operators

``` <?php\$foo = null;\$bar = null;\$baz = 1;\$qux = 2;echo \$foo ?? \$bar ?? \$baz ?? \$qux; // gibt 1 aus?> ```

### User Contributed Notes 11 notes

164
crazy888s at hotmail dot com
12 years ago
``` I couldn't find much info on stacking the new ternary operator, so I ran some tests:<?phpecho 0 ?: 1 ?: 2 ?: 3; //1echo 1 ?: 0 ?: 3 ?: 2; //1echo 2 ?: 1 ?: 0 ?: 3; //2echo 3 ?: 2 ?: 1 ?: 0; //3echo 0 ?: 1 ?: 2 ?: 3; //1echo 0 ?: 0 ?: 2 ?: 3; //2echo 0 ?: 0 ?: 0 ?: 3; //3?>It works just as expected, returning the first non-false value within a group of expressions. ```
22
16 years ago
``` Note: according to the spec, PHP's comparison operators are not transitive.  For example, the following are all true in PHP5: "11" < "a" < 2 < "11" As a result, the outcome of sorting an array depends on the order the elements appear in the pre-sort array.  The following code will dump out two arrays with *different* orderings: <?php \$a = array(2,    "a",  "11", 2); \$b = array(2,    "11", "a",  2); sort(\$a); var_dump(\$a); sort(\$b); var_dump(\$b); ?> This is not a bug report -- given the spec on this documentation page, what PHP does is "correct".  But that may not be what was intended... ```
18
rshawiii at yahoo dot com
17 years ago
``` You can't just compare two arrays with the === operator like you would think to find out if they are equal or not.  This is more complicated when you have multi-dimensional arrays.  Here is a recursive comparison function. <?php /** * Compares two arrays to see if they contain the same values.  Returns TRUE or FALSE. * usefull for determining if a record or block of data was modified (perhaps by user input) * prior to setting a "date_last_updated" or skipping updating the db in the case of no change. * * @param array \$a1 * @param array \$a2 * @return boolean */ function array_compare_recursive(\$a1, \$a2) {    if (!(is_array(\$a1) and (is_array(\$a2)))) { return FALSE;}           if (!count(\$a1) == count(\$a2))       {        return FALSE; // arrays don't have same number of entries       }          foreach (\$a1 as \$key => \$val)    {        if (!array_key_exists(\$key, \$a2))            {return FALSE; // uncomparable array keys don't match               }        elseif (is_array(\$val) and is_array(\$a2[\$key]))  // if both entries are arrays then compare recursive            {if (!array_compare_recursive(\$val,\$a2[\$key])) return FALSE;            }        elseif (!(\$val === \$a2[\$key])) // compare entries must be of same type.            {return FALSE;            }    }    return TRUE; // \$a1 === \$a2 } ?> ```
niall at maranelda dot org
5 years ago
``` Care must be taken when using the spaceship operator with arrays that do not have the same keys:- Contrary to the notes above ("Example #2 Transcription of standard array comparison"), it does *not* return null if the left-hand array contains a key that the right-hand array does not.- Because of this, the result depends on the order you do the comparison in.For example:<?php\$a = ['a' => 1, 'b' => 2, 'c' => 3, 'e' => 4];\$b = ['a' => 1, 'b' => 2, 'd' => 3, 'e' => 4];var_dump(\$a <=> \$b);        // int(1) : \$a > \$b because \$a has the 'c' key and \$b doesn't.var_dump(\$b <=> \$a);        // int(1) : \$b > \$a because \$b has the 'd' key and \$a doesn't.?> ```
13
bishop
16 years ago
``` When you want to know if two arrays contain the same values, regardless of the values' order, you cannot use "==" or "===".  In other words:<?php(array(1,2) == array(2,1)) === false;?>To answer that question, use:<?phpfunction array_equal(\$a, \$b) {    return (is_array(\$a) && is_array(\$b) && array_diff(\$a, \$b) === array_diff(\$b, \$a));}?>A related, but more strict problem, is if you need to ensure that two arrays contain the same key=>value pairs, regardless of the order of the pairs.  In that case, use:<?phpfunction array_identical(\$a, \$b) {    return (is_array(\$a) && is_array(\$b) && array_diff_assoc(\$a, \$b) === array_diff_assoc(\$b, \$a));}?>Example:<?php\$a = array (2, 1);\$b = array (1, 2);// true === array_equal(\$a, \$b);// false === array_identical(\$a, \$b);\$a = array ('a' => 2, 'b' => 1);\$b = array ('b' => 1, 'a' => 2);// true === array_identical(\$a, \$b)// true === array_equal(\$a, \$b)?>(See also the solution "rshawiii at yahoo dot com" posted) ```
Sumon Mahmud
3 years ago
``` Extending from here: https://www.php.net/manual/en/language.operators.comparison.php#121907\$a = ['a' => 1, 'b' => 2, 'c' => 3, 'e' => 4]; \$b = ['a' => 1, 'b' => 2, 'd' => 3, 'e' => 4];echo \$a > \$b; // 0echo \$b > \$a; // 0echo \$a <\$b; // 0echo \$b < \$a; // 0If using spaceship operator then it is returning true like : echo \$a <=> \$b; //1echo \$b <=> \$a; //1echo \$a <=> \$b; //1echo \$b <=> \$a; //1 ```
11
Cuong Huy To
11 years ago
``` In the table "Comparison with Various Types", please move the last line about "Object" to be above the line about "Array", since Object is considered to be greater than Array (tested on 5.3.3)(Please remove my "Anonymous" post of the same content before. You could check IP to see that I forgot to type my name) ```
Ryan Mott
3 years ago
``` Searching for "double question mark" operator should find this page (and hopefully after this comment the crawlers will agree) ```
Marcin Kuzawiski
7 years ago
``` A < B and still B < A...\$A = [1 => 1, 2 => 0, 3 => 1];\$B = [1 => 1, 3 => 0, 2 => 1];var_dump(\$A < \$B);  // TRUEvar_dump(\$B < \$A);  // TRUEvar_dump(\$A > \$B);  // TRUEvar_dump(\$B > \$A);  // TRUENext - C and D are comparable, but neither C < D nor D < C (and still C != D)...\$C = [1 => 1, 2 => 1, 3 => 0];\$D = [1 => 1, 3 => 1, 2 => 0];var_dump(\$C < \$D); // FALSEvar_dump(\$D < \$C); // FALSEvar_dump(\$C > \$D); // FALSEvar_dump(\$D > \$C); // FALSEvar_dump(\$D == \$C); // FALSE ```
Tahazzot
1 year ago
``` Very careful when reading PHP documentation, Here's a lot of miss information. According to documentation, They say's (int) 0 == (string) "a" is true. But it is not in PHP 8.var_dump(0 == "a"); // 0 == 0 -> trueNow In PHP 8 it's False. ```
admin at zeros dot co dot id
5 months ago
``` Please be careful when you try to compare strings that have a plus sign `+` at the beginning (such as phone number, etc). When you use the Equal operator `==` PHP will ignore the plus sign. Use Identical operator `===` insteadExample:\$str1 = "62";\$str2 = "+62";var_dump(\$str1 == \$str2); // bool(true)var_dump(\$str1 === \$str2); // bool(false) ``` 