PHP/Tutorials/Einstieg/Operatoren

Aus SELFHTML-Wiki
< PHP‎ | Tutorials‎ | Einstieg
Wechseln zu: Navigation, Suche

Erst durch die Verknüpfung von Werten aus unterschiedlichen Quellen (Konstanten, Variablen, Funktionsergebnisse) entsteht die volle Funktionalität eines PHP-Skripts. Jede Programmiersprache bietet dazu ein Set an Basisfunktionen (oder Operationen) an, die vom Programmierer sofort benutzt werden können. Die häufigsten dieser Operationen wie Addition, Multiplikation, Wertevergleich oder logische Verknüpfungen werden durch eine Kurzschreibweise realisiert, die man Operator nennt. Die Werte, auf die der Operator wirkt, nennt man Operanden.

Überblick

Grundsätzlich teilt man Operatoren danach ein, wie viele Werte sie verknüpfen können.

  1. unär: Der Operator wirkt nur auf einen einzigen Wert. Ein Beispiel dafür ist das Minuszeichen: -$a nimmt den Wert in der Variablen $a und gibt den Wert mit entgegengesetztem Vorzeichen zurück.
  2. binär: Dies sind die meisten Operatoren. Man schreibt sie, wie in der Mathematik, zwischen die Werte, die verknüpft werden sollen. Zum Beispiel: $a + $b addiert die Werte in den Variablen $a und $b
  3. ternär: Der ternäre Operator ?: ist ein Spezialfall in den Sprachen der C-Familie. Er stellt eine kompakte Form der IF-Abfrage zur Verfügung.

Operatoren erwarten, dass die ihnen übergebenen Werte bestimmte Datentypen haben. Der + Operator zum Beispiel ist dazu da, Zahlen zu addieren. Bekommt er etwas anderes, versucht PHP, diese anderen Werte in eine Zahl umzuwandeln. Ist das nicht möglich, endet das Script mit einem Fatal Error.

Das Ergebnis eines Operators ist ein neuer Wert, der überall dort verwendet werden kann, wo PHP Werte erwartet. Zum Beispiel auch als Eingabe für einen weiteren Operator.

Verwendung mehrerer Operatoren
<?php
echo $a + $b + $c;
?>

In diesem Beispiel würde PHP zunächst $a + $b verarbeiten. Die ermittelte Summe dient dann als Eingabe für den zweiten + Operator, der $c hinzuaddiert.

Werden in einer Programmiersprache Werte, Variablen und Operatoren eingesetzt, um neue Werte zu bestimmen, spricht man von einem Ausdruck (engl. Expression). Das hat nichts mit einem Drucker zu tun, sondern ist im Sinne von „sich ausdrücken, formulieren“ zu verstehen.

Zwei wichtige Eigenschaften von Operatoren, die Sie auch aus der Mathematik kennen, sind ihre Priorität und Assoziativität. Diese Eigenschaften legen fest, in welcher Reihenfolge die Operatoren in einem Ausdruck verarbeitet. Findet PHP in einem Ausdruck Operatoren mit unterschiedlicher Priorität vor, verarbeitet es diejenigen mit höherer Priorität zuerst. Ein Beispiel dafür ist die Regel "Punkt- vor Strichrechnung": 3 + 4 * 5 ergibt 23, nicht 35. Die Assoziativität kommt zum Tragen, wenn Operatoren mit gleicher Priorität auftreten. 9 - 3 - 2 könnte man als (9 - 3) - 2 = 4 oder 9 - (3 - 2) = 8 lesen. Der Minus-Operator ist links-assoziativ, das heißt: das linke Minus wird zuerst verarbeiten. 9 - 3 - 2 ergibt deshalb 4, wie man aus der Mathematik auch erwarten würde. Die meisten Operatoren sind links-assoziativ. Ein Beispiel für einen rechts-assoziativen Operator ist der ** Operator, mit dem man Potenzen berechnet. In der Mathematik würde 4 32 so berechnet, dass man zunächst 32 bestimmt und 9 erhält, und dann erst 49 rechnet. Dieses Verhalten zeigt auch PHP: 4 ** 3 ** 2 ergibt 262144, nicht 4096.

