1. Sinn von Schleifen
Schleifen dienen dazu einen Programmteil öfters hintereinander
auszuführen ohne ihn mehrfach im Code zu schreiben. Der Schleifenrumpf
wird dann jeweils mit leicht unterschiedlichen Variableninhalten durchlaufen.
Des Weiteren wird die Anzahl der Schleifendurchläufe durch eine
Bedingung kontrolliert. Wenn die Bedingung nach einem Durchlauf den Wert
false
ergibt so wird die Schleife beendet und der PHP-Code wird
danach normal weitergearbeitet. So werden z.B. Newsbeiträge aus einer
Datenbank ausgelesen. Solch eine Schleife sorgt dann dafür dass ein
einzelner Newsbeitrag auf der Homepage ausgegeben wird. Wenn keine
weiteren Newsbeiträge in der Datenbank vorhanden sind so ist die
Schleife beendet und weiter PHP-Code kann folgen.
Es gibt 4 Arten von Schleifen in PHP, wobei hier erstmal nur 3 dargestellt werden. Der 4. Schleifentyp wird im Kapitel Arrays durchgenommen, da er ein Schleifenkonstrukt speziell für Arrays ist. Die anderen 3 Schleifentypen sind while, do-while und for.
2. While-Schleifen
Eine while-Schleife ist der einfachste Schleifentyp. Er
besitzt einen Schleifenkopf in dem nur ein Ausdruck steht. Dieser
Ausdruck wird vor jedem Schleifendurchlauf ausgewertet und auf Boolean
geprüft. Wenn der Ausdruck true
ergibt so wird der
Schleifenrumpf ausgeführt. Danach beginnt die nächste Überprüfung des
Schleifenkopfs. Wenn der Ausdruck false
ergibt so wird
die Schleife beendet bzw. übersprungen und der weitere PHP-Code wird
ausgeführt. Da der Ausdruck ständig für einen neuen Schleifendurchlauf überprüft
wird muss der Ausdruck irgendwann den Wert false
liefern, damit
die Schleife abgebrochen wird. Wenn dies nicht der Fall ist/wird so hat
man eine Endlosschleife, das Skript terminiert nicht sauber und der
Webserver bricht das Skript von sich aus mit einer entsprechenden Fehlermeldung
(meist nach 30 Sekunden) ab.
Eine While-Schleife wird in PHP mit dem Schlüsselwort while
eingeleitet.
Danach folgt in runden Klammern (()
) der zu prüfende Ausdruck. Dann folgt ein
einzelne Anweisung oder mehrere Anweisungen in geschweiften Klammern ({}
) die
von der Schleife gesteuert werden. Obwohl eine einzelne Anweisung keine
geschweiften Klammern benötigen, ist es wie bei einer if-Abfrage üblich trotzdem
geschweifte Klammern zu verwenden, um die Übersichtlichbarkeit zu erhöhen.
<?php
while (isAutoDreckig()) {
Reinigen();
}
?>
Der Ausdruck für die Bedingung kann beliebig aufgebaut sein, jedoch muss er einen Wert zurückliefern
der dann geprüft wird. Dies heißt auch dass logische Verknüpfungen wie and
verwendet werden können.
3. Do-While-Schleife
Eine Do-While-Schleife besitzt wie die while-Schleife
ein zu prüfender Ausdruck. Dieser steht jedoch am Ende der Schleife und wird auch
erst an dieser Stelle überprüft. Da der Schleifenrumpf vor dem Schleifenkopf steht kann
der Schleifenkopf erst nach einem Durchlauf überprüft werden. Dies bedeutet
auch das eine Do-While-Schleife mindestens einmal durchlaufen wird, selbst wenn
die Schleifenbedingung false
ergibt. Dies ist auch der Unterschied zu
einer While-Schleife. Wenn man möchte dass die Schleife mindestens 1 mal durchlaufen wird
verwendet man eine Do-While-Schleife. Wenn die Schleife auch 0 mal durchlaufen werden
soll verwendet man eine While-Schleife.
Eine Do-While-Schleife wird mit dem Schlüsselwort do
eingeleitet.
Danach folgt der Schleifenrumpf, also die Anweisungen die in einer Schleife
ausgeführt werden sollen. Danach kommt das Schlüsselwort while
,
dann der zu prüfende Ausdruck in runden Klammern und dann (zwingend erforderlich)
ein Semikolon. Bei einer While-Schleife ist ein Semikolon nicht Bestandteil der
While-Schleife (so fehlerhaft wie bei if();
), bei einer Do-While-Schleife hingegen pflicht.
<?php
do {
Verbinden();
$daten = DatenAbfragen();
VerbindungBeenden();
} while ($daten > 40);
// was auch immer dieser Code machen wird...
?>
4. For-Schleife
Eine For-Schleife ist wie eine While-Schleife eine kopfgesteuerter Schleife (Do-While ist fussgesteuert). Der Schleifenkopf ist somit vor dem Schleifenrumpf. Auch er enthält eine zu prüfender Ausdruck. Zusätzlich zu einer While-Schleife enthält er noch 2 weitere Felder. Das eine Feld wird einmal zum Start ausgeführt, das andere Feld wird nach jedem Schleifendurchlauf ausgeführt.
Eine For-Schleife wird mit dem Schlüsselwort for
eingeleitet.
Danach folgen in runden Klammern die 3 Felder von der for-Schleife,
getrennt mit ;
. Nach dem Schleifenkopf folgt wie üblich
der Schleifenrumpf mit den Anweisungen.
<?php
for (startanweisung; bedingung; durchlaufanweisung) {
// anweisungen...
}
?>
Am Anfang wird der Teil startanweisung
ausgeführt (einmal). Dann wird
wie bei While die Bedingung bedingung
geprüft und demnach entschieden
ob der Schleifenrumpf ausgeführt werden soll oder nicht. Am Ende des Schleifendurchlaufs,
aber vor der nächsten Überprüfung, wird der Teil durchlaufanweisung
ausgeführt.
<?php
// gib die Zahlen von 0 bis 9 aus (bei 10 ist die Bedingung false)
for ($i=0; $i<10; $i++) {
echo $i."\n";
}
?>
5. Wann While- und wann For-Schleifen?
Da man nun Ähnlichkeiten zwischen While- und For-Schleifen feststellt stellt sich nun die Frage in welcher Situation eine While-Schleife und wann eine For-Schleife verwendet wird. Unabhängig von dieser Antwort ist es erstmal möglich jede While-Schleife in eine For-Schleife umzuwandeln, indem man die Anweisungen aus dem For-Teil in den While-Rumpf packt und umgekehrt.
<?php
while (bedingung) {
anweisungen;
}
// umformen zu for:
for (;bedingung;) {
anweisungen;
}
?>
<?php
for (start; bedingung; durchlauf) {
anweisungen;
}
// umformen zu while:
start;
while (bedingung) {
anweisungen;
durchlauf;
}
?>
Die Anzahl der Anweisungen kann also kein Grund sein wann ein While- und wann eine For-Schleife verwendet wird. Eine For-Schleife benutzt man gegenüber einer While-Schleife wenn man schon zu Entwicklungszeit die Anzahl der Schleifendurchläufe kennt. Die Startanweisung und die Durchlaufanweisung realisieren daher eine Zählstruktur.
<?php
for ($i=0; $i<10; $i++) {
// mach was mit $i, wobei $i von 0 bis 9 läuft
}
?>
Eine While-Schleife verwendet man üblicherweise wenn man nicht die Anzahl der Schleifendurchläufe kennt (selbst wenn man sie im PHP-Skript berechnen könnte). Ein Beispiel wäre das Auslesen von Datensätzen aus einer Datenbank.
<?php
while (DatensaetzeVorhanden()) {
GibNaechstenDatensatzAus();
}
?>
Auch das Auslesen aus einer Datei folgt nach dem selben Prinzip obwohl man mit filesize die Dateigröße bestimmen könnte.
<?php
while (!Dateiende()) {
LeseEinZeichen();
}
?>
6. Continue und Break
Der Verlauf einer Schleife kann neben der Schleifenbedingung noch anders
gesteuert werden. Eine Möglichkeit besteht ein return zu verwenden. Dies
hat aber nichts speziell mit Schleifen zu tun, da man return
(fast) überall
verwenden kann. Für Schleifen gibt es jedoch noch die speziellen Ausdrücke
continue und break.
-
break - beendet an der aktuellen Stelle die Schleife und führt dann den folgenden PHP-Code aus, so als würde die Schleifenbedingung
false
ergeben (selbst wenn dies nicht der Fall wäre).<?php
while (...) {
break; // --->
// |
// V
} // <---
?> -
continue - überspringt den aktuellen Schleifendurchlauf und beginnt mit dem nächste. Er springt dabei zum Ende des Schleifenrumpfs. Für For-Schleifen bedeutet dies auch dass die Durchlaufanweisung ausgeführt wird (für den nächsten Durchlauf), für Do-While-Schleifen bedeutet dies dass die Schleifenbedingung geprüft wird (und auch für While-Schleifen, aber da erst im Beginn des darauf folgenden Schleifendurchlaufs).
<?php
// keine Endlosschleife wie vielleicht vermutet
do { // < - - -
// | Nicht wie erwartet
// |
continue; // ---> - -
// |
// V Dies ist der Weg von continue
// <---
} while(false);
?>
Eine if-Abfrage kann auf diese Weise nicht verlassen (oder sogar neu durchlaufen werden)
da eine if-Abfrage kein Schleifenkonstrukt ist. Sowas wie if (...) { .... break; ...}
wird nur klappen wenn das ganze in einer Schleife steht und somit das break
auf
die Schleife angewendet werden kann.
Beide Konstrukte können optional eine Zahl angegeben werden die angibt die wievielte Schleife
angesprechend werden soll. Die aktuelle/innerste Schleife ist dabei Nummer 1 und wird dann
entsprechend der Verschachtelungen hochgezählt. Der Ausdruck break 1
ist
äquivalent zu break
.
<?php
$found = false;
for ($x=0; $x<100; $x++) {
for ($y=0; $y<100; $y++) {
for ($z=0; $z<100; $z++) {
if (PixelFarbe($x, $y, $z) == 0xFFCCFF) {
$found = true;
break 3;
}
}
}
}
?>
Diese verschachtelten Schleifen würden insgesammt 100*100*100 also 1.000.000 mal durchlaufen. Würde
der Funktionsaufruf von PixelFarbe(int, int, int)
nur 10µs dauern würde dieser
Code 10 Sekunden laufen. Mit dem break 3
verlassen wir jedoch die 3 Schleifen,
nachdem wir unseren Pixel gefunden haben und können so Zeit einsparen. Es ist klar wenn
wir die Farbe nicht finden müssen wir trotzdem alle Pixel durchlaufen.