Der Unterschied zwischen „||“ und „or“ bzw. „&&“ und „and“
Wenn man eine if-Anweisung in PHP schreiben möchte, und dabei 2 Bedingungen mit einem „und“ verknüpfen möchte, kann man entweder „&&“ nutzen oder „and“ schreiben. Richtig?
if ($a > 0 && $b < 100) {
if ($a > 0 and $b < 100) {
Das ist das selbe, oder? Ja, ist es. Beides funktioniert, beides ist syntaktisch korrekt, und beides ist äquivalent.
Kopieren wir nun die Bedingungen in eine temporäre Variable $c:
$c = $a > 0 && $b < 100; if ($c) {
$c = $a > 0 and $b < 100; if ($c) {
DAS ist nun nicht mehr das selbe!
Schauen wir uns das in einer einfacheren Zuweisung an:
$a = true; $b = false; $bool = $a && $b; var_dump($bool); // false, wie erwartet $bool = $a and $b; var_dump($bool); // true ?!?
Mir war der Unterschied nicht bekannt, bis vor einigen Wochen auf der PHP-Internals-Liste über das Thema Unifying logical operators diskutiert wurde. Ryan „Iggy“ Volz schlägt vor, diesen nicht erwarteten Unterschied zu entfernen, „and“ solle in Zukunft ein Alias für „&&“ sein, „or“ ein Alias für „||“. Einen Entwurf eines RFC hat er vorbereitet.
Doch woher kommt der Unterschied?
Schuld daran ist die Operator precedence:
&& bzw. || sind höher in der Reihenfolge als das Gleichheitszeichen „=“. „and“ bzw. „or“ sind niedriger als „=“. Das führt zur beobachteten unterschiedlichen Gruppierung der Operanden.
Hier eine schöne Übersicht:
$bool = FALSE || TRUE; - interpreted as ($bool = (FALSE || TRUE)) - value of $bool is TRUE $bool = FALSE OR TRUE; - interpreted as (($bool = FALSE) OR TRUE) - value of $bool is FALSE $bool = TRUE && FALSE; - interpreted as ($bool = (TRUE && FALSE)) - value of $bool is FALSE $bool = TRUE AND FALSE; - interpreted as (($bool = TRUE) AND FALSE) - value of $bool is TRUE
Der Unterschied ist in der „interpreted as“ Zeile zu sehen: Einmal werden erst die beiden linken Operanden verarbeitet, dann bei Bedarf der rechte, und einmal werden erst die beiden rechten Operanden verarbeitet, und dann per Zuweisung in die Variable geschrieben.
Ich muss zugeben, sehr selten ein „or“ bzw. „and“ in PHP-Code zu sehen, aber in altem Code sieht man es ab und zu. Entweder weil es jemand schöner findet, oder weil er mit anderen Sprachen durcheinander gekommen ist, in denen „and“ bzw. „or“ genutzt werden (SQL ist ein bekanntes Beispiel). Häufig funktioniert es ohne Probleme, z.B. in if-Anweisungen, aber bei Zuweisungen ist Vorsicht angesagt.
Ich glaube nicht, dass eine Änderung des aktuellen Verhaltens angegangen wird, die Diskussion ist zum Erliegen gekommen, sie ging eher hin zu „das war noch nie ein großes Problem“, „es wird genutzt in diversen Projekten, die Änderung macht alle diese Projekte unnötigerweise kaputt“, und „ich finde es toll, dass es diese beiden Schreibweisen gibt“. Es wird also vermutlich kein Aliasing geben, und alles bleibt so wie es ist.