Wenn die von PHP durch Priorität und Assoziativität festgelegte Reihenfolge nicht dem entspricht, was Ihr Programm tun soll, können Sie Klammern setzen. Ein Ausdruck, der in Klammern steht, wird immer als erstes ausgewertet. Wenn Sie Klammern ineinander schachteln, wertet PHP die innerste Klammer zuerst aus.

Im Folgenden werden die wichtigsten PHP Operatoren angesprochen.

Arithmetische Operatoren

Numerische Berechnungen führen Sie mit Hilfe von Rechenoperatoren durch. Diese stehen für die Variablentypen integer und float zur Verfügung.

Notieren Sie zwischen den Operanden

  • zum Addieren das Pluszeichen +
  • zum Subtrahieren das Minuszeichen -
  • zum Multiplizieren den Stern *
  • zum Dividieren den Schrägstrich /
  • für Modulo-Berechnungen das Prozentzeichen %.
  • zum Potenzieren einen Doppelstern ** (ab PHP 5.6 verfügbar)

Um das Vorzeichen eines Wertes zu wechseln, setzen Sie ein - davor.

Es gelten die üblichen Rechenregeln. Das bedeutet: ** hat die höchste Priorität, * / % die zweithöchste und + - die niedrigste. Bei gleicher Priorität werden + - * / % von links nach rechts ausgeführt und ** von rechts nach links.

Wie in der Mathematik üblich, können Sie Klammern setzen, um eine andere Rangfolge der Operationen festzulegen.

für Berechnungen
var $zwei           = 1 + 1,
    $ergebnis       = $zahl1 + $zahl2,
    $Nix        = 81 / 3 - 27,
    $wenigerAlsNix  = 81 / (3 - 27),
    $SinnDesLebens  = 6 * 7,
    $ergibtAuchSinn = 84 / 2,
    $mitMinus       = 35 - -7;
    $wiederNix      = 36 * 37 % 666;
Im Beispiel werden verschiedene Variablen definiert und jeweils ein Rechenergebnis zugewiesen.
Beachten Sie das $mitMinus Beispiel. PHP kann das binäre und das unäre Minus aus dem Zusammenhang unterscheiden.

Zeichenketten-Operator

In PHP kann man mit dem Punktoperator . Zeichenketten verknüpfen (String-Verkettung oder String-Konkatenation).

Verkettung von Zeichenketten
<?php
echo 'self' . 'html'; // gibt den String "selfhtml" aus.
?>
Beachten Sie: PHP unterscheidet sich an dieser Stelle von anderen Programmiersprachen wie JavaScript. Die Stringverketttung in JavaScript erfolgt mittels des + Operators. Wenn Sie das in PHP tun('self' + 'html';), erhalten Sie als Ergebnis den Wert 0, da das + ausschließlich ein arithmetischer Operator ist, der die Zeichenketten in Zahlen umgewandelt und dann eine arithmetische Berechnung ausgeführt.

Wertzuweisungs-Operatoren

Wie schon im Abschnitt Grundlagen angesprochen, wird in PHP das Speichern von Werten in Variablen mit Hilfe des Wertzuweisungs-Operators = realisiert.

Zuweisen von Werten an Variablen
<?php
$a = 3;
$b = "Hallo selfhtml";
?>

Man nennt den Operanden rechts vom = den Donator, und den Wert links den Akzeptor.

Das Ergebnis des Zuweisungsoperators ist der zugewiesene Wert:

echo $a = 3;

würde 3 ausgeben.

Ein häufiges Konstrukt ist das Aktualisieren einer Variablen, z. B. indem man die um 1 erhöht, oder verdoppelt. Das kann man so schreiben:

