Im Laufe der PHP-Tutorial Reihe haben wir uns im zuletzt erschienen Artikel mit Konstanten und globalen Variablen beschäftigt. Auch Arrays in PHP waren bereits Thema.
Auf dieser Seite lernst Du nun etwas über Schleifen. Welche es gibt und wie Du diese einsetzen kannst, werde ich Dir in diesem Artikel zeigen und erklären.
Schleifen allgemein
Zunächst einmal sollten wir klären, wofür Schleifen überhaupt da sind. Dafür lassen wir die switch-Schleife, die ja auch in der Überschrift steht, erst einmal aus.
Eine Schleife ist dazu da, einen Prozess, also beliebigen PHP-Code, mehrmals auszuführen. Und zwar solange eine Bedingung zutrifft.
Mit einer Zählschleife (for) beispielsweise können wir PHP von … bis mit beliebigen Schritten zählen lassen. Innerhalb des ausgeführten Codes haben wir Zugriff auf den Zähler und können extra Aktionen ausführen lassen, wenn der Zähler den Wert x hat.
Eine while-Schleife („solange“-Schleife) wird erst dann beendet, wenn die übergebene Bedingung nicht mehr zutrifft.
Bei foreach handelt es sich um eine besondere Schleife in PHP. Damit können wir Arrays auslesen. Das geht zwar auch mit einer for-Schleife, ist damit aber noch deutlich bequemer, weil PHP uns die ganze Arbeit abnimmt.
Die while-Schleife
Beginnen wir nun aber mit der while-Schleife. Eine while-Schleife benötigt eine Bedingung (es können nicht mehrere angegeben werden, wie bei einer if-Abfrage) und einen Schleifenblock, der ausgeführt werden soll.
<?php $a = true; $i = 0; while ($a == true) { // Zähler ausgeben und für den nächsten Durchlauf um 1 erhöhen // echo $i++; if (mt_rand(1, 10) == 1) { // Wenn Zufallszahl = 1 (10% Wahrscheinlichkeit), dann Schleife beenden $a = false; } } ?>
Dieser PHP-Code zeigt eine Schleife, in der Variable $i die Durchläufe zählt und mit jedem Durchlauf diesen Wert ausgibt. Solange $a true ist, wird die Schleife ausgeführt.
Dieser Code beendet die Schleife einfach zufällig (siehe: mt_rand()). Mal wird sie 100-Mal durchgeführt, mal 5-Mal und zum Teil nur 1-Mal. Du kannst es natürlich selbst ausprobieren.
Gleichzeitig kannst Du bereits eine Besonderheit erkennen. Vor jedem Durchlauf, auch vor dem ersten, wird die Bedingung geprüft. Ist sie zutreffend, wird der Code ausgeführt, sonst nicht.
In der Regel kannst Du deinen Code immer so einrichten, dass er so funktioniert. Wenn Du dies nicht möchtest, kannst Du dir die do-while-Schleife angucken. Ich halte wenig davon, deswegen nur so viel: Mit einer do-while-Schleife wird erst der Code ausgeführt und anschließend geprüft, ob die Bedingung (für den nächsten Durchlauf) zutrifft. Wenn eine Bedingung also von vornherein unwahr (false) ist, wird eine do-while-Schleife dennoch einmal ausgeführt.
Stellt sich nun noch die Frage, wann eine while-Schleife sinnvoll ist. Häufig ist das bei Eigenlösungen der Fall. Wenn Du also kein Array auslesen möchtest, und nicht so wie oben zählen möchtest, ist die while-Schleife richtig. Warte nur ab, Du wirst im Laufe deiner Coding-Zeit bestimmt noch einige Male auf solche Beispiele treffen. Etwa wenn Du einen Ordner auslesen möchtest.
Die Zählschleife (for) in PHP
Immer dann, wenn es um das Zählen geht, ist die for-Schleife richtig. Dabei gibt es keine einzelne Bedingung, sondern in den Klammern wird eine Zählvariable übergeben, die Bedingung, die gelten muss (z.B. Zählvariable < 100), und der Schritt (z.B. +1).
<?php for ($zaehler = 1; $zaehler <= 100; $zaehler++) { echo $zaehler; } // Beginnt mit 50 // $zaehler = 50; for ($zaehler; $zaehler <= 100; $zaehler++) { echo $zaehler; } ?>
So, wie Du siehst, werden die einzelnen Teile durch ein Semikolon getrennt. Außerdem kannst Du der Zählvariable (in diesem Fall $zaehler) zu Beginn einen Wert zuteilen oder eine Variable übergeben, die bereits eine Zahl enthält.
Dann prüft PHP mit jedem Durchlauf, ob die Bedingung zutrifft. Außerdem wird der Zählschritt durchgeführt. Mit einem ++ hinter der Variablen (z.B. $zaehler++), wird der aktuelle Wert der Variablen zurückgegeben und die Variable wird anschließend um eins erhöht.
Mit einem ++ (— ist auch möglich) vor der Variablen (z.B. ++$zaehler) wird der Wert erst um eins erhöht und dann zurückgegeben. Noch nicht ganz klar? Dann probiere es am besten einfach selbst aus.
Du kannst als dritten Teil übrigens auch so etwas:
$zaehler += 8
oder so etwas:
$zaehler *= 2
übergeben. Dabei sind alle Rechenzeichen (-, +, *, /) möglich, die den jeweiligen Effekt erzielen. Im zweiten Fall wird der Inhalt von $zaehler also mit 2 multipliziert, im ersten mit 8 addiert.
Die Funktion count() gibt die Anzahl von Elementen zurück, die einem Array zugeordnet sind. So ist also ganz einfach möglich, mit einer for-Schleife auch ein Array mit durchnummerierten, also kein assoziatives, Indizes auszulesen:
<?php $a = array('Affe', 'Elefant', 'Zebra'); // Array $a mit Zählschleife auslesen // for ($i = 0; $i < count($a); $i++) { echo $a[$i]; } ?>
Bei komplexeren Arrays ist die foreach-Schleife hilfreich, die ich Dir weiter unten vorstelle.
Vorsicht: Endlosschleife
Sowohl bei der for- als auch bei der while-Schleife kannst du mit etwas „Glück“ eine Endlosschleife erstellen. Der Name verrät bereits, was das Problem ist. Die Schleife wird endlos ausgeführt.
Wenn Dein Server eine maximale Skript-Laufzeit von 30 Sekunden eingestellt hat und Du den Seitenaufruf (Seite lädt in diesem Fall ewig) nicht vorher beendest, wird diese Schleife 30 Sekunden lang ausgeführt. Das ist im Coding schon eine echt lange Zeit.
Doch noch schlimmer wird es mit entsprechenden Server-Einstellungen. Wenn Dein Server keine oder eine sehr hohe maximale Skript-Laufzeit toleriert und den Benutzer-Abbruch ignoriert, musst Du zusehen, dass Du dieses Skript irgendwie über deine Konsole oder einen Neustart des Servers beendet bekommst.
Hier zur Veranschaulichung noch ein einfaches Beispiel:
<?php // Endlosschleife (while) // while (true) { echo "endlos..."; } // Endlosschleife (for) // for ($i = 0; $i < ($i + 1); $i++) { echo "endlos2..."; } ?>
Merke: Prüfe immer, ob Deine Schleife dafür sorgt, dass die Bedingung irgendwann unwahr, also false ist oder benutze gezielt break-Statements (siehe unten).
foreach-Schleife für Arrays in PHP
Für den Fall, dass Du ein assoziatives Array verwendest, also eigene Indizes für die Werte festlegst, kommst Du mit einer einfachen for-Schleife nicht weit.
Die foreach-Schleife ist prädestiniert dafür, Arrays auszulesen, dabei gibt es zwei Formen, die Schleife auszuführen:
<?php $a = array(array(), array('Apfel', 'Birne', 'Orange')); // Nur den Wert ($v) abfragen // foreach ($a[1] AS $v) { echo $v; } // Wert ($v) und Index ($i) abfragen // foreach ($a[1] AS $i => $v) { echo $i." = ".$v; } ?>
In diesem Fall handelt es sich bei der Variable $a um ein verschachteltes Array, daher das $a[1]. Du kannst natürlich aber auch anders angeordnete Arrays auslesen.
Je nach Form, die Du wählst, kannst Du dir auch den Indexwert übergeben lassen. Dieser ist dann wichtig, wenn Du zum Beispiel Inhalte des Arrays über $array[$index] verändern und nicht nur auslesen willst.
switch-Schleife
Du prüfst eine Variable auf einen Wert und das mehrmals? Mit if-Abfragen sieht das nicht nur unschön aus, sondern ist auch nicht sehr effizient. Besser eine switch-Schleife verwenden.
Dieser wird eine Variable übergeben. Anschließend können mit sogenannten case-Statements Aktionen ausgeführt werden. Das case handelt dabei ähnlich wie das === in if-Abfragen. Der Wert der Variable muss also identisch (Groß- und Kleinschreibung, false nicht gleich 0) mit dem gewünschten Wert sein. Jeder case-Block sollte mit einem break; beendet werden, sonst werden die nachfolgenden Blöcke eventuell ebenfalls ausgeführt.
<?php $var = 'Test'; switch ($var) { case 1: // Hier kann, wie bei den anderen case-Blöcken auch, beliebig viel PHP- Code eingefügt werden // echo 'ist 1'; break; case 'Hallo': echo 'Begrüßung'; break; default: // Benötigt kein break am Ende, wird ausgeführt, wenn kein Statement zutrifft // echo 'anderer Wert!'; } ?>
Das default benötigt, wie bereits im Kommentar beschrieben, kein break, sollte am Ende stehen und wird dann ausgeführt, wenn kein case-Statement zutrifft.
Eine Schleife? Eventuell wirst Du dich nun fragen, was an switch nun einer Schleife ähneln sollen. Zwar handelt es sich dabei um keine klassische Schleife, doch auch hier können entsprechende Befehle wie etwa break angewendet werden.
break- und continue in PHP
break kann nämlich auch bei allen for-, while– und foreach-Schleifen verwendet werden. Mit einem einfachen break; innerhalb der Schleife wird die Schleife komplett abgebrochen und der Code hinter der Schleife wird ausgeführt.
Ein korrekt eingesetztes break-Statement kann also auch eine Endlosschleife verhindern.
Möchtest Du hingegen sofort zum nächsten Schritt springen, also eventuell nachfolgenden Code innerhalb der Schleife ignorieren, kannst Du continue einsetzen, etwa so:
<?php // Das kann ähnlich mit anderen Schleifen-Typen (z.B. while) verwirklicht werden // for ($i = 0; $i < 10; $i++) { // HINWEIS: Zahl % Zahl = Rest beim Teilen // if ($i % 2 == 0) { continue; } echo $i; } ?>
Da wir mit dem % Zeichen in der Form: Zahl % Zahl den Rest beim Teilen ermitteln können, kann in diesem Fall mit $i % 2 == 0 überprüft werden, ob es sich um eine gerade Zahl handelt.
In diesem Fall springt die Schleife direkt zum nächsten Schritt und ignoriert somit auch das nachfolgende echo-Statement. Bei der Ausführung dieses PHP-Codes werden folglich nur die ungeraden Zahlen ausgegeben.
Fazit & Ausblick
Das ist mal wieder ein langer Artikel geworden. Aber dafür hast Du nun auch ein sehr wichtiges Konstrukt in PHP kennengelernt: die Schleife. Gezielt eingesetzt, kann diese Dir bei zahlreichen Anwendungsprozessen helfen.
Für den nachfolgenden Artikel habe ich mir schon ein interessantes Thema ausgeguckt. Wir beschäftigen uns mit der Verarbeitung von Dateien in PHP.
Danke für den Artikel – 5 Sterne !
Macht es Sinn, eine Schleife dazu zu nutzen um zu prüfen ob if(file_exists(file.php)) mit dem Code fortzuführen, Stichwort Endlos und wie viele Loops, oder gibt es eine bessere/elegantere Lösung dazu ?
Hallo Coli,
Leider wird aus deinem Kommentar nicht ganz ersichtlich, was du vor hast. Sofern du zwingend das Vorhandensein mehrerer Dateien prüfen musst, bietet sich dafür eine Schleife (etwa foreach aus einem Array mit Dateinamen) an.