$a = $a + 3;

Aus mathematischer Sicht liest sich das wie Unsinn, $a und $a+3 können nicht gleich sein. Aus diesem Grund wird die Wahl von = für die Wertzuweisung häufig kritisiert. Lesen Sie eine Zuweisung darum nicht als „$a ist gleich $a plus 3“, sondern als „$a wird zu $a plus 3“.

Wegen der Häufigkeit solcher Zuweisungen gibt es dafür eine Kurzschreibweise:

$a += 3;

Außer += gibt es auch -=, *= /= %= und .=

Vergleichsoperatoren

Vergleichsoperatoren dienen zum Vergleichen zweier Werte. Solche Vergleiche werden vor allem für bedingte Anweisungen und Schleifen benutzt. Als Ergebnis liefern Vergleichsoperatoren immer einen sogenannten booleschen Wert (Wahrheitswert) vom Typ boolean, d. h. entweder true (wahr) oder false (falsch).

Sie können z. B. den Inhalt einer Variablen mit dem Inhalt einer anderen oder mit dem Ergebnis eines Ausdrucks vergleichen, indem Sie den gewünschten Vergleichsoperator zwischen den beiden Operanden notieren:

Operator Bedeutung Ergebnis der Operation
> größer true, wenn der linke Wert größer als der rechte ist, sonst false.
>= größergleich true, wenn der linke Wert größer oder gleich dem rechten ist, sonst false.
< kleiner true, wenn der linke Wert kleiner als der rechte ist , sonst false.
<= kleinergleich true, wenn der linke Wert kleiner oder gleich dem rechten ist, sonst false.
== istgleich true, wenn die Werte gleich sind, sonst false.
=== strenges istgleich true, wenn die Werte gleich sind, sonst false. Siehe Hinweis unten.
 != ungleich true, wenn die Werte ungleich sind, sonst false.
 !== strenges ungleich true, wenn die Werte ungleich sind, sonst false.
<=> 3-Wege-Vergleich Ab PHP 7. Der 3-Wege-Vergleich, im PHP-Handbuch auch „Raumschiff“-Operator genannt, liefert eine Ganzzahl, die kleiner, gleich oder größer als 0 ist, je nachdem, ob der linke Operand kleiner, gleich oder größer dem rechten ist. Aktuelle PHP Versionen liefern die Werte -1, 0 und 1, Sie sollten sich auf die Werte -1 und 1 aber nicht verlassen. Der „Raumschiff“-Operator ist bei Sortieroperationen nützlich, weil die PHP Sortierfunktionen, die Vergleichs-Callbacks akzeptieren, genau diese Werte erwarten.
Beachten Sie: Es ist ein häufiger Fehler, den istgleich Operator == mit der Wertzuweisung = zu verwechseln. Wenn Sie if ($a = 3) {...} schreiben, gibt PHP keinen Fehler aus. Es setzt $a auf den Wert 3, stellt fest, dass das Ergebnis ungleich null ist, was true entspricht, und führt die Befehle zum if immer aus. Viele Programmierer haben sich angewöhnt, if (3 == $a) { ... } zu schreiben. Wenn man dann versehentlich = statt == schreibt, gibt PHP einen Fehler aus.
für Vergleiche
<?php
 $sinnDesLebens = 42; 
 $alter = 8;

 if ($sinnDesLebens == 42) {
   echo "Richtig.";
 }
 if ($sinnDesLebens != 42) {
   echo "Falsch.";
 }
 if ($alter > 17) {
   echo "volljährig.";
 } else {
   echo "minderjährig";
 }
?>

Im Beispiel werden die Inhalte der Variablen $sinnDesLebens und $alter mit fixen numerischen Werten (42 etc.) verglichen.

Die Vergleichsoperatoren haben eine geringere Priorität als die arithmetischen Operatoren. Innerhalb der Vergleichsoperatoren haben < <= > >= eine höhrere Priorität als == === != !== <=> . Die Assoziativität für Vergleichsoperatoren ist nicht festgelegt. PHP weist einen Ausdruck wie 3 < $a < 10 als Syntaxfehler ab.

Boolesche Operatoren

Mit booleschen Operatoren werden Wahrheitswerte verarbeitet. Man nutzt sie zumeist, um das Ergebnis mehrerer Vergleichsoperatoren zusammenzufassen.

Operator Bedeutung Erklärung
&& logisches UND alle Bedingungen müssen erfüllt sein, damit die gesamte Bedingung erfüllt ist.
|| Logisches ODER es genügt, wenn eine der Bedingungen erfüllt ist, damit die gesamte Bedingung erfüllt ist.
Ausdruck liefert nur false, wenn beide Operanden false sind
 ! Nicht (engl. not) kehrt den Wahrheitswert des Operanden um (false wird true und true wird false).
and logisches UND tiefpriorisierte Variante von &&
or logisches ODER tiefpriorisierte Variante von ||
xor Entweder-Oder tiefpriorisiert, liefert true wenn genau einer der beiden Operanden true ist.

Eine wichtige Eigenschaft der booleschen Operatoren &&, ||, and und or ist die sogenannte Kurzschluss-Auswertung. Das bedeutet, dass diese Operatoren den rechten Operanden nicht ermitteln, wenn auf Grund des linken Operanden das Ergebnis bereits feststeht. false && $x ist immer false, ganz gleich, welchen Wert $x hat. Und true || $x ist immer true. Der Kurzschluss ist nicht von Bedeutung, wenn auf der rechten Seite nur Variablenwerte abgerufen werden. Man kann in einem Ausdruck aber auch Funktionsaufrufe verwenden. Diese können zeitaufwändig sein oder sogar Nebenwirkungen haben (Ausgaben, andere Werte verändern). Man spart durch den Kurzschluss also Verarbeitungszeit oder vermeidet eventuell unerwünschte Nebenwirkungen. Ein Beispiel dafür folgt weiter unten im Zusammenhang mit OR.

&& und || haben eine Priorität , die zwischen den Vergleichsoperatoren und der Zuweisung liegt, und sie sind links-assoziativ. ! hat eine hohe Priorität, zwischen * / % und **.

Der Unterschied zwischen && || einerseits und and, or und xor andererseits ist ihre Priorität. Man muss dazu wissen, dass die Wertzuweisung ebenfalls ein Operator ist und demnach eine (niedrige) Priorität hat. Die meisten anderen Operatoren sind höher priorisiert als die Zuweisung, mit der Ausnahme von and, or und xor. Im folgenden Ausdruck:

$a = $x - 3 OR print "x enthielt 3!";

wird zuerst $x - 3 berechnet, dann das Ergebnis an $a zugewiesen. Das Ergebnis eines Zuweisungsoperators ist der zugewiesene Wert, wenn also $x den Wert 3 enthielt, wird 0 zugewiesen und das Ergebnis von $a = $x - 3 ist 0. Der Wert 0 wird von PHP wie false behandelt, d. h. der linke Operand des or Operators ist false. Wegen der Kurzschluss-Auswertung der booleschen Operatoren wird jetzt die rechte Seite des or ausgewertet und der Hinweis "x enthielt 3!" ausgegeben.

Würde man statt or den || Operator verwenden, würde das Ergebnis von $x - 3 mit dem Rückgabewert der Print-Funktion ODER-verknüpft, was true ergeben – und das Ergebnis verfälschen – würde.

Es gibt keine hochpriorisierte Form des xor Operators. Sie können statt dessen den != Operator verwenden, müssen dann aber beachten, dass dieser deutlich höher priorisiert ist als && und || .

Mit den tiefpriorisierten booleschen Operatoren ist eine Form von "natürlichsprachiger" Programmierung möglich.

Anwendung von OR
<?php
$db = $db->query("SELECT id,name FROM Person") OR abortWithError("Prepare failed");
?>
In diesem Beispiel wird versucht, einen Datenbankabfrage auszuführen. Die query-Methode von PDO liefert das Ergebnis, oder FALSE. Ein Ergebnis ist ein anderes Objekt, das wie true behandelt wird, im Erfolgsfall wird also der rechte Teil des OR nicht ausgeführt. Bei einem Fehler führt OR auch den rechten Teil durch und ruft eine Funktion zur Fehlerbehandlung auf (die dann auch das Script abbrechen könnte). Wenn Sie diese Schreibweise für schwer lesbar halten, können Sie auch so formulieren:
<?php
$db = $db->query("SELECT id,name FROM Person");
if ($db === FALSE) {
   abortWithError("Prepare failed");
}
?>

Boolesche Operatoren und das NOT

Eine häufiges Problem beim Einsatz boolescher Operatoren ist der richtige Gebrauch von AND und OR, wenn negierte Bedingungen vorliegen.

Eine Abfrage mit einem unwichtigen Then-Zweig
<?php
if ($datum == "" || $datum == "00.00.0000") {
   echo "Das Datum ist leer";
}
else
{
   echo "Zeige Werte ab $datum";
}
?>

Dieses simple Beispiel soll einen Fall verdeutlichen, wo ein String aus einer Datumseingabe leer oder 00.00.0000 sein kann. In diesem Fall soll keine Verarbeitung erfolgen. Nun ist der echo im Then-Zweig des if nicht wirklich wichtig, und wenn man es entfernt, möchte man keinen leeren Then-Zweig behalten. Die Lösung ist, die Bedingung umzukehren (zu negieren) und den Code in Then- und else-Zweig zu vertauschen:

Negierte Abfrage - Then und Else tauschen die Rollen
<?php
if ( !($datum == "" || $datum == "00.00.0000") ) {
   echo "Zeige Werte ab $datum";
}
else
{
   echo "Das Datum ist leer";
}
?>

Weil der else-Zweig eines if optional ist, kann man ihn problemlos weglassen.

Das Problem, das bleibt, ist die Formulierung der Bedingung im if. Ein !(...) liest sich nicht gut, und es gibt ja auch != statt ==. Warum also nicht die Klammer auflösen?

Negierte Abfrage - falsche Klammernauflösung
<?php
if ( $datum != "" || $datum != "00.00.0000" ) {
   echo "Zeige Werte ab $datum";
}
?>

Die Wirkung dieses Programms ist, dass das Programm immer Werte anzeigt, auch wenn $datum einen Leerstring oder "00.00.0000" enthält. Warum? Wir müssen 3 Fälle unterscheiden:

  1. $datum enthält den Leerstring. Dann ist die Bedingung rechts vom || wahr, und damit auch das Ergebnis des ||.
  2. $datum enthält "00.00.0000". Dann ist die Bedingung links vom || wahr, und damit auch wieder das Ergebnis des ||.
  3. $datum enthält irgendwas anderes. Dann sind beide Bedingungen wahr, und das Ergebnis des || ebenso.

Wir sind in die Falle der De Morganschen Gesetze getappt. Sie besagen, dass in einem Fall wie diesem AND und OR die Rollen tauschen müssen. Denn ein Satz wie „Bohnen ODER Spinat esse ich nicht“ meint ja: „Ich esse keine Bohnen UND ich esse keinen Spinat“. Ein „NICHT (bohnen ODER spinat)“ meint „WEDER bohnen NOCH spinat“, und dahinter steckt ein UND, kein ODER.

Negierte Abfrage - korrekte Klammernauflösung
So ist's richtig
<?php
if ( $datum != "" && $datum != "00.00.0000" ) {
   echo "Zeige Werte ab $datum";
}
?>