PHP lernen

http://php.lernenhoch2.de/lernen/

1. PHP Einleitung

1.1. Motivation

1.2. Wie funktioniert PHP

1.3. Dein eigener Server

1.4. PHP Editoren

2. PHP Anfänger

2.1. Das erste PHP Skript – Ausgaben mit dem „echo“ Befehl

2.1.1. echo mit Anführungszeichen “ und Hochkomma ‚

2.2. Variablen

2.2.1. weitere Variablen Beispiele

2.2.2. Beispiele für gültige und ungültige Variablen Namen

2.2.3. Variablen Typen

2.3. PHP Kommentare

2.4. Bedingungen

2.4.1. Bedingung mit Alternative – If, else

2.4.2. Noch mehr Möglichkeiten – If, else if, else

2.4.3. Vergleichsoperatoren

2.4.4. Wahrheitswerte kombinieren

2.4.5. Ternärer Operator – Kurzform für If then else

2.4.6. Endif – Alternative Syntax zur geschweiften Klammer

2.5. Switch

2.6. Arrays

2.6.1. Assoziative Arrays

2.6.2. Mehrdimensionales Array

2.6.3. Array Werte sortieren

2.6.4. Mehrdimensionales Array sortieren

2.7. Schleifen

2.7.1. For-Schleife

2.7.2. While-Schleife

2.7.3. Do-While-Schleife

2.7.4. Foreach-Schleifen

2.7.5. Schleifen Fazit

2.8. Konstanten

2.9. Include

2.10. Formulare erstellen und auswerten

2.10.1. Unterschied zwischen GET und POST

2.11. Fehler finden und beheben für Anfänger

3. PHP Fortgeschritten

3.1. PHP Version herausfinden

3.2. Funktionen

3.2.1. Referenz Parameter

3.2.2. PHP Funktionen und Dokumentation

3.3. Klassen und Objekte (Einführung)

3.3.1. OOP/Klassen Begriffe

3.3.2. Klasse erstellen in PHP

3.3.2.1. Klassenname – was gibt es zu beachten

3.3.3. Eigenschaften – Variablen einer Klasse

3.3.4. Objekt erzeugen / Klasse instanziieren

3.3.5. Klasse: Raumschiff_fabrik

3.3.6. Methoden – Funktionen einer Klasse

3.3.6.1. Lazy Space Wars I

3.3.7. Constructor – Objekt erzeugen und Variablen initialisieren

3.3.7.1. Magische Methoden in PHP
3.3.7.2. Magische Konstanten in PHP
3.3.7.3. Destructor – Objekt zerstören und Ressourcen freigeben

3.3.8. Vererbung

3.3.8.1. Sichtbarkeit – Public, Private & Protected

3.3.9. Vererben und erweitern – Klasse: Raumschiff_fabrik

3.3.9.1. Klasse: Scout
3.3.9.2. Klasse: Transporter + Schlüsselwort: „self“
3.3.9.3. Klasse: Zerstoerer

3.3.10. Static

3.3.11. Abstract

3.3.12. Interfaces

3.3.13. Überladen

3.3.14. Final

3.4. Fehler finden und beheben für Fortgeschrittene

1. PHP Einleitung


1.1. Motivation

Für eine dynamische Webseite ist HTML nicht ausreichend, da muss eine knackige Skriptsprache wie PHP her. Die Grundzüge von PHP sind schnell erlernt und dennoch bietet diese Skriptsprache genügend Potential, mit allen Alternativen (z.b. ASP, Java, Ruby, etc.) mitzuhalten.

PHP ist kostenlos, Server die PHP unterstützen findet man wie Sand am Meer und eine riesige Community unterstützt die Weiterentwicklung. Zudem hat die Beliebtheit für PHP etliche Frameworks und andere Systeme hervorgebracht, die ebenfalls kostenlos sind. So basiert z.b. das beliebteste Blog-System WordPress auf PHP.

PHP nur für kleine Webseiten?

Ob klein oder groß, PHP wird durchweg genutzt:

As of April 2007, over 20 million Internet domains had web services hosted on servers with PHP installed and mod_php was recorded as the most popular Apache HTTP Server module.[34] Significant websites are written in PHP including the user-facing portion of Facebook,[35] Wikipedia (MediaWiki),[36] Yahoo!,[37] MyYearbook,[38] Digg, Joomla, WordPress, YouTube in its early stages, Drupal, Tagged[39] and Moodle [40].

Quelle

Also Facebook, Digg, Youtube und andere große Seiten sind sich nicht zu Schade, PHP einzusetzen, warum sollte es deinen Ansprüchen nicht genügen? ;)

Ich wünsche dir nun viel Spass beim lernen von PHP


1.2. Wie funktioniert PHP


Quelle

Die Funktionsweise von PHP ist garnicht so schwer: Ein Besucher ruft über seinen Browser ein PHP-Skript auf deinem Server auf, z.b.: http://domain.de/mein-skript.php. Über das Internet wird diese Anfrage an deinen Server gestellt, auf dem das Skript liegt (wenn es dort kein Skript gibt, bekommt der Besucher eine Fehlermeldung).

Der Webserver sucht nun auf der Festplatte nach der PHP-Datei, wenn er sie gefunden hat, wird sie an den PHP Interpreter übergeben. Der PHP Interpreter verarbeitet dein PHP-Skript und übergibt das Ergebnis an den Besucher. Das Ergebnis ist in der Regel HTML, kann aber auch CSS, Javascript und sogar Bilder sein
(ja, PHP kann auch Bilder erzeugen :) ).

Wann setze ich PHP ein?

PHP kann sehr viele Formate erstellen (CSS, Javascript, Bilder), doch meist wird es für die Ausgabe von HTML genutzt. Nun kommt die Frage auf „Warum soll ich PHP überhaupt verwenden, wenn ich meine HTML-Datei direkt erzeugen kann?“. Das ist leicht beantwortet, eine HTML-Datei ist statisch, dass heißt, wenn du eine Tabelle mit 10 Einträgen in HTML schreibst, können nur diese 10 angezeigt werden. PHP ist dynamisch und kann dir eine Tabelle mit einer Zeile oder mit tausend Zeilen erzeugen, je nach Bedarf.

Alles was irgendwie dynamisch sein soll auf deiner Seite, muss mit PHP gemacht werden, denn HTML ist nur statisch:

  • Ein Besuchercounter (bei jedem Besuch +1)
  • Ein Kontaktformular (das Formular selbst wird rein in HTML erzeugt, aber die Verarbeitung der Formular-Daten erfolgt mit PHP)
  • ein Gästebuch (wir wollen ja nicht bei jedem neuen Eintrag die HTML Datei aktualisieren müssen, dass soll PHP automatisch und in Echtzeit machen)
  • Anzeige welches Datum heute ist
  • usw.

Wenn dich PHP interessiert, dann schau dir mal das PHP Tutorial an.


1.3. Dein eigener Server

Der erste Schritt zum lernen von PHP und MySQL ist es, auf seinem Rechner einen Apache Server zu installieren. Damit kann man seine PHP-Skripte direkt testen bzw eine Datenbank anlegen und mit MySQL Befehlen rumspielen. Die einfachste Möglichkeit dafür, die ich finden konnte, ist Apache Friends – XAMPP

Wähle einfach die für dein Betriebssystem passende Version von XAMPP aus (als bsp.: XAMPP für Windows), lade die passende Datei herunter (entweder XAMPP oder XAMPP lite) und installiere XAMPP (ich empfehle die selbstentpackende .EXE, da man so nichts falsch machen kann).

Den Server starten

Nach der Installation ist der Server nun bereit, aber um ihn benutzen zu können, muss er erst noch über das „XAMPP Control Panel“ gestartet werden. Schau dir dazu auch den Bereich XAMPP Server starten, stoppen und testen an.
Bedenke das der Server bei jedem Neustart deines Rechners erst wieder gestartet werden muss. Wenn du also über localhost (http://localhost/) eine PHP-Datei aufrufst, dir aber nichts ausgegeben wird (bzw. ein Fehler), dann prüfe erstmal ob der Server auch läuft.

Bei Fragen und Problemen mit dem XAMPP Server ist die XAMPP Friends Website dein Freund. Dort gibt es viele Anleitungen und Tipps die dich schnell zur Lösung führen werden.


1.4. PHP Editoren

Ein wirklich guter Editor, für Webprogrammierung allgemein, ist Aptana. Der Aptana Editor basiert auf Eclipse, ist kostenlos, unterstützt alle nötigen Web-Sprachen (CSS, HTML, XML, PHP, etc.) und beinhaltet viele weitere Features. Ich nutze Aptana schon seit über einem Jahr und er ist meiner Meinung nach, einer der besten Editoren für PHP.

Für PHP Anfänger ist die Funktionsvielfalt in der Regel erdrückend, zumal man gerade anfangs auch problemlos mit einem simplen Texteditor seine Skripte schreiben kann. Doch wer das Anfänger Tutorial erstmal durchgearbeitet hat, der ist mit Aptana auf der sicheren Seite.

Hier noch eine Liste mit anderen PHP Editoren: PHP-Editor, PHP-Tools und andere PHP-Software


2. PHP Anfänger

Wenn du deinen eigenen Server schon gestartet hast und bereit bist, deine ersten Zeilen in PHP zu schreiben, bist du hier genau richtig. Ich setze für das PHP Anfänger Tutorial keinerlei Wissen in PHP oder anderen Skriptsprachen voraus. Es wäre praktisch, wenn du Grundkenntnisse in HTML hast, aber zwingend nötig ist auch das nicht.

Du solltest die Lektionen von oben nach unten durcharbeiten, da die jeweils folgende Lektion auf dem Wissen der vorigen aufbaut. Ich wünsche dir viel Spass und Erfolg beim lernen von PHP.


2.1. Das erste PHP Skript – Ausgaben mit dem „echo“ Befehl

Überprüfe als erstes, ob dein Server läuft bzw. ob auf deinem Web-Server PHP zur Verfügung steht (wovon man heutzutage eigentlich ausgehen kann). Der Server muss laufen, damit unser PHP-Skript vom Server verarbeitet werden kann (=> sprich: Damit wir was ausgegeben bekommen).

Hallo Welt

Erstelle eine Datei mit dem Namen „index.php“. Dazu erzeuge erstmal eine .txt-Datei (im Windows-Explorer einfach einen „rechts-klick“ machen -> „Neu“ auswählen und dann auf „Textdokument“ klicken).

Nun sollte deine Datei folgenden Namen haben Neues Textdokument.txt. Ist dies nicht der Fall und stattdessen heißt die Datei lediglich „Neues Textdokument“, dann musst du vorher noch die Option „Dateierweiterungen anzeigen“ von Windows aktivieren:

Nachdem du nun die Dateierweiterung „.txt“ sehen kannst, benenne die Datei um in „index.php“ (nicht index.php.txt!!)

Die Datei kannst du trotzdem mit jedem beliebigen Texteditor öffnen (dazu einfach „rechts-klick“ -> „Öffnen mit“ -> „Editor“ oder „Standardprogramm auswählen“).
Nachdem du nun die Datei erstellt und geöffnet hast, trage folgenden Code ein:

<?php
	echo 'Hallo Welt';
?>

Wenn du die Datei nun in deinem Browser aufrufst, sollte folgender Text ausgegeben werden:

Hallo Welt

Erklärung

Jeglichen PHP-Code den du schreibst, musst du innerhalb von <?php … ?> schreiben, damit PHP erkennt, wo der Code anfängt und wo er endet. Mit dem „echo“-Befehl kannst du Text auf dem Bildschirm ausgeben. Diesen Befehl wirst du sehr häufig benutzen, unter anderem auch um HTML-Text auszugeben:

<?php
	echo '<h2>Dies ist HTML-Text</h2>';
?>

2.1.1. echo mit Anführungszeichen “ und Hochkomma ‚

Den echo-Befehl kann man mit Anführungszeichen und mit Hochkommata nutzen. Also beides ist möglich:

<?php
	echo "Hallo Welt";
	echo 'Hallo Welt';
?>

Unterschied zu Variante 1 (Anführungszeichen „) und Variante 2 (Hochkomma ‚)

Unterschied 1 – mit Backslash Zeichen entwerten

Möchtest du in Variante 1 innerhalb deiner Ausgabe ein Anführungszeichen verwenden, musst du dieses extra „escapen“ mit dem Backslash-Zeichen:

<?php
	echo "...und er sagte es wäre \"wenig\" Arbeit";
?>

Da PHP in dieser Variante die „-Zeichen dazu benutzt, den String einzugrenzen, müssen wir die Zeichen innerhalb des Strings mit einem Backslash „entwerten“, ansonsten würden wir einen Fehler erhalten. In Variante 2 ist das nicht nötig, da zum eingrenzen das Hochkomma genutzt wird. Möchten wir aber innerhalb des Strings Hochkomma ausgeben, müssen wir die wiederum entwerten. Nach meiner Erfahrung braucht man aber häufiger das Anführungszeichen als das Hochkomma, deshalb nutze ich Variante 2.

Unterschied 2 – Variablen im String

Du kannst Variablen innerhalb des Strings in Variante 1 packen und PHP wird automatisch den Wert einfügen:

<?php
	$name = "Marie";
	
	echo "Ich heiße $name";
?>

In Variante 2 würdest du mit dieser Methode folgende Ausgabe erhalten: Ich heiße $name
Ich finde es allerdings unsauber, Variablen direkt in den String zu packen. Meiner Meinung nach sollte man Variablen mit dem String konkatenieren, dass macht den Code deutlich lesbarer und verständlicher:

<?php
	$name = "Marie";
	
	echo 'Ich heiße '.$name;
?>

Fazit

Ich bevorzuge die Hochkomma-Variante, da ich sie sauberer finde, aber es ist geschmackssache. Meine gründe dafür sind:

  • Ich schreibe Variablen eh nicht direkt in den String (weil ich es für „unsauberen“ Code halte)
  • Ich muss in einem String die Anführungszeichen mit Backslash entwerten

Andererseits kommt es auch auf den Einzelfall an. Du wirst in den folgenden Kapiteln häufig sehen, dass ich anstelle von Hochkommata auf Anführungszeichen zurückgreife. Es ist halt geschmackssache ;)


2.2. Variablen

Im vorigen Teil hast du den „echo“-Befehl kennengelernt und herausgefunden, wie man Text ausgibt. Nun kommt ein weiterer, sehr wichtiger Teil von PHP und zwar die Variablen. Sollte dir etwas unklar sein, stell deine Frage einfach unten als Kommentar.

Variablen – Einführung

Erstmal ein kleines Beispiel:

<?php
	$zustand = "gut";
	echo "Mir geht es ".$zustand;
?>

Erzeuge ein neues PHP-Skript mit dem Namen „variablen1.php“, trage den Code darin ein und führe es in deinem Browser aus. Als Ergebnis sollte dir folgendes angezeigt werden:

Mir geht es gut

Zeile 1 und 4 kennst du schon aus dem vorigen Teil (das erste PHP Skript). Auch den „echo“-Befehl hast du schon gesehen und weißt, dass damit Text ausgegeben wird. Nun kommt mit Zeile 2 etwas neues hinzu und zwar eine Variable.

Was sind Variablen und wofür gibt es die in PHP?

Variablen sind Behälter, die einen Wert haben. Der Wert kann

  • eine Zahl sein, z.b. 5 oder 14 oder auch 139283454627236 (jede beliebige Zahl halt)
  • ein Text, z.b. „Wieviel Uhr ist es?“, „Wie geht es dir?“, „Mir ist langweilig“
  • ein Buchstabe, z.b. „a“, „r“, „x“

und noch vieles mehr. Doch erstmal bleiben wir bei Zahlen und Texten (bzw. Buchstaben). Ausserdem kannst du den Wert einer Variable ausgeben (z.b. mit dem „echo“-Befehl) oder verändern. Eine Variable beginnt immer mit dem Dollarzeichen, gefolgt von Buchstaben, Zahlen und Unterstrichen, die den Variablen-Namen definieren.

So, du weißt also nun grob was eine Variable ist (wenn nicht frag einfach nach). Du weißt auch, dass eine Variable einen Wert besitzt, doch wie erhält sie den Wert?

<?php
	$alter = 25;
?>

Um einer Variable einen Wert zuzuweisen, schreibst du erstmal die Variable. Dann folgt ein „=“ was soviel heißt wie „packe den Wert auf der rechten Seite vom „=“ in meine Variable auf der linken Seite“. Merke dir: Die Variable die Links vom „=“ steht, bekommt immer den Wert der rechts vom „=“ steht.

Variablen haben also einen Wert und diesen Wert können wir ausgeben:

<?php
	$zahl = 12;
	echo $zahl;
?>

Wir legen eine Variable mit der Bezeichnung „zahl“ an und weisen ihr den Wert 12 zu. Teste das Skript und du wirst sehen, dass auf dem Bildschirm „12“ ausgegeben wird. Ändere nun den Wert der Variable Zahl auf einen beliebigen anderen Wert und schau dir das Ergebnis an.

Nun schauen wir uns nochmal das Beispiel vom anfang an:

<?php
	$zustand = "gut";
	echo "Mir geht es ".$zustand;
?>

Die Variable „Zustand“ hat in diesem Fall keinen Wert vom Typ Zahl (Int für Integer), sondern einen Wert vom Typ Text (String). Lies hier nach was für Variablen Typen es in PHP gibt.

Also, $zustand hat den Wert „gut“, dass heißt, wenn wir $zustand ausgeben, wird uns „gut“ angezeigt. Und genau das wollen wir in Zeile 3 erreichen, indem wir zuerst „Mir geht es“ normal mit echo ausgeben, aber dann noch das „gut“ dranhängen. Um einen Wert „dranzuhängen“ bzw zu konkatenieren, gibt es den „.“
Schau dir die Ausgabe des Skripts an und ändere den Wert von „zustand“ um das Prinzip von Variablen und dem konkatenieren von Werten zu verstehen.

Variablen-Wert während der Laufzeit ändern

Nun wollen wir mal sehen, was passiert, wenn wir den Wert einer Variablen während der Laufzeit des Skripts ändern:

<?php
	$zahl = 1;
	echo "Mein Wert ist ".$zahl." - ";
	
	$zahl = 2;
	echo "jetzt ist er ".$zahl;
?>

Ausgabe:

Mein Wert ist 1 – jetzt ist er 2

Der Wert einer Variable ist also nicht fest, wir können ihn beliebig verändern auch während das Skript läuft.

Variablen Zusammenfassung

Hier nochmal eine kurze Zusammenfassung zu Variablen:

  • Eine Variable ist ein Behälter
  • Hat einen Wert (Zahl oder Text)
  • du kannst Variablen in deinem PHP-Skript anlegen
  • Variablen bestehen aus $ + Bezeichnung (bsp.: $a, $hallo, $uhrzeit, $aswdds)
  • Ein gültiger Variablen-Name fängt mit einem Buchstaben (a-z) oder einem Unterstrich (_) an und kann dann eine beliebige Zahl von Buchstaben, Zahlen oder Unterstrichen haben (unten findest du eine Liste mit gültigen und ungültigen Variablen-Namen)

2.2.1. weitere Variablen Beispiele

Variable einer anderen Variable zuweisen

Wenn wir einer Variable einen Wert zuweisen, muss das nicht direkt eine Zahl oder ein Text sein. Wir können einer Variable auch einfach den Wert einer anderen Variable zuweisen:

<?php
	$a = 12;
	$z = $a;
	
	echo $z;
?>

Beide Variablen, also $a und $z, haben ab Zeile 4 den Wert „12“.

Ein einfacher(?) Tausch

Nun was kniffliges: Wir haben zwei Variablen, $a und $b und die Werte werden am Ende des Skripts ausgegeben.

<?php
	$a = 100;
	$b = 200;
	
	//hier wird getauscht
	
	echo $a." - ".$b;
?>

Ausgabe:

100 – 200

Das ist soweit klar, bis auf Zeile 5. Dabei handelt es sich um einen Kommentar, die komplette Zeile wird von PHP ignoriert. Mit Kommentaren kannst du dir Notizen in deine Skripte schreiben, aber dazu später mehr.
Nun möchte ich, dass $a den Wert von $b erhält und $b den Wert von $a ohne an den Zeilen 2,3 und 7 was zu ändern. Ein direkter Tausch funktioniert nicht:

<?php
	$a = 100;
	$b = 200;
	
	//hier wird getauscht
	$a = $b;
	$b = $a;
	
	echo $a." - ".$b;
?>

Ausgabe:

200 – 200

In Zeile 6 erhält $a den Wert von $b (200) und überschreibt damit den Wert 100. Was wir brauchen ist eine dritte Variable, die temporär den Wert von $a festhält:

<?php
	$a = 100;
	$b = 200;
	
	//hier wird getauscht
	$temp = $a;
	$a 	  = $b;
	$b    = $temp;
	
	echo $a." - ".$b;
?>

Zeile 6: $temp erhält den Wert 100
Zeile 7: $a erhält den Wert 200
Zeile 8: den vorigen Wert von $a haben wir in $temp festgehalten und können ihn jetzt $b zuweisen; Der Tausch ist vollzogen.

Variablen miteinander addieren

Wir können Variablen Werte nicht nur ausgeben, sondern auch manipulieren. Dazu ein kleines Beispiel:

<?php
	$zahl1 = 12;
	$zahl2 = 8;
	$ergebnis = $zahl1 + $zahl2;
	
	echo $ergebnis;
?>

Zeile 2 und 3 sind leicht, es werden zwei Variablen angelegt und jeweils ein Wert zugewiesen, doch was passiert in Zeile 4?

  1. es wird eine Variable „ergebnis“ angelegt
  2. der Variable „ergebnis“ wird ein Wert zugewiesen (alles was auf der rechten Seite vom „=“ steht)

Doch anstelle einer Zahl oder eines Texts, stehen dort zwei Variablen und ein + Zeichen. Vielleich hast du es dir schon gedacht: Auf der rechten Seite werden die beiden Werte der Variablen zahl1 und zahl2 miteinander addiert und dieses Ergebnis wird dann der Variablen „ergebnis“ zugewiesen. Eigentlich ganz einfach, teste es mal mit anderen Zahlen und mit anderen Rechenoperationen wie subtrahieren (-), multiplizieren (*) und dividieren (/) aus.


2.2.2. Beispiele für gültige und ungültige Variablen Namen

Der Name einer Variablen unterliegt ein paar Regeln, hier findest du gültige und ungültige Kombinationen.

Beispiele für gültige Variablen Namen

Denke daran, gültige Variablen-Namen fangen mit einem Buchstaben (a-z) oder einem Unterstrich (_) an und können dann eine beliebige Zahl von Buchstaben, Zahlen oder Unterstrichen haben.

  • $a
  • $a123
  • $variable
  • $platzhalter
  • $uhrzeit
  • $alter
  • $name
  • $_hallo
  • $_123

Beispiele für ungültige Variablen Namen

Denke daran, Sonderzeichen etc sind nicht erlaubt im Variablen Namen. Lediglich Buchstaben, Zahlen und Unterstriche.

  • $123
  • $achtung!
  • variable

2.2.3. Variablen Typen

Eine Variable kann unterschiedliche Werte aufnehmen, um Beispiel Zahlen oder Text. Allerdings ist es einer PHP Variable egal, welchen Wert du ihr gibst. So ist folgendes Beispiel problemlos möglich:

<?php
	$zahl = 12;
	echo $zahl;
	
	$zahl = "dies ist ein Text";
	echo $zahl;
?>

Als erstes weisen wir der Variable „zahl“ den Integer Wert 12 zu. Danach bekommt sie einen String zugewiesen und gibt den auch brav aus. PHP ist es also egal, welche Werte du in eine Variable packst, aber damit du weißt, welche Typen es gibt und worin sie sich unterscheiden, findest du hier eine Liste mit allen Wert-Typen für Variablen in PHP:

Integer

Bezeichnungen: int, integer, Ganzzahl
Beispiele:

<?php
	$zahl1 = 2;
	$zahl2 = 15;
	$zahl3 = 4432552;
	$zahl4 = 0;
	$zahl5 = 234;
	$zahl6 = -5;
	$zahl7 = -39928;
?>

Ganze Zahlen ohne Nachkommastellen können mit dem Typ Integer gespeichert werden.

Float

Bezeichnungen: float, double, Fließkommazahl
Beispiele:

<?php
	$float_zahl1 = 1.423;
	$float_zahl2 = 166343.23;
	$float_zahl3 = 0.234345;
?>

Anders als beim Typ Integer, können bei Float Werte mit Nachkommastellen gespeichert werden (und nur dafür sollte man float bzw. double nutzen, ansonsten integer)

String

Bezeichnungen: String, Zeichenkette, Text, Zeichen
Beispiele:

<?php
	$string1 = "Hallo Welt";
	$string2 = "test";
	$string3 = "Klaus";
	$string4 = "a";
	$string5 = "xyz";
	$string6 = "123";
	$string7 = "1. Wahl";
?>

Boolean

Bezeichnungen: boolean, bool, Wahrheitswert
Beispiele:

<?php
	$eingeloggt = true;
	$eingeloggt = false;
?>

Boolean ist mitunter der einfachste Typ, denn er kann nur zwei Werte haben: TRUE oder FALSE
Variablen vom Typ boolean werden z.b. für folgende Abfrage eingesetzt:

  • ist der Benutzer eingeloggt? TRUE = Ja, er ist eingeloggt
  • wurde die Taste „p“ gerückt? FALSE = Nein, sie wurde nicht gedrückt
  • hat sich der Benutzer für den Newsletter angemeldet? TRUE = Ja, hat er

Array

Bezeichnungen: array
Beispiel:

<?php
	$zahlen = array(1, 14, 82, 1002);
	$namen = array("Peter", "David", "Henning", "Gerhard", "Norman");
?>

Ein Array ist eine Variable, die mehrere Werte in sich speichern kann. Mehr über den Typ Array findest du hier: Arrays.

Ist das alles?

Es gibt noch weitere, aber dies sind die wichtigsten und mit denen wirst du die meiste Zeit arbeiten.


2.3. PHP Kommentare

Kommentare sind Zeilen in deinem Skript, die der PHP Interpreter einfach ignoriert. Dadurch kannst du dir super Notizen machen oder erklären was dein Code macht, damit du auch später noch dein Skript verstehst.

PHP Kommentare

In PHP gibt es zwei Möglichkeiten Kommentare zu erstellen:

Einzeilige Kommentare

<?php
	echo "Hallo Welt";
	
	//Dies ist ein Kommentar
	
	echo "Hier wird wieder was ausgegeben";
?>

Mehrzeilige Kommentare

<?php
	echo "Hallo Welt";
	
	/* 
	Wenn man mal was mehr zu sagen hat und 
	eine Zeile dafür nicht ausreicht, kann man leicht
	zu mehrzeiligen Kommentare greifen
	*/
	
	//oder man macht es so
	//indem man jede Zeile auskommentiert
	//besser ist aber dann, direkt einen mehrzeiligen
	//Kommentar zu machen
	
	echo "Hier wird wieder was ausgegeben";
?>

2.4. Bedingungen

Bislang können wir zwar wie wild Variablen anlegen und ihnen Werte zuweisen, aber mehr als hier und da die Variablen auszugeben, ist nicht drin. Was machst du z.b. wenn du abhängig vom Wert einer Variablen etwas anderes ausgeben möchtest? Oder wenn du erstmal prüfen möchtest, ob eine Variable einen Wert hat, bevor du sie ausgibst? Lies weiter um zu erfahren, wie das geht.

Einfache Bedingung

<?php
	$zahl = 5;
	
	if($zahl == 5)
		echo "Die Variable hat den Wert 5";
?>

Das Schlüsselwort „if“ leitet unsere Bedingung ein. Der Ausdruck, der in der Klammer steht, muss wahr sein, damit Zeile 5 ausgeführt wird und damit auf dem Bildschirm „Die Variable hat den Wert 5“ erscheint.

Versteh ich nicht, bitte einfacher!

Eine Bedingung fängt immer mit dem Wort „if“ an, gefolgt von einer öffnenden und einer schließenden Klammer:

<?php
	if()
?>

So alleine funktioniert das noch nicht, es fehlt nämlich noch der Ausdruck, der in der Klammer steht. Das kann vieles sein, zum Beispiel kann man zwei Werte miteinander vergleichen ($zahl == 5), oder einfach nur eine Variable reinschreiben ($eingeloggt) oder noch einfacher, man schreibt folgendes:

<?php
	if(true)
		echo "Die Bedingung ist wahr, deshalb siehst du diesen Text";
?>

Oben hab ich schonmal angedeutet, dass der Ausdruck, der in der Klammer steht, wahr sein muss, damit die nächste Zeile ausgeführt wird. Das ist für Anfänger meist erstmal nicht so einfach zu verstehen (bitte frag nach, wenn irgendwas unklar ist!). Wann ist ein Ausdruck wahr? Wann ist er falsch? Wenn du also in deine Klammer „true“ reinschreibst, ist der Ausdruck immer wahr. Das heißt, die Zeile, die der Bedingung folgt, wird immer ausgeführt. Das ist aber nur für Testfälle interessant, denn was würde es uns bringen, wenn eine Bedingung immer wahr ist, dann können wir die Bedingung auch weglassen, weil es immer ausgeführt wird (verstehst du?).

Ein Ausdruck ist wahr oder falsch

Unser Gerüst für eine Bedingung sieht also folgendermaßen aus:

<?php
	if(Ausdruck)
		echo "gib hier irgendwas aus";
?>

Der Ausdruck muss also wahr sein, damit PHP die Zeile mit „echo“ ausführt. Wenn der Ausdruck also falsch ist, wird die Zeile 3 nicht ausgeführt, ganz einfach.

<?php
	$zahl = 12;
	$name = "Hans";
	
	if($zahl == 11)
		echo "Die Variable zahl hat den Wert 11";
		
	if($name == "Hans")
		echo "Die Variable name hat den Wert Hans";
?>

Die erste Bedingung ist falsch, weil unsere Variable „zahl“ nunmal nicht den Wert 11, sondern den Wert 12 hat. Die zweite Bedingung hingegen ist wahr, denn unsere Variable „name“ hat den Wert „Hans“. Achte darauf, dass ein Vergleich von zwei Werten immer mit dem doppelten Gleichheitszeichen erfolgt und eine Wertzuweisung mit einem einfachen Gleichheitszeichen.

Bedingung mit mehrzeiliger Anweisung

Bislang kannst du nur Bedingungen erstellen, die, wenn sie wahr sind, eine Zeile ausgeben. Doch was ist, wenn du mehrzeilige Anweisungen hast? Folgendes funktioniert nämlich nicht:

<?php
	$name = "Hans";

	if($name == "Hans")
		echo "Hallo Hans";
		echo "schön dich wiederzusehen";
?>

Wenn die Bedingung wahr ist, wird beides ausgegeben. Doch wenn du den Wert der Variable name änderst, wird nur noch das zweite echo ausgegeben. Woran liegt das? Ganz einfach, PHP schließt in die Anweisung nur die erste Zeile nach der Bedingung ein, also echo „Hallo Hans“;
Die darauffolgende Zeile wird ganz normal ausgeführt, unabhängig von der Bedingung. Normalerweise sehe der Code auch so aus (ich habe es extra eingerückt, um es deutlich zu machen):

<?php
	$name = "Hans";

	if($name == "Hans")
		echo "Hallo Hans";
	
	echo "schön dich wiederzusehen";
?>

Damit obiges Beispiel korrekt funktioniert, musst du PHP klarmachen, dass du eine mehrzeilige Anweisung hast:

<?php
	$name = "Hans";

	if($name == "Hans")
	{
		echo "Hallo Hans";
		echo "schön dich wiederzusehen";
	}	
?>

Alles was innerhalb der geschweiften Klammern steht, wird ausgeführt wenn die Bedingung wahr ist. Du solltest deine Zeilen ebenfalls so einrücken, durch gut strukurierten Code, wirst du Fehler schneller finden und dein Skript auch nach Monaten leicht verstehen.

Fazit

Bedingungen sind sehr wichtig, doch für Anfänger nicht gerade leicht zu verstehen. Gerade der Punkt, dass Ausdrücke wahr oder falsch sein können, wirft meist viele Fragen auf (frag nach!). Ich hab dieses Kapitel in mehrere Teile aufgesplittet, im nächsten Punkt wirst du Bedingungen mit Alternativen kennenlernen, also was passiert, wenn ein Ausdruck nicht wahr ist. Schau es dir an!


2.4.1. Bedingung mit Alternative – If, else

Bislang weißt du nur, wie man einfache Bedingungen erstellt, doch was ist wenn du eine Alternative haben möchtest? Also wenn die Bedingung nicht wahr ist, dann mache xyz?

Else – Bedingungen mit Alternative

Angenommen du hast ein Login-System auf deiner Webseite und möchtest prüfen, ob ein Benutzer eingeloggt ist und ihm eine Nachricht ausgeben:

<?php
	$eingeloggt = true;

	if($eingeloggt == true)
		echo 'Willkommen zurück!';
?>

Nun möchtest du dem Benutzer aber auch eine Nachricht ausgeben, wenn er nicht eingeloggt ist. Dafür gibt es das Schlüsselwort „else“:

<?php
	$eingeloggt = true;

	if($eingeloggt == true)
		echo 'Willkommen zurück!';
	else
		echo 'Bitte melde dich an.';
?>

Else“ funktioniert nur in Kombination mit dem Schlüsselwort „if“ und muss unmittelbar nach der einzeiligen Anweisung erfolgen, bzw direkt nach einer abschließenden geschweiften Klammer:

<?php
	$eingeloggt = true;

	if($eingeloggt == true) 
	{
		echo 'Willkommen zurück!';
	}
	else
	{
		echo 'Bitte melde dich an.';
	}
?>

Auch „else“ arbeitet mit einzeiligen und mehrzeiligen Anweisungen und braucht für zweiteres ebenfalls die geschweiften Klammern. Zur besseren Übersichtlichkeit und um Fehler zu vermeiden, empfehle ich Anfängern immer mit geschweiften Klammern zu arbeiten, auch bei einzeiligen Anweisungen.

Im nächsten Teil erfährst du, dass man mehr als eine Alternative pro If-Bedingung angeben kann.


2.4.2. Noch mehr Möglichkeiten – If, else if, else

Manchmal reicht eine Alternative einfach nicht aus. Deshalb können wir in PHP nicht nur „if“ und „else“ nutzen, sondern auch „else if“ und davon soviele wie wir möchten. Sieh dir dazu erstmal folgendes Beispiel an:

<?php
	$zahl = 1;
	
	if($zahl == 0)
		echo 'Die Variable "zahl" hat den Wert 0';
	else if($zahl == 1)
		echo 'Die Variable "zahl" hat den Wert 1';
	else
		echo 'Die Variable "zahl" ist ungleich 0 und 1';
?>

Wir können also mit „else if“ bzw. „elseif“ eine weitere Bedingung abfragen. Wenn also der Ausdruck der ersten if-Bedingung „falsch“ zurückgibt, wird die Bedingung von „else if“ geprüft. Gibt auch diese „falsch“ zurück, nutzt die Bedingung die „else“-Anweisung und führt die Befehle darin aus.

Natürlich kann man „if“ und „else if“ auch ohne „else“ nutzen. Ausserdem kann man beliebig viele „else if“-Abfragen nach dem ersten „if“ setzen, doch dass das in den meisten Fällen besser mit switch gelöst wird, sehen wir später.


2.4.3. Vergleichsoperatoren

Bislang können wir nur Werte direkt miteinander vergleichen, also hat die Variable „zahl“ den Wert „10“ oder hat die Variable „name“ den Wert „Max“. Doch häufig reicht das nicht aus und man möchte z.b. wissen, ob die Variable einen Wert größer 10 hat oder einen Wert der zwischen 100 und 200 liegt. Dafür gibt es dann weitere Vergleichsoperatoren:

  • $a == $b – prüft ob beide Werte gleich sind
  • $a != $b – prüft ob die Werte ungleich sind
  • $a < $b – prüft ob der linke Wert kleiner als der rechte Wert ist
  • $a > $b – prüft ob der linke Wert größer als der rechte Wert ist
  • $a <= $b – prüft ob der linke Wert kleiner oder gleich ist vom rechten Wert
  • $a >= $b – prüft ob der linke Wert größer oder gleich ist vom rechten Wert
  • $a <> $b – prüft ob die Werte ungleich sind (funktioniert genau wie $a != $b )
  • $a === $b – prüft ob beide Werte gleich sind und ob beide vom selben Typ sind
  • $a !== $b – prüft ob die Werte ungleich sind und ob beide einen unterschiedlichen Typ haben

Quelle

$a == $b

Das doppelte Gleichheitszeichen kennst du schon, damit können wir zwei Werte vergleichen, und wenn sie den gleichen Wert haben, dann ist der Ausdruck wahr.

Beispiele:

<?php
	if(5 == 5)
		echo 'Der Ausdruck ist wahr';
?>
<?php
	$a = 5;

	if($a == 5)
		echo 'Der Ausdruck ist wahr';
?>
<?php
	$a = 5;
	$b = 5;

	if($a == $b)
		echo 'Der Ausdruck ist wahr';
?>

$a != $b

Das Gegenteil vom doppelten Gleichheitszeichen, prüft ob die beiden Werte ungleich sind. Wenn beide Werte ungleich sind, ist der Ausdruck wahr

Beispiele:

<?php
	if(5 != 4)
		echo 'Der Ausdruck ist wahr, denn 5 ist ungleich 4';
?>
<?php
	$a = 5;

	if($a != 4)
		echo 'Der Ausdruck ist wahr, denn 5 ist ungleich 4';
?>

$a < $b

Ist der Wert der Variable „a“ kleiner als der Wert der Variable „b“, dann ist der Ausdruck wahr.

<?php
	$a = 5;

	if($a < 10)
		echo 'Der Ausdruck ist wahr, denn 5 ist kleiner 10';
?>
<?php
	$a = 5;

	if($a < 6)
		echo 'Der Ausdruck ist wahr, denn 5 ist kleiner 6';
?>

$a > $b

Ist der Wert der Variable „a“ größer als der Wert der Variable „b“, dann ist der Ausdruck wahr.

<?php
	$a = 5;

	if($a > 4)
		echo 'Der Ausdruck ist wahr, denn 5 ist größer 4';
?>

$a <= $b

Ist der Wert der Variable „a“ kleiner oder gleich als der Wert der Variable „b“, dann ist der Ausdruck wahr.

<?php
	$a = 3;

	if($a <= 4)
		echo 'Der Ausdruck ist wahr, denn 3 ist kleiner 4';
?>
<?php
	$a = 5;

	if($a <= 5)
		echo 'Der Ausdruck ist wahr, denn 5 ist gleich 5';
?>

$a >= $b

Ist der Wert der Variable „a“ größer oder gleich als der Wert der Variable „b“, dann ist der Ausdruck wahr.

<?php
	$a = 5;

	if($a >= 4)
		echo 'Der Ausdruck ist wahr, denn 5 ist größer 4';
?>
<?php
	$a = 5;

	if($a >= 5)
		echo 'Der Ausdruck ist wahr, denn 5 ist gleich 5';
?>

$a <> $b

Ist der Wert der Variable „a“ ungleich dem Wert der Variable „b“, dann ist der Ausdruck wahr. Genau wie der Ausdruck $a != $b

<?php
	$a = 5;

	if($a <> 4)
		echo 'Der Ausdruck ist wahr, denn 5 ist ungleich 4';
?>
<?php
	$a = 10;
	$b = 1;

	if($a <> $b)
		echo 'Der Ausdruck ist wahr, denn 10 ist ungleich 1';
?>

$a === $b

Das dreifache Gleichheitszeichen funktioniert wie das doppelte Gleichheitszeichen und prüft den Wert beider Variablen. Doch zusätzlich prüft das dreifache Gleichheitszeichen noch, ob die beiden Variablen vom gleichen Typ sind. Dazu ein Beispiel:

<?php
	$a = 0;
	if($a == false)
		echo 'Der Ausdruck ist wahr, denn der Wert 0 ist gleich false';
?>

Der Ausdruck in obigem Beispiel ergibt wahr denn der Wert integer Wert „0“ ist gleich dem boolischen Wert „false“. Der Ausdruck in folgendem Beispiel hingegen funktioniert nicht:

<?php
	$a = 0;
	if($a === false)
		echo 'Dieses "echo" wird nicht ausgeführt.';
?>

Der Ausdruck ist falsch, denn auch wenn die Werte „0“ und „false“ gleich sind, so sind die beiden Typen Integer (0) und Boolean (false) ungleich.

$a !== $b

Geprüft wird, ob die Werte der beiden Variablen unterschiedlich sind und ob die Variablen einen unterschiedlichen Typen haben.

<?php
	$a = 0;
	if($a !== false)
		echo 'Der Ausdruck ist wahr, denn der Wert "0" ist zwar gleich "false", aber die beiden Typen Integer und Boolean sind unterschiedlich.';
?>

2.4.4. Wahrheitswerte kombinieren

Bislang haben wir innerhalb der Bedingung nur für einen Wert geprüft, ob der Wert wahr oder falsch ist. Doch man kann mehrere Wahrheitswerte kombinieren:

AND (&&)

Häufig ist eine Bedingung von zwei Werten abhängig, also nur wenn beide Werte WAHR sind, ist die Bedingung erfüllt. Ein gutes Beispiel ist ein Kommentarsystem. Du möchtest deinen Benutzern erlauben, auf deiner Seite Kommentare zu schreiben, aber nur wenn der Benutzer seinen Namen und eine Email-Adresse angibt.

<?php
	$name = "Klaus";
	$email = "klaus63552@fakemail.de";

	if($name != '')
	{
		if($email != '')
		{
			echo 'Dein Kommentar wurde gespeichert';
		}
	}
?>

Hier siehst du erstmal, dass man Bedingungen auch ineinander verschachteln kann, also erst wird geprüft, ob der Benutzer einen Namen eingegeben und danach ob er auch eine EMail Adresse angegeben hat. Wenn beide Bedingungen wahr sind, wird der Kommentar gespeichert. Das kann man aber auch kürzer schreiben:

<?php
	$name = "Klaus";
	$email = "klaus63552@fakemail.de";

	if(($name != '') && ($email != ''))
	{
		echo 'Dein Kommentar wurde gespeichert';
	}
?>

Das &&-Zeichen steht für AND und heißt soviel wie, die erste Bedingung muss wahr ergeben und die zweite Bedingung ebenfalls, damit der gesamte Ausdruck wahr ist. Also, dass „if“-Statement möchte nur einen Wert aus der Klammer erhalten, WAHR oder FALSCH. Wir können aber innerhalb der Klammer mehrere Wahrheitswerte kombinieren und mit dem &&-Operator sagen, dass alle Bedingungen wahr sein sollen.

OR (||)

Zusätzlich zum &&-Operator gibt es noch den ||-Operator, den ODER-Operator. Dieser sagt, dass nur eine Bedingung wahr sein muss, damit der gesamte Ausdruck wahr ist. Wenn wir obiges Beispiel ein wenig anpassen:

<?php
	$name = "Klaus";
	$email = "";

	if(($name != '') || ($email != ''))
	{
		echo 'Dein Kommentar wurde gespeichert';
	}
?>

Jetzt reicht es schon, wenn der Besucher entweder seinen Namen angibt oder seine Email-Adressen. Er kann aber auch weiterhin beides angeben, damit das if-Statement wahr ist. Der einzige Fall wo es nicht klappt ist, wenn er weder den Namen, noch die Email Adresse angibt.

Drei und mehr Bedingungen kombinieren

Natürlich ist man nicht auf zwei Bedingungen beschränkt, man kann soviele Bedingungen miteinander kombinieren wie man mag:

<?php
	if(($wert1 != 0) && ($wert2 > 100) && ($wert2 <= 200))
	{
		//WAHR, nur wenn alle 3 Bedingungen wahr sind
	}
?>
<?php
	if(($wert1 != 0) || ($wert2 > 100) || ($wert2 <= 200))
	{
		//WAHR, wenn einer der 3 Bedingungen wahr sind
	}
?>
<?php
	if((($wert1 != 0) || ($wert2 > 100)) && ($wert2 <= 200))
	{
		//WAHR, wenn entweder Bedingung 1 oder Bedingung 2 wahr ist UND Bedingung 3 wahr ist
		//bei solchen Konstruktionen auf die Klammersetzung achten!
	}
?>
<?php
	if((($wert1 != 0) && ($wert2 > 100)) || ($wert2 <= 200))
	{
		//WAHR, wenn entweder Bedingung 1 und Bedingung 2 wahr sind ODER Bedingung 3 wahr ist
		//bei solchen Konstruktionen auf die Klammersetzung achten!
	}
?>

Fazit

Dies ist das Kombinieren von Wahrheitswerten. Als Ergebnis erhält man immer nur WAHR oder FALSCH doch kann man dadurch mehrere Fälle zusammen abfragen. Umso mehr Bedingungen man miteinander kombiniert, desto komplexer wird die Abfrage und damit schwerer für andere zu verstehen. Daher macht es manchmal Sinn auf die Kombination von Wahrheitswerten zu verzichten und stattdessen die einzelnen Abfragen in if-Verschachtelungen abzufragen.


2.4.5. Ternärer Operator – Kurzform für If then else

Das „if else“-Konstrukt wird in PHP sehr häufig verwendet, daher haben die Entwickler eine Kurzform für if else herausgebracht. Auch wenn sie für Anfänger häufig nicht so leicht verstanden wird, kann sie in manchen Fällen Platz und Codezeilen sparen. Das ganze nennt sich der ternärer Operator und sieht folgendermaßen aus:

Die Syntax für die Kurzform von if else sieht folgendermaßen aus:

<?php
	(wenn Ausdruck wahr) ? (mache das hier) : (ansonsten das hier)
?>

Nun ein paar Beispiele:

<?php
	if($alter < 18)
		echo 'Du bist nicht volljährig';
	else
		echo 'Du bist volljährig';

	//als Kurzform
	echo ($alter < 18) ? 'Du bist nicht volljährig' : 'Du bist volljährig';
?>
<?php
	if($a > $b)
		$b = $a;
	else
		$a = $b;

	//als Kurzform
	($a > $b) ? $b = $a : $a = $b;
?>
<?php
	if($a > $b)
		$c = $a;
	else
		$c = $b;

	//als Kurzform
	$c = ($a > $b) ? $a : $b;
?>

Angenommen wir haben eine Anzeige die dir die Stunden ausgibt seitdem du das letzte mal eingeloggt warst. Also ist die Ausgabe „zuletzt eingeloggt vor x Stunden“, doch für die Stunde 1 müsste die Ausgabe folgendermaßen lauten: „zuletzt eingeloggt vor 1 Stunde“, also ohne das n.

Normal:

<?php
	if($stunden == 1)
		echo 'zuletzt eingeloggt vor 1 Stunde';
	else
		echo 'zuletzt eingeloggt vor '.$stunden.' Stunden';
?>

If Else Kurzform

<?php
	echo 'zuletzt eingeloggt vor '.$stunden.' Stunde'.(($stunden==1) ? "" : "n");
?>

Natürlich kann man das auch immer mit dem kompletten „if/else“-Konstrukt machen, meistens ist das sogar verständlicher, doch in manchen Fällen ist eine Kurzform einfach nützlich.

If, Else if, Else

Mit dem ternären Operator lassen sich auch If, ElseIf, Else Abfragen verkürzen. Persönlich gefällt mir der Einsatz des ternären Operators nicht, da es meiner Meinung nach den Quellcode erschwert (sprich, für andere den Code zu verstehen). Dennoch zur Vollständigkeit:

<?php
	$auswahl = 1;
	echo $geschlecht = ($auswahl == 1) ? "männlich" : (($auswahl == 2) ? "weiblich" : "unbekannt");	
?>

Wenn die Variable $auswahl den Wert 1 hat, wird „männlich“ ausgegeben, für den Wert 2 wird „weiblich“ ausgegeben. Sollte $auswahl keinen Wert haben oder einen Wert der weder 1 noch 2 ist, wird „unbekannt“ ausgegeben.


2.4.6. Endif – Alternative Syntax zur geschweiften Klammer

PHP bietet noch eine weitere Schreibweise für die if then else Bedingung an. Diese ist vorallem praktisch, wenn man größere Blöcke HTML direkt ausgeben möchte (ohne z.b. „echo“ zu benutzen).

Standard-Schreibweise

<?php
	$id = 5;

.
.
.

	if($id == 5)
	{
		echo '<p>text</p>';
		echo '<p>text</p>';
		echo '<p>text</p>';
		echo '<p>text</p>';
	}
?>

Anstelle der geschweiften Klammern kann man auch mit einer alternativen Schreibweise arbeiten:

<?php
	$id = 5;	
?>

.
.
.

<?php if($id == 5): ?>
		<p>text</p>
		<p>text</p>
		<p>text</p>
		<p>text</p>
<?php endif; ?>

Dadurch kann man auf die ganzen „echo“-Befehle verzichten und den HTML-Code direkt ausgeben. Wird die Bedingung hingegen nicht erfüllt (sprich, $id != 5), wird der HTML-Code-Block nicht ausgegeben.

Möchtest du innerhalb des HTML-Blocks PHP-Befehle ausführen, muss du erst wieder die PHP-Tags öffnen:

<?php if($id == 5): ?>
		<p>text</p>
		<p>text</p>
		<p>text</p>
		<p><?php echo 'hallo welt'; ?></p>
		<p>text</p>
<?php endif; ?>

Geschweifte Klammern bei alternativer Syntax sind aber immernoch möglich

Das gleiche Ergebnis läßt sich aber auch mittels der geschweiften Klammer erzielen:

<?php
	$id = 1;
?>

<?php if($id == 5) { ?>
	<p>text</p>
	<p>text</p>
<?php } else if($id > 5) { ?>		
	<p>Alternative</p>
<?php } else { ?>	
	<p>Ende</p>	
<?php } ?>

Nicht nur Kontrollstrukturen spielen brav mit der alternativen Syntax, auch Schleifen wie z.b. foreach haben damit keinerlei Probleme:

<?php
	$elemente = array(1, 2, 3);
?>

<?php foreach($elemente as $element): ?>
	<p>Element Nr.<?php echo $element; ?></p>
<?php endforeach; ?>

Zugegeben, in diesem Beispiel macht es nicht sonderlich viel auf die alternative Syntax zurückzugreifen, aber ich hoffe du verstehst worauf ich damit hinaus möchte :)


2.5. Switch

Im Kapitel zu if, else if, else habe ich schon angesprochen, dass man statt einer Reihe von „else if“-Abfragen besser ein Switch-Konstrukt nutzt.

<?php
	switch($zahl) {
		case 0:
			echo 'Durch 0 darf man nicht teilen';
			break;
		case 1:
			echo 'Die Zahl 1 ist sehr klein';
			break;
		case 99999:
			echo 'Das ist eine sehr große Zahl';
			echo 'kurz vor hunderttausend';
			break;
	}
?>

Switch ist dafür gedacht, eine Variable auf mehrere Werte zu prüfen und für den jeweiligen Wert, einen unterschiedlichen Code auszuführen. Das selbe könnte man auch mit mehreren „else if“-Abfragen bewerkstelligen, doch switch ist dafür aufgrund seiner Struktur übersichtlicher. Der Code ist schnell erklärt:

  • switch erwartet eine Variable und prüft dann den Wert
  • für jeden Wert kann ein „case“ angelegt werden
  • das „break;“ nach jeder Anweisung besagt, dass die Switch-Abfrage beendet wird, wenn ein Wert gefunden wurde
  • nach einem „case“ können ein- und mehrzeilige Anweisungen folgen

„default“ ersetzt „else“ in der Switch Anweisung

Auch für die Switch Anweisung gibt es eine „else“ Bedingung doch hier heißt sie „default“:

<?php
	switch($zahl) {
		case 0:
			echo 'Zahl 0';
			break;
		case 1:
			echo 'Zahl 1';
			break;
		default:
			echo 'Eine Zahl ungleich 0 oder 1';
	}
?>

Default steht am Ende nach allen „case“-Anweisungen und muss auch nicht mit einem break geschlossen werden, da die Switch-Anweisung an dieser Stelle sowieso zuende ist.

Natürlich kann man nicht nur Zahlen sondern auch Strings prüfen:

<?php
	switch($name) {
		case 'Lisa':
			echo 'Lisa ist ein schöner Name';
			break;
		case 'Laura':
			echo 'Hey Laura, ebenfalls ein schöner Name';
			break;
		default:
			echo 'Auch dein Name ist schön, '.$name;
	}
?>

Warum die Switch Anweisung verwenden?

Es gibt eigentlich nur 2 Gründe:

  1. bei vielen „case“-Anweisungen kann switch schneller sein als mehrere „else if“-Anweisungen
  2. in manchen Fällen ist es übersichtlicher, gerade wenn man viele „case“-Anweisungen hat, bzw eine Variable auf viele unterschiedliche Fälle prüfen möchte (z.b. welche Taste wurde gedrückt: „oben“, „unten“, „links“, „rechts“, „space“, „enter“, etc.)

2.6. Arrays

Ein Array ist ebenfalls eine Variable, die allerdings anstatt nur einem Wert, viele Werte speichern kann. Stell dir vor du hast 5 Namen, die du in Variablen speichern möchtest. Mit deinem bisherigen Wissen müsstest du das folgendermaßen machen:

<?php
	$name1 = "David";
	$name2 = "Norman";
	$name3 = "Gerhard";
	$name4 = "Henning";
	$name5 = "Peter";
?>

Das ist doof, umständlich und problematisch. Einfacher geht es mit einem Array:

<?php
	$namen[] = "David";
	$namen[] = "Norman";
	$namen[] = "Gerhard";
	$namen[] = "Henning";
	$namen[] = "Peter";
?>

Uh? Was ist denn hier jetzt passiert?
Als erstes siehst du die Variable „$namen“, das ist unser Array. Doch die Variable hat noch so eine eckige-Klammer „[]“ hinter dem Namen. Damit sagen wir dem Array „jetzt kommt ein Wert den wir speichern wollen, leg also im Array einen neuen Eintrag an“. Nicht verstanden? Dann jetzt mal Schritt für Schritt.

Arrays Schritt für Schritt erklärt

Wir können ein Array in PHP mit folgender Anweisung anlegen:

<?php
	$namen = array();
?>

Wir müssen das nicht so explizit machen (im ersten Beispiel habe ich auch drauf verzichtet), aber es schadet auch nicht. Das Array hat noch keinen Wert, deshalb fügen wir ihm jetzt einen hinzu:

<?php
	$namen = array();
	$namen[] = "David";
	
	echo $namen;
?>

Wenn du das Skript ausführst, wirst du als Ausgabe „Array“ erhalten. Das ist auch korrekt, denn Arrays arbeiten ein bisschen anders als Variablen. Um alle Werte in einem Array zu erhalten, gibt es die Funktion „print_r()“:

<?php
	$namen = array();
	$namen[] = "David";
	
	print_r($namen);
?>

Ausgabe:

Ok, also der Name wurde gespeichert und befindet sich an Position „0“ im Array. Moment…. Position 0???
Ja also.. öhm… das ist zwar etwas seltsam, aber in Arrays startet der erste Wert nicht an Position 1, sondern an Position 0. Das wird in den kommenden Wochen für dich auch immer wieder eine Fehlerquelle sein, aber so ist es nunmal, Arrays starten bei 0, Arrays starten bei Position 0, Position 0 == 1. Wert

Du wirst dazu gleich noch weitere Beispiele sehen. Als erstes wollen wir unser Namens-Array mit weiteren Namen füttern:

<?php
	$namen = array();
	$namen[] = "David";
	$namen[] = "Norman";
	$namen[] = "Gerhard";
	$namen[] = "Henning";
	$namen[] = "Peter";
	
	print_r($namen);
?>

Dies ist nur eine Variante ein Array mit Werten zu erstellen, eine andere Variante ist folgende:

Nun sieht die Ausgabe schon interessanter aus:

Wenn du noch eine kleine Formatierung machst, wird das Array auch übersichtlicher angezeigt:

<?php
	$namen = array("David", "Norman", "Gerhard", "Henning", "Peter");
	
	echo '<pre>';
	print_r($namen);
	echo '</pre>';
?>

Wie du siehst, werden im Array die Plätze 0, 1, 2, 3 und 4 belegt für 5 Namen.
Du weißt nun, dass man mit „print_r()“ ein Array komplett ausgibt und mit den HTML-Tags „pre“, die Ausgabe schön formatieren kann. Aber normalerweise möchte man ja nicht das komplette Array ausgeben (fürs debugging/fehler finden sehr nützlich), sondern einzelne Werte bearbeiten und anzeigen.

Array Werte hinzufügen, ausgeben und löschen

Wie man Werte einem Array hinzufügt, hast du schon gesehen. Einfach der Name des Arrays + []-Klammern = Wert:

<?php
	$namen = array("David", "Norman", "Gerhard", "Henning", "Peter");
?>

Der Versuch „echo $namen;“ führte zu nichts, denn das gesamte Array können wir nicht ausgeben. Wir müssen auf die einzelnen Container im Array zugreifen. Möchtest du z.b. den Namen „Gerhard“ ausgeben, führt dich folgender Code zum Ziel:

<?php
	$namen = array("David", "Norman", "Gerhard", "Henning", "Peter");
	
	echo $namen[2];
?>

Um einen bestimmten Array-Wert auszugeben, musst du einfach nur die Container-Nummer angeben. Achte darauf, dass wir hier Container-Nummer 2 angegeben haben, denn an Position 0 ist „David“ an Position 1 ist „Norman“ und erst an Position 2 ist „Gerhard“. Vergiss niemals die Position 0 in einem Array zu berücksichtigen!

Gut, jetzt können wir Array-Werte hinzufügen und ausgeben, doch was ist wenn wir einen Array Wert löschen wollen?
Wir haben ein kleines Spiel in PHP programmiert und oben ist unser Array mit allen 5 Spielern. Nun hat der Spieler „Henning“ verloren und wir wollen ihn aus unserem Array löschen. Dazu hilft uns die Funktion „unset()“.

<?php
	$namen = array("David", "Norman", "Gerhard", "Henning", "Peter");
	
	echo "Anzahl Spieler: ".count($namen)."<br />";
	unset($namen[3]);
	echo "Anzahl Spieler: ".count($namen)."<br />";

        echo '<pre>';
	print_r($namen);
	echo '</pre>';
?>

In Zeile 4 geben wir erstmal aus, wieviele Spieler wir derzeit haben. Die Funktion „count()“ gibt die Anzahl aller Elemente eines Arrays aus. In Zeile 5 löschen wir mit „unset()“ den 3. Container, also den Spieler „Henning“ (0. Container beachten!). In Zeile 6 prüfen wir nun nochmal, wieviele Spieler vorhanden sind und stellen fest, dass nun nur noch 4 Spieler dabei sind.

Zum Schluss geben wir nochmal das Array formatiert aus und stellen fest, dass zwar der Spieler gelöscht wurde, aber die Array-Indizes (also die Container-Zahlen) lückenhaft sind (die 3 fehlt). Im Kapitel Schleifen wirst du sehen, dass das nicht so toll ist und fortlaufende Indizes weniger Probleme machen. Daher müssen wir, nachdem der Spieler „Henning“ gelöscht wurde, noch schnell das Array neu auflisten mit der PHP Funktion „array_values($namen);“:

<?php
	$namen = array("David", "Norman", "Gerhard", "Henning", "Peter");
	
	echo "Anzahl Spieler: ".count($namen)."<br />";
	unset($namen[3]);
	echo "Anzahl Spieler: ".count($namen)."<br />";
	
	echo '<pre>';
	print_r($namen);
	echo '</pre>';
	
	$namen = array_values($namen);
	
	echo '<pre>';
	print_r($namen);
	echo '</pre>';
?>

Ausgabe:

Array – Fazit

Damit haben wir gerade mal an der Oberfläche von Arrays gekratzt. Arrays werden ständig benötigt und machen die Programmierung mit PHP erst so richtig dynamisch. Wenn dir etwas unklar ist oder du noch Fragen hast, zögere nicht und stell sie (Feedback-Button auf rechter Seite).


2.6.1. Assoziative Arrays

Assoziative Arrays unterscheiden sich von normalen Arrays in nur einem Punkt: Anstelle von Zahlen-Indizes haben assoziative Arrays, Namen als Index-Wert:

<?php
	//normales Array
	$spieler = array("Marie", "Anna", "Lars", "Martin");
	echo $spieler[2] ; // Ausgabe => Lars
	
	//assoziatives Array
	$spieler["Marie"] = 4030;
	$spieler["Anna"] = 2313;
	$spieler["Lars"] = 120;
	$spieler["Martin"] = 2819;
	
	echo "Punktzahl: ".$spieler["Anna"]; // Ausgabe => Punktzahl: 2313
?>

Assoziative Arrays bieten daher die Möglichkeit, „logischer“ zu sein und den Quellcode verständlicher zu machen.


2.6.2. Mehrdimensionales Array

Wenn man ein Array benötigt, welches pro Container mehr als einen Wert speichern soll, greift man auf mehrdimensionale Arrays zurück. Stell dir vor, du hast ein Schachbrett und möchtest alle Felder in einem Array speichern. 8 Reihen x 8 Zeilen = 64 Felder => 64 Elemente in unserem Array:

<?php
	$schachbrett[0] = "A1";
	$schachbrett[1] = "A2";
	$schachbrett[2] = "A3";
	$schachbrett[3] = "A4";
	...
	$schachbrett[8] = "B1";
	$schachbrett[9] = "B2";
	$schachbrett[10] = "B3";
	...
	$schachbrett[62] = "H7";
	$schachbrett[63] = "H8";
?>

Damit hätten wir ein ein-dimensionales Array mit 64 Feldern. Das ist natürlich möglich, man kann das Schachbrett aber auch als zwei-dimensionales Array erzeugen:

<?php
	$schachbrett[0][0] = "A1";
	$schachbrett[0][1] = "A2";
	$schachbrett[0][2] = "A3";
	$schachbrett[0][3] = "A4";
	$schachbrett[0][4] = "A5";
	$schachbrett[0][5] = "A6";
	$schachbrett[0][6] = "A7";
	$schachbrett[0][7] = "A8";
	$schachbrett[1][0] = "B1";
	$schachbrett[1][1] = "B2";
	$schachbrett[1][2] = "B3";
	$schachbrett[1][3] = "B4";
	$schachbrett[1][4] = "B5";
	...
	$schachbrett[7][6] = "H7";
	$schachbrett[7][7] = "H8";
	
	echo $schachbrett[0][4]; //Ausgabe => A5
	echo $schachbrett[1][2]; //Ausgabe => B3
?>

Man kann aber noch mehr Werte in sein Array packen, also entweder die Anzahl der Dimensionen erhöhen und oder das ganze mit einem assoziativen Array kombinieren:

<?php
	$schachbrett[0][0] = array("Feld" => "A1", "Farbe" => "schwarz");
	$schachbrett[0][1] = array("Feld" => "A2", "Farbe" => "weiß");
	$schachbrett[0][2] = array("Feld" => "A3", "Farbe" => "schwarz");
	$schachbrett[0][3] = array("Feld" => "A4", "Farbe" => "weiß");
	
	echo '<pre>';
	print_r($schachbrett);
	echo '</pre>';
	
	echo $schachbrett[0][2]["Farbe"]; // Ausgabe => schwarz
?>

Ausgabe:


2.6.3. Array Werte sortieren

PHP bietet einige Standard-Funktionen zum sortieren von Arrays an: Array Sortier-Funktionen
Mit diesen ist es möglich ein eindimensionales Array beliebig zu sortieren:

<?php
	$zahlen = array(7, 3, 0, 8);

	echo '<pre>';
	print_r($zahlen);
	echo '</pre>';
	
	sort($zahlen);
	
	echo '<pre>';
	print_r($zahlen);
	echo '</pre>';
?>

In diesem Beispiel wird die Array-Sortier-Funktion „Sort“ verwendet. Sort sortiert die Werte eines Arrays von klein nach groß. Möchte man die Werte anstelle von „klein nach groß“ von „groß nach klein“ sortieren, kann man dafür die Funktion rSort benutzen.

Array nach Zufall sortieren – shuffle

Hin und wieder möchte man die Werte eines Arrays durcheinandermischen, dazu empfiehlt sich die Funktion shuffle. Shuffle durchschmischt alle Werte eines Arrays und sollte bei jedem Aufruf eine andere Reihenfolge erzeugen.

Array alphabetisch sortieren

Hat man ein Array was nur aus Strings besteht (z.b. SchülerInnen-Namen einer Klasse) und möchte alle Namen alphabetisch sortieren, kann man dafür ebenfalls die Funktion sort verwendet:

<?php
	$namen = array("Michael", "Alex", "Peter", "Yvonne", "Fabian", "Sabine");

	echo '<pre>';
	print_r($namen);
	echo '</pre>';
	
	sort($namen);
	
	echo '<pre>';
	print_r($namen);
	echo '</pre>';
?>

Array sortieren und Umlaute berücksichtigen

PHP sollte sich beim sortieren eines Arrays an Umlaute eigentlich nicht stören und das Array anhand dieser Reihenfolge sortieren: Deutsches Alphabet – Reihenfolge


2.6.4. Mehrdimensionales Array sortieren


2.7. Schleifen

Schleifen sind ebenfalls ein Konstrukt, was du ständig brauchen wirst. Gerade wenn du einen bestimmten Algorithmus häufig wiederholen willst oder wenn du z.b. ein Array durchlaufen möchtest, sind Schleifen die richtige Wahl.

In PHP gibt es vier Schleifen-Varianten:

  • For-Schleifen
  • While-Schleifen
  • Do-While-Schleifen
  • Foreach-Schleifen

Es kommt auf den jeweiligen Fall an, welche Variante am besten geeignet ist. Aus meiner Erfahrung kann ich sagen, dass du die For-Schleife und die While-Schleife deutlich häufiger brauchen wirst, als die Do-While-Schleife, doch versuche sie alle zu verstehen. Wenn du etwas in den folgenden 4 Teilen nicht verstehst oder Fragen hast, zögere nicht einen Kommentar zu hinterlassen.


2.7.1. For-Schleife

Die For-Schleife ist der erste Schleifen-Typ, den wir kennenlernen. Der typische Aufbau sieht folgendermaßen aus:

<?php
	for($i=0; $i < 10; $i++)
	{
		echo $i."<br />";
	}
?>

In Zeile 2 sind alle Bedingungen der For-Schleife angegeben. Mit dem Schlüsselwort „for“ wird PHP mitgeteilt, dass die For-Schleife hier beginnt. Innerhalb der Klammer sind 3 Blöcke, getrennt durch Semikolons „;“:

  • $i=0 – Im ersten Block erhält unsere Zählvariable ihren Startwert. Wir nennen unsere Zählvariable „i“, sie kann aber auch jeden anderen Namen haben, etwa „zaehler“, „counter“, „sdfaawerwe“, etc.
  • $i < 10 – Nun folgt die Abbruchbedingung der Schleife. Solange der Wert der Zählvariable „i“ kleiner als 10 ist, wird die Schleife ausgeführt
  • $i++ – Bei jedem Schleifendurchlauf erhöht sich die Zählvariable um den Wert 1. Dadurch ist gewährleistet, dass unsere Schleife nach 10 Durchläufen beendet wird. Natürlich kann man auch den Wert um 2 oder mehr erhöhen: „$i = $i + 2“

Wenn du das Beispiel ausführst, solltest du eine vertikal-verlaufende Zahlenreihe von 0-9 sehen. Die Zählvariable ist das Herzstück der Schleife, denn nur durch ihren Wert weiß die Schleife, wann sie beendet werden soll.

Array mit Schleife durchlaufen

Im Abschnitt Arrays haben wir ein Array mit Namen angelegt. Dieses wollen wir jetzt mal mit einer for-Schleife ausgeben:

<?php
	$namen = array("David", "Norman", "Gerhard", "Henning", "Peter");
	
	for($i=0; $i < 5; $i++)
	{
		echo $namen[$i]."<br />";
	}
?>

Anstelle also die Container manuell aufzurufen ($namen[0], $namen[1], $namen[2], etc.) nutzen wir eine Schleife, die für uns alle Container anzeigt. Die Schleife startet bei „0“ (weil das 0. Array Element unser 1. Wert ist) und endet sobald $i den Wert 5 hat. Wenn die Schleife feststellt, dass ihre Zählvariable den Wert 5 hat, geht sie nicht mehr in den Ausführungsbereich.

Mit einer Schleife können wir also Programmierzeilen zusammenfassen, bzw eine Operation die wir x-mal schreiben müssten in einer Schleife zusammenfassen. Für 5 Werte macht das noch nicht wirklich Sinn, aber stell dir mal vor, unser Array hätte 2000 oder mehr Namen.

Ist das soweit verständlich?

Endlosschleifen

Ich habe schon darauf hingewiesen, dass eine Schleife eine Abbruchbedingung braucht. Denn wenn eine Schleife nicht abbricht, läuft sie endlos => Endlosschleife. Schau dir dazu folgendes Beispiel an:

<?php
	for($i=0; $i < 5; $i++)
	{
		echo $i."<br />";
		$i--;
	}
?>

Wir haben zwar eine Abbruchbedingung und die Zählvariable wird nach jedem Durchlauf um eins hochgezählt, doch innerhalb der Schleife wird sie immer um 1 reduziert. PHP prüft sowas natürlich nicht, das liegt an uns sowas zu vermeiden/verhindern. Dies ist noch ein einfaches Beispiel, doch manchmal schleichen sich Fehler ein, die nicht so schnell zu finden sind. Andererseits kommt man Endlosschleifen schnell auf die Schliche, denn wenn man sein Skript testet und es nicht fertig wird, liegt das in der Regel an einer Endlosschleife.

For-Schleife Zusammenfassung

Die For-Schleife ist essentiell in PHP und mit ihrer Zählvariable kann man Arrays einfach durchlaufen. Nach jedem Durchlauf kann der Wert der Zählvariable verändert werden, dies ist nötig damit die Abbruchbedingung der Schleife erreicht wird und keine Endlosschleife entsteht.


2.7.2. While-Schleife

Der Aufbau einer While-Schleife ist anders als bei der For-Schleife:

<?php
	$i = 0;
	while($i < 10)
	{
		echo $i."<br />";
		$i++;
	}
?>

aber dennoch finden sich auch hier die Initialisierung der Zählvariable (Zeile 2), die Abbruchbedingung (Zeile 3) und die Erhöhung der Zählvariable (Zeile 6) wieder. Die While-Schleife läuft solange, bis die Abbruchbedingung erfüllt ist. Die While-Schleife prüft erstmal ob das Statement, also die Bedingung innerhalb der Klammer, TRUE ergibt. Wenn dies zutrifft, wird der Schleifeninhalt ausgeführt, wenn nicht, wird die Schleife nicht einmal ausgeführt.

Zur While-Schleife gibt es eigentlich nicht viel mehr zu sagen, sie unterscheidet sich ein wenig von der for-Schleife, aber nur minimal. Ob man die for- oder die while-Schleife nutzt, kommt auf den jeweiligen Anwendungsfall an.


2.7.3. Do-While-Schleife

Eine Do-While-Schleife arbeitet nahezu identisch wie eine while-Schleife, doch mit einem entscheidenden Unterschied: Die Prüfung der Abbruchbedingung erfolgt am Ende der Schleife was garantiert, dass die Schleife mindestens einmal ausgeführt wird:

<?php
	$i = 0;
	
	do {
		echo $i."<br />";
		$i++;
	} while ($i < 10);
?>

2.7.4. Foreach-Schleifen

Die Foreach-Schleife ist eine Schleife zum durchlaufen von Arrays:

<?php
	$tage = array("Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag");
	
	foreach($tage as $tag)
	{
		echo $tag."<br />";
	}
?>

Das Beispiel zeigt den typischen Einsatz einer Foreach-Schleife: ein Array mit allen Wochentagen soll durchlaufen werden. Der Schleifenkopf nimmt das Array „$tage“ und holt sich das 1. Element und weist es der Variablen „$tag“ zu. Das tolle daran ist, dass wir innerhalb der Schleife mit den Werten des Arrays arbeiten können. In diesem Fall ist es eine einfache Variable, doch wenn es ein multidimensionales Array wäre, könnten wir auf alle Felder zugreifen ($tag[0][0], $tag[0][1], etc.). Und auch für assoziative Arrays ist die foreach-Schleife wie gemacht:

<?php
	//Jeder Spieler hat eine bestimmte Punktzahl
	
	$spieler["Maurice"] = 4233;
	$spieler["Anna"] = 3872;
	$spieler["Sarah"] = 1497;
	
	foreach($spieler as $index => $value)
	{
		echo $index." hat ".$value." erreicht <br />";
	}
?>

Die Variable „index“ greift dabei immer auf den Index-Namen des assoziativen Arrays zu, in diesem Fall also „Maurice“, „Anna“ und „Sarah“. Die Variable „value“ beinhaltet den Wert der Array-Variable, also „4233“, „3872“ und „1497“. Man muss nicht „index“ und „value“ verwenden, man kann auch aussagekräftigere Variablennamen verwenden:

<?php
	//Jeder Spieler hat eine bestimmte Punktzahl
	
	$spieler["Maurice"] = 4233;
	$spieler["Anna"] = 3872;
	$spieler["Sarah"] = 1497;
	
	foreach($spieler as $name => $punkte)
	{
		echo $name." hat ".$punkte." erreicht <br />";
	}
?>

Die foreach-Schleife funktioniert unabhängig von den Indizes. Also damit eine for-Schleife ein Array durchlaufen kann, müssen die Indizes lückenlos sortiert sein ($tage[0],
$tage[1], $tage[2], usw.), einer foreach-Schleife ist das egal, die durchläuft einfach alle Array-Elemente:

<?php
	$werte[rand(999, 9999)] = "Wert 1";
	$werte[rand(999, 9999)] = "Wert 2";
	$werte[rand(999, 9999)] = "Wert 3";
	
	foreach($werte as $index => $wert)
	{
		echo $wert." - Index: ".$index."<br />";
	}
?>

Wir erzeugen 3 Container im Array „$werte“ und die Indizes sind jeweils zufällig zwischen 999 und 9999. Dennoch durchläuft das Array problemlos alle 3 Container und gibt uns den Wert der jeweiligen Index-Zahl aus.


2.7.5. Schleifen Fazit

Jede Schleife in PHP hat ihre Vor-und Nachteile gegenüber einer anderen und es kommt immer auf das jeweilige Ziel des Algorithmus an, welche Schleife zu bevorzugen ist.

Beim durchlaufen von Arrays nutze ich so gut wie immer die foreach-Schleifen, für alles andere die for– und while-Schleifen (je nach Anforderung). Die Do-While-Schleife verwende ich so gut wie nie, auch wenn es hin und wieder mehr Sinn machen würde, eine Do-While-Schleife einer While-Schleife vorzuziehen.


2.8. Konstanten

Konstanten sind nahezu identisch mit Variablen, haben allerdings einen entscheidenden Unterschied: Ihr Wert kann sich nicht ändern, ihr Wert ist konstant. Hat man in seinem Skript einen Wert, der mehrmals benutzt wird, aber immer gleich bleibt, so sollte man eine Konstante statt einer Variablen bevorzugen (dazu gleich mehr).

Konstanten definieren und benutzen

<?php
	define("BREITE", "500");
	define("MEHRWERTSTEUER", "19");
	define("VERSION", "1.0.3");
?>

Wie du siehst, starten Konstanten nicht mit einem $-Zeichen, sondern müssen über die Funktion „define“ definiert werden. Ausserdem werden sie komplett großgeschrieben, dass hat auch den Vorteil, dass du Konstanten in deinem Skript schnell identifizieren kannst (die fallen auf).

Konstanten ausgeben

Möchte man nun seine definierten Konstanten im Skript verwenden muss man folgendermaßen vorgehen:

<?php
	echo BREITE; //Ausgabe: 500
	echo MEHRWERTSTEUER; //Ausgabe: 19
	echo VERSION; //Ausgabe: 1.0.3
?>

Wie du siehst, benötigen wir bei der Ausgabe ebenfalls kein $-Zeichen, dafür müssen allerdings alle Buchstaben großgeschrieben werden.

Der Sinn von Konstanten

Oben hast du schon die Konstante MEHRWERTSTEUER gesehen. Angenommen wir haben ein Skript, was an mehreren Stellen mit dem Wert der Mehrwertsteuer rechnet, so macht es Sinn diese als Konstante zu definieren. Stell dir vor dein Skript ist mehrere hundert Zeilen lang und plötzlich wird vom Staat der Betrag der Mehrwertsteuer von 19 auf 21% geändert. Ohne Konstante müsstest du nun dein Skript durchsuchen und jedesmal die 19 auf eine 21 ändern. Mit einer Konstante, die du am anfang deines Skripts angelegt hast, musst du nur an einer Stelle den Betrag ändern und dein Skript ist aktualisiert.

Regeln für Konstanten Namen

Die Regeln für den Namen einer Konstante sind identisch mit denen für Variablen: der Name startet mit einem Buchstaben oder Unterstrich und danach kann er eine beliebige Anzahl an Buchstaben, Zahlen oder Unterstrichen haben.


2.9. Include

Die Include-Anweisung von PHP ermöglicht es, PHP Skripte in anderen PHP-Dateien einzubinden und die Variablen, Funktionen und Anweisungen auszuführen. Dazu mal ein einfaches Beispiel:

index.php

<?php
	echo "Hallo Welt (index.php)";
?>

Dies ist unser Skript „index.php“, welches wir aufrufen. Doch bislang passiert darin noch nicht viel, lediglich „Hallo Welt (index.php)“ wird ausgegeben. Jetzt legen wir ein zweites Skript an:

frage.php

<?php
	echo "Wie geht es dir? (frage.php)";
?>

Jetzt wollen wir, dass die Ausgabe von „frage.php“ unterhalb der Ausgabe in der index.php erfolgt, dazu nehmen wir eine kleine Änderung an der index.php vor:

<?php
	echo "Hallo Welt (index.php)";
	include 'frage.php';
?>

Die Anweisung „include ‚frage.php‘;“ sagt PHP, „suche im gleichen Ordner, indem die Datei ‚index.php‘ liegt, nach der Datei ‚frage.php‘ und füge sie an dieser Stelle ein„.

Zugegeben, so ist das noch recht unspektakulär, aber bedenke, du kannst mit include jede PHP Datei in eine andere integrieren. Das wiederum heißt, wenn du dir eine PHP Webseite baust, brauchst du nicht eine riesige index.php zu haben, in der alles steht, sondern kannst deine Bereiche in einzelnen PHP-Dateien auslagern.

Variablen auslagern und mit include einbinden

Folgendes Beispiel soll den Include-Befehl noch etwas verständlicher machen:

index.php

<?php
	include 'variable.php';
	include 'berechnen.php';
	
	echo 'Die Variable "$zahl" hat den Wert :'.$zahl;
?>

Die index.php soll nur die beiden Dateien „variable.php“ und „berechnen.php“ einbinden und den Wert der Variable „$zahl“ ausgeben.

variable.php

<?php
	$zahl = 100;
?>

Hier wird unsere Variable erzeugt und ein Wert zugewiesen.

berechnen.php

<?php
	$zahl = $zahl - 50;
	$zahl = $zahl * rand(2,5);
?>

berechnen.php subtrahiert von der Variable Zahl den Wert 50 und multipliziert die Variable dann mit einem zufälligen Wert zwischen 2 und 5. Wenn man nun die index.php aufruft, sollte einer der Ausgaben erfolgen:

Die Variable "$zahl" hat den Wert :100
Die Variable "$zahl" hat den Wert :150
Die Variable "$zahl" hat den Wert :200
Die Variable "$zahl" hat den Wert :250

Natürlich kann man das auch alles in einer Datei machen, aber dieses Beispiel soll verdeutlichen, dass man Code in mehreren Dateien auslagern kann, um dadurch sein Projekt logisch zu strukturieren und übersichtlicher zu machen (stell dir eine index.php Datei mit 10.000 Code-Zeilen vor ;) ).

Pfad beachten

Immer wenn du eine Datei mit „include()“ in einer anderen Datei einbindest, musst du auf den korrekt Pfad achten (Datei 1 bindet Datei 2 ein):

<?php
    //Datei 1 liegt im gleichen Ordner wie Datei 2
	include 'datei2.php';
?>
<?php
    //Datei 1 liegt im root-Ordner und Datei 2 liegt dadrunter im Ordner "Dateien"
	include 'dateien/datei2.php';
?>
<?php
    //Datei 1 liegt einen Ordner unterhalb von Datei 2
	include '../datei2.php';
?>

2.10. Formulare erstellen und auswerten

Ein Formular besteht eigentlich nur aus HTML (eventuell noch Javascript) und hat somit erstmal nichts mit PHP zu tun. Wenn wir aber das Formular auswerten möchten, brauchen wir PHP.

Ein typisches Formular

<form action="formular_verarbeiten.php" method="get">
	<p>Gib deinen Namen ein: <input type="text" name="benutzername" /></p>
	<input type="submit" value="absenden" />
</form>

Hier siehst du ein typisches HTML-Formular. Unser Formular hat zwei Attribute:

  • action – das action-Attribut hat den Wert „formular_verarbeiten.php“. Nachdem der Besucher auf den Absenden Button des Formulars klickt, wird diese Datei aufgerufen und die Formular-Werte übermittelt.
  • method – Die Methode mit der die Variablen verschickt werden sollen. Es gibt die Wahl zwischen get und post. Wir benutzen hier erstmal die Methode GET

Der Rest ist Standard HTML: Ein Input-Feld mit dem Feldnamen „benutzername“ und einen Submit-Button, um das Formular abzuschicken.

Erstelle jetzt die Datei „index.html“ und füge obigen HTML Code ein. Wenn du die Datei jetzt aufrufst, solltest du folgende Ausgabe sehen:

Das ist unser HTML-Formular, und viel passiert noch nicht. Wenn du deinen Namen einträgst und auf absenden klickst, versucht der Browser die Datei aufzurufen, die im action-Attribut angegeben ist. Da die Datei noch nicht existiert, erscheint eine Fehlermeldung.

Formular Daten mit PHP verarbeiten

Um die Fehlermeldung zu beseitigen, erstellen wir jetzt die Datei „formular_verarbeiten.php“ im selben Ordner wie die „index.html“:

<?php
	echo 'Hallo ';
?>

Bislang alles wie gewohnt, aber nun wollen wir auf die Formular-Eingaben zugreifen. Die Formular-Werte werden in die PHP-Variablen „$_GET“ und „$_POST“ gespeichert, je nachdem, welche Methode wir oben im Formular angegeben haben. Da wir uns erstmal für „get“ entschieden haben, sind da auch unsere Werte drin. Da „$_GET“ ein Array ist, wollen wir uns das mal anschauen:

<?php
	echo 'Hallo ';
	
	echo '<pre>';
	print_r($_GET);
	echo '</pre>';
?>

Die Formular-Werte werden also als assoziatives Array in der $_GET-Variable abgelegt. Der Wert des „name“-Attributs ist der Index und der Wert ist die Eingabe, die der User ins Feld geschrieben hat. Das wollen wir nun direkt mal nutzen und passen die Datei „formular_verarbeiten.php“ an:

<?php
	echo 'Hallo '.$_GET['benutzername'];
?>

Ausgabe: Hallo Christian (bzw. welchen Namen du eingibst)

Ein weiteres Beispiel

Man kann alle Formular-Werte an PHP schicken, man muss den Eingabe-Feldern nur einen Namen geben:

index.html

<form name="eingabe" action="formular_verarbeiten.php" method="get">
	<p><strong>Wie geht es dir?</strong></p>
	<input type="radio" name="zustand" value="1" /> Super <br />
	<input type="radio" name="zustand" value="2" /> Gut <br />
	<input type="radio" name="zustand" value="3" /> Wie immer <br />
	<input type="radio" name="zustand" value="4" /> Geht so <br />
	<input type="radio" name="zustand" value="5" /> Schlecht <br />
	
	<br />
	<input type="submit" value="absenden" />
</form>

formular_verarbeiten.php

<?php
	switch($_GET['zustand']) {
		case 1:
			echo 'Geht mir genau so, ein super Tag!';
			break;
	
		case 2:
			echo 'Toll, das freut mich für dich :)';
			break;
			
		case 3:
			echo 'Besser als sich schlecht zu fühlen ;)';
			break;
			
		case 4:
			echo 'Kopf hoch, das wird schon wieder.';
			break;
			
		case 5:
			echo 'Denk dran, nach jedem Tief kommt ein Hoch.';
			break;
	
		default:
			echo 'Du hast vergessen deinen Zustand auszuwählen.';
	}
?>	

Der Besucher kann seinen Gemütszustand auswählen und wir geben ihm eine dazu passende Antwort. Wenn der Besucher vergisst etwas auszuwählen, nutzen wir die „default“-Aktion von Switch.


2.10.1. Unterschied zwischen GET und POST

Beim Formular-Attribut „method“ haben wir die Wahl zwischen „get“ und „post“, je nachdem welches wir wählen, müssen wir im PHP Script auf die Variable „$_GET“ oder „$_POST“ zugreifen. Doch was ist der Unterschied zwischen den beiden?

GET wird in der URL angezeigt

Wenn wir ein Formular mit „get“ verschicken, wird in der URL-Zeile des Browser die Variablen + ihrem Wert angezeigt:

Diesen Wert kann der Benutzer manipulieren, allerdings ist $_POST kein Schutz dagegen, aber es sieht in den meisten Fällen „schöner“ aus, da die URL-Zeile nicht mit Variablen vollgepumpt ist.

GET ist begrenzt, POST nicht

Gerade wenn man ein Formularfeld hat, indem sehr sehr viele Daten reinkommen können (z.b. ein Blog-Artikel, ein Forumbeitrag, ein Wikipedia-Artikel) muss man POST verwenden, da die get-Methode begrenzt ist. Bzw eigentlich ist nicht „get“ begrenzt, sondern die Url-Zeile des Browsers. Je nach Browser hat man eine maximale Länge um 1024 Zeichen und für Artikel ist das in der Regel nicht ausreichend (für Twitter-Nachrichten schon ;) )

Vor- und Nachteile von post und get

Hier nochmal die Vor- und Nachteile zusammengefasst:

  • Bei GET sieht der User, welche Daten übergeben werden (kann man als Vorteil oder als Nachteil sehen)
  • Bei GET ist die Länge begrenzt, bei POST nicht
  • Die Ergebnisseite eines GET-Formulars kann man bookmarken, da alle nötigen Informationen in der URL enthalten sind
  • Die Ergebnisseite eines POST-Formulars kann man weder bookmarken noch im Browser aktualisieren, da die Daten nicht mehr zur Verfügung stehen
  • File-Upload ist nur mit POST möglich

Quelle


2.11. Fehler finden und beheben für Anfänger

Als PHP Anfänger macht man in der Regel folgende Fehler am häufigsten:

  • Semikolon vergessen
  • normale/geschweifte Klammer nicht geschlossen
  • Array Größe überschritten (z.b. in einer Schleife)
  • Vergessen, dass das 1. Array-Element an der 0. Stelle beginnt
  • Dollar-Zeichen am Anfang einer Variable vergessen (statt „$zahl“ => „zahl“)
  • Logische Fehler (Endlosschleife, falsche Programmlogik, etc.)

Wie kann man solche Fehler vermeiden?

Leider ist hier fast der einzige Weg Praxis. Wer häufig den selben Fehler macht, wird über kurz oder lang diesen Fehler so gut wie nicht mehr machen. Neben Praxis hilft aber auch ein gut strukturierter Quellcode:

<?php
	//unübersichtlich
	if($zahl < 100) { $zahl++; $zahl += $zahl2 - 14; } else { $zahl = 0; }
?>
<?php
	//besser
	if($zahl < 100) 
	{ 
		$zahl++; 
		$zahl += $zahl2 - 14; 
	} 
	else 
	{ 
		$zahl = 0; 
	}
?>

Zusätzlich zu einem gut strukturierten Quellcode empfiehlt sich aufjedenfall der Einsatz eines Editors mit Syntaxhighlighting. Dieser macht den Quellcode nochmals leichter zu überblicken und man kann durch farbliche Hervorhebung schnell erkennen, wenn man vergessen hat eine Klammer oder einen String zu schließen.

Einfaches Debugging in PHP

Semikolon und vergessene Klammern lassen sich recht leicht finden, da PHP die Datei und die Zeilennummer angibt, in welcher der Fehler vorkommt. Doch manchmal läßt sich der Fehler trotz der Angabe nicht finden oder es handelt sich um einen logischen Fehler (dein Code arbeitet nicht so, wie du es gerne hättest).

Logische Fehler können z.b. Endlosschleifen sein, falsche/fehlende Array-Werte oder dein Quellcode spuckt einfach etwas aus, was du so nicht erwartet hast. Nun heißt es den Code Zeile für Zeile durchzugehen und an den jeweiligen Stellen die Variablen auszugeben (um zu schauen, welchen Wert sie haben). Ein Array kannst schön formatiert folgendermaßen ausgeben:

<?php
	echo '<pre>';
	print_r($array);
	echo '</pre>';
?>

Als letzter Tipp, bei Fehlermeldungen die du nicht direkt verstehst, empfiehlt sich nach dem Fehler zu googlen: Wenn PHP eine Fehlermeldung ausspuckt, einfach komplett kopieren (ohne Pfadangaben, Zeilenangaben, weil zu spezifisch) und in Google mit Anführungszeichen einfügen. Meist erhält man dadurch genügend Links, die das Problem schon behandelt haben und eine Lösung anbieten.


3. PHP Fortgeschritten


3.1. PHP Version herausfinden

Im Kapitel PHP Fortgeschritten gibt es einige Bereiche, die nur mit PHP 5 funktionieren. Daher solltest du dir, mit diesem kleinen Skript, deine PHP Version anzeigen lassen:

info.php

<?php
	phpinfo();
?>

Als Ergebnis solltest du folgendes erhalten:

Oben siehst du die PHP Version, in meinem Fall 5.2.6
Wenn du weiter runterscrollst, findest du noch etliche weitere Daten, welche Module für diese Version installiert sind, die Apache Konfigurations-Werte, etc.
Auch wenn du nur eine 4er PHP-Version hast, kannst du die wichtigsten Teile in diesem Kapitel angehen, nur beim Bereich „Klassen und Objekte“ könnte es Probleme geben, dazu aber im jeweiligen Kapitel nochmal ein extra Hinweis.


3.2. Funktionen

Funktionen sind dafür da, Programmlogik zu bündeln, die man immer wieder braucht. Dadurch vermeidet man Redundanz, somit auch Fehlerquellen und muss bei einer Änderung nur an einer Stelle eingreifen. Der Aufbau einer Funktion sieht so aus:

<?php
	function NAME_DER_FUNKTION (parameter1, parameter2, ...)
	{
		//auszuführender Code
	}
?>

Nun wollen wir mit einer Funktion zwei Zahlen addieren und die Rechnung + Ergebnis ausgeben:

<?php
	function addieren($zahl1, $zahl2)
	{
		echo $zahl1.' + '.$zahl2.' = '.($zahl1+$zahl2).'<br />';
	}
	
	addieren(5, 10);
?>

Unsere Funktion nennen wir sinngemäß „addieren“ und erwarten zwei Parameter, „$zahl1“ und „$zahl2“. Parameter sind Möglichkeiten, Werte an unsere Funktion zu übergeben. Man kann auch Funktionen programmieren, die keinen Parameter erwarten (leere Klammer), aber da wir hier zwei Zahlen addieren wollen, brauchen wir zwei Parameter.

Der Code innerhalb der Funktion sollte selbsterklärend sein.
Nun können wir beliebige Zahlen miteinander addieren und zudem so häufig wir wollen:

<?php
	function addieren($zahl1, $zahl2)
	{
		echo $zahl1.' + '.$zahl2.' = '.($zahl1+$zahl2).'<br />';
	}
	
	addieren(5, 10);
	echo '<br />';
	addieren(2732, 19883);
	echo '<br />';
	addieren(1, 1);
	echo '<br />';
	
	for($i=1; $i < 30; $i++) 
	{
		addieren($i, $i*10);
		echo '<br />';
	}	
?>

Ergebnis:

Wert mit return zurückgeben

Häufig möchte man, dass die Funktion einen Wert zurückgibt, also zuerst wird etwas berechnet und abhängig vom Ergebnis dieser Berechnung, gibt die Funktion einen Wert zurück. Im folgenden Beispiel möchten wir, dass unsere Funktion uns nur das Ergebnis der Addition zurückgibt:

<?php
	function addieren($zahl1, $zahl2)
	{
		$ergebnis = $zahl1 + $zahl2;
		
		return $ergebnis;
	}
	
	for($i=1; $i < 10; $i++) 
	{
		echo $i.' + '.$i.' = '.addieren($i, $i);
	}	
?>

Optionale Parameter

Manchmal möchte man eine Funktion haben, die einen optionalen Parameter beinhaltet:

<?php
	function addieren($zahl1, $zahl2=5)
	{
		echo $ergebnis = $zahl1 + $zahl2;
	}
	
	addieren(10,12);
	echo '<br />';
	addieren(10);
?>

Wenn beide Werte angegeben sind, läuft alles wie gewohnt. Wird aber nur ein Parameter befüllt, erhält der zweite Parameter automatisch den Wert „5“.

Funktionen sind ein mächtiges Werkzeug und ohne kommt man als PHP Programmierer einfach nicht aus. Da aber bestimmte Funktionen von so gut wie allen PHP Entwicklern benötigt werden, werden diese von PHP direkt zur Verfügung gestellt. Schau dir dazu den Unterartikel PHP Standard Funktionen an.


3.2.1. Referenz Parameter

Normalerweise übergibt man einer Funktion ein paar Variablen, mit dieser arbeitet die Funktion dann und gibt ein Ergebnis zurück, womit das PHP Skript weiterarbeiten kann. Bei der Übergabe werden Kopien der Variable angelegt und mit diesen Kopien gearbeitet, sprich die Ursprungs-Variable wird nicht verändert:

<?php
	function verkleinern($zahl)
	{
		$zahl = $zahl - 10;
	}
	
	$zahl = 20;
	verkleinern($zahl);
	
	echo $zahl;
?>

Als Ergebnis erhält man den Wert „20“, denn auch wenn wir innerhalb der Funktion den Wert der Variablen „$zahl“ um 10 reduzieren, handelt es sich dabei nur um die Kopie der Variablen.

Möchte man nun aber, dass die Original-Variable verändert wird, also keine Kopie der Variable angelegt wird, muss man mit Referenz Parametern arbeiten. Hört sich schlimmer an als es ist, denn im Grunde setzt man lediglich ein kaufmännisches Und (&) vor die Variable und macht sie dadurch zu einer Referenz:

<?php
	function verkleinern(&$zahl)
	{
		$zahl = $zahl - 10;
	}
	
	$zahl = 20;
	verkleinern($zahl);
	
	echo $zahl;
?>

Nun erhalten wir als Ergebnis tatsächlich den Wert „10“ denn es wird keine Kopie der Variable angelegt, sondern die Variable direkt manipuliert.


3.2.2. PHP Funktionen und Dokumentation

PHP kommt mit einer Fülle an nützlichen Funktionen, die man ständig benötigt und warum sollte man das Rad neuerfinden? Eine Übersicht über die Standard PHP Funktionen findest du hier: PHP Funktionsreferenz

Da das für Anfänger recht unübersichtlich ist, hier die Referenzen, welche von Anfängern am häufigsten benötigt werden:

PHP bietet dir also schon viele Funktionen an, doch wie verwendest du die jetzt? Und wie findest du die richtige für dein Problem?

PHP Dokumentation verstehen

In Foren werden Anfänger bei Fragen und Problemen häufig auf die PHP Dokumentation verwiesen. An sich ist das auch absolut legitim, denn die Dokumentation ist vollständig, aktuell und bietet zudem sehr viele Beispiele zu den einzelnen Funktionen. Das Problem ist allerdings, die meisten Anfänger wissen einfach nicht wie die Dokumentation zu lesen ist und wie sie ans Ziel kommen. Daher hier mal eine kleine Annäherung:

1. Funktionen finden
Auf was bezieht sich dein Problem, auf Arrays, auf Strings, auf Mathematik? Identifziere als erstes den Bereich und suche dann in der Funktionsreferenz nach diesem Bereich (tricky: „Strings“ sind hier unter „Zeichenketten“ zu finden).

2. Funktionsbeschreibung lesen und verstehen
Wenn man nun seine Funktion gefunden hat (oder glaubt sie gefunden zu haben), steht in der Beschreibung wie man diese Funktion anwenden muss. Als erstes mal ein einfaches Beispiel, strlen gibt die Länge einer Zeichenkette zurück:

Erklärung:
Das „int“ vor „strlen“ besagt, dass die Funktion einen Integer-Wert zurückgibt, in diesem Fall die Länge des Strings. Die Funktion erwartet einen Parameter, dieser ist vom Typ „string“.

Nun ein etwas komplexeres Beispiel, dafür nehmen wir die Funktion str_replace welches einen Teil eines Strings durch einen anderen ersetzt:

Das „mixed“ steht für Arrays und Variablen und „mixed str_replace“ bedeutet, dass die Funktion eine Variable oder ein Array zurückgibt, jenachdem mit welchen Werten man die Funktion aufruft. Nun folgen die Parameter: „mixed $search“ ist ein Pflichtparameter, also da muss entweder eine Variable oder ein Array rein. Gleiches gilt für „mixed $replace“ und „mixed $subject„, hingegen ist der vierte Parameter int &$count optional (eckige Klammern). Die PHP Dokumentation ist wirklich gut, so findet man unterhalb der Beschreibung eine Parameter-Liste, die erklärt was die Parameter machen und welche Auswirkungen sie haben.

Wer aber nicht so gerne mit der Beschreibung arbeitet, kann sich stattdessen unten auch die Beispiele anschauen. Diese sind wirklich sehr gut gewählt und zeigen die Variationsmöglichkeiten der Funktionen und ihre Ausgaben.


3.3. Klassen und Objekte (Einführung)

Funktionen waren der erste Schritt, komplexe PHP Skripte übersichtlicher zu machen und Code wiederzufinden. Der nächste Schritt sind Klassen und Objekte. PHP wurde lange Zeit von Programmierern mit einem lächeln abgetan, doch spätestens seit dem Einzug von OOP (Objekt-orientierte Programmierung sprich: Klassen und Objekte) wird PHP weitgehend ernst genommen.

Was sind Klassen und Objekte

Klassen kann man grob als „Bauplan“ ansehen, mit dem Bauplan selbst kann man nichts machen, aber man kann den Bauplan nutzen, um etwas herzustellen. Also unsere Klassen können wir direkt nicht benutzen, aber aus den Klassen können wir Objekte erzeugen. Stell dir vor du hast eine Klasse „Auto“ (einen Bauplan für ein Auto). Nun kannst du mit der Klasse ein Objekt erzeugen, in diesem Fall ein Auto. Also könntest du z.b. sagen: Klasse „Auto“, gib mir einen „Opel Insignia“.

Von einer Klasse kannst du beliebig viele Objekte erzeugen, also kannst du dir von der Klasse „Auto“ einen ganzen Fahrzeughof erschaffen ;)

Bevor wir jetzt von dieser abstrakten Erklärung zum konkreten Beispiel springen noch einen Hinweis: Häufig liest man von Objekten und Instanzen und fragt sich nach dem Unterschied. Objekte und Instanzen sind das gleiche, denn: Ein Objekt ist die Instanz einer Klasse. Also nicht verwirren lassen, es gibt Klassen und Objekte/Instanzen.

Zusammenfassung von Klassen und Objekten

  • Wir brauchen Klassen (Baupläne) um Objekte (Gegenstände) zu erzeugen
  • Mit Klassen selbst können wir nichts machen, nur mit Objekten
  • Von einer Klasse können wir beliebig viele Objekte erstellen
  • Objekte werden auch als Instanzen bezeichnet

Im Teil Klasse erstellen in PHP erzeugen wir unsere erste PHP Klasse und damit wird die ganze Erklärung etwas verständlicher. Davor folgt aber noch der Teil OOP/Klassen Begriffe dies ist eine Referenz der wichtigsten Begriffe von Klassen, du kannst ihn dir jetzt anschauen oder später wenn du mehr über Klassen erfahren hast.


3.3.1. OOP/Klassen Begriffe

Zum besseren Verständnis der folgenden Teile habe ich hier mal die wichtigsten Begriffe aufgelistet und jeweils eine kurze Erklärung. Keine Sorge wenn du mit den Begriffen derzeit noch nichts anfangen kannst, die werden sich mit der Zeit von selbst erklären:

  • Klasse: eine Klasse kann man sich als Bauplan vorstellen. Stell dir einfach den Bauplan für ein Haus vor, mit dem Plan selbst hast du noch kein Haus, aber du weißt wie du daraus eins bauen kannst
  • Objekt: in unserem Beispiel ist das Objekt nun das fertiggebaute Haus. Natürlich kann man mit einem Bauplan mehrere Häuser bauen, gleiches gilt für Objekte. Von einer Klasse kann man mehrere Objekte erzeugen
  • Instanz: Instanz ist nur ein anderes Wort für Objekt
  • instanziieren: das Erzeugen einer Instanz/Objekt von einer Klasse. In unserem Beispiel bedeutet instanziieren das Haus zu bauen (im Vergleich zum Bau eines Hauses brauchen Objekte aber nur Millisekunden um gebaut zu werden)
  • Eigenschaften: Eigenschaften sind nichts anderes als Variablen. Lass dich nicht von den unterschiedlichen Begriffen verwirren, Eigenschaften = Variablen
  • Methoden: Methoden sind nichts anderes als Funktionen.
  • OOP/objekt-orientierte Programmierung – ist nichts anderes als das programmieren und die Verwendung von Objekten. Alles was du in den folgenden Teilen lernst, ist Teil der OOP.

3.3.2. Klasse erstellen in PHP

Hinweis: Für die folgenden Kapitel wird PHP 5 vorausgesetzt. Hast du nur PHP 4 und möchtest dich trotzdem mit Klassen und Objekten beschäftigen, schau dir die Unterschiede auf folgender Seite an: PHP bar Klasse

Bevor es losgeht noch was wichtiges: Laß dich von der Thematik Klassen, Objekte und objekt-orientierte Programmierung (OOP) nicht einschüchtern. Die ganze Thematik ist im Grunde recht leicht, vorallem wenn du die vorigen Teile durchgearbeitet hast. In der OOP werden die Grundkonzepte einfach recyclet und ein paar neue Dinge kommen hinzu. 80% der geschriebenen Klassen (diese Zahl ist völlig aus der Luft gegriffen) benutzen nur 20% der Möglichkeiten, die die OOP anbietet (diese Zahl ist ebenfalls völlig aus der Luft gegriffen). Worauf ich hinaus will ist: die Grundkonzepte von Klassen sind leicht zu lernen und mehr wirst du anfangs für deine Klassen ebenfalls nicht brauchen. Dennoch, wenn ich etwas unklar oder falsch erklärt habe, sag mir bescheid :)

Der Aufbau einer Klasse

<?php

class MeineKlasse
{
    // hier kommt rein, welche Eigenschaften (Variablen) das Objekt hat und welche Methoden (Funktionen)
}

?>

Dies ist eine ganz simple Klasse. Das Schlüsselwort „class“ sagt PHP, dass nun eine Klasse beginnt, danach folgt der Name der Klasse in meinem Fall „MeineKlasse„. In der Klasse selbst passiert derzeit allerdings noch nichts. Welche Regeln es für den Namen der Klasse gibt könnt ihr hier nachschauen: Klassenname – was gibt es zu beachten

Und genau damit beenden wir diesen Teil des Tutorials und gehen weiter zum nächsten: Eigenschaften – Variablen einer Klasse


3.3.2.1. Klassenname – was gibt es zu beachten

Ein Klassenname in PHP kann eigentlich alles sein, es gibt nur ein paar Regeln zu beachten:

  • als Klassename darf kein von PHP reserviertes Wort verwendet werden
  • ein gültiger Klassenname beginnt mit einem Buchstaben oder einem Unterstrich, gefolgt von einer beliebigen Anzahl von Buchstaben, Ziffern oder Unterstrichen

erlaubte Klassennamen

(unabhängig davon ob die Namen Sinn machen oder nicht

  • meineKlasse
  • Klasse
  • _Klasse
  • _
  • dies_ist_meine_klasse
  • Klasse_123
  • _class

Klassennamen die nicht funktionieren

  • class
  • 123
  • Klasse_A/B_testing
  • meine-tolle-klasse
  • exception
  • default

3.3.3. Eigenschaften – Variablen einer Klasse

Eine Eigenschaft einer Klasse ist im Grunde nichts anderes als eine Variable. Diese Variable wird innerhalb einer Klasse deklariert:

<?php

class MeineKlasse
{
	public $gib_laut = 'Hallo Welt';
}

?>

public $gib_laut = ‚Hallo Welt‘;
Ignoriere erstmal das Schlüsselwort „public“ => $gib_laut = ‚Hallo Welt‘;
Wie du siehst handelt es sich hierbei lediglich um eine Variable die einen Wert erhält (Hallo Welt). Der einzige Unterschied ist das Schlüsselwort „public“.

Was aber bedeutet nun „public“?
Eine Eigenschaft/Variable innerhalb einer Klasse muss immer eines der folgenden Schlüsselwörter enthalten: public, protected oder private. Derzeit brauchst du noch nicht zu wissen was die Schlüsselwörter bedeuten, setze einfach vor jeder Eigenschaft die du innerhalb deiner Klasse deklarierst das Schlüsselwort public. Keine Sorge, ich werde darauf später genauestens eingehen.

Jetzt haben wir eine Klasse mit einer Eigenschaft $gib_laut und einem Wert „Hallo Welt“. Damit können wir aber noch nichts machen. Der Versuch den Wert der Eigenschaft „gib_laut“ auszugeben wird von PHP mit folgender Fehlermeldung quittiert:

Notice: Undefined variable: gib_laut

Die Erklärung ist einfach: ausserhalb der Klasse ist die Eigenschaft „gib_laut“ nicht bekannt. Um die Eigenschaft auszugeben müssen wir erst ein Objekt der Klasse erstellen (klick auf den Link für den nächsten Teil).


3.3.4. Objekt erzeugen / Klasse instanziieren

Im vorigen Teil haben wir unserer Klasse eine Eigenschaft mitgegeben. Nun wollen wir ein Objekt dieser Klasse erzeugen:

<?php

class MeineKlasse
{
	public $gib_laut = 'Hallo Welt';
}

$meinObjekt = new MeineKlasse();

?>

Nach der Klassendefinition erstellen wir nun ein Objekt von der Klasse oder anders ausgedrückt wir erstellen eine Instanz der Klasse (meint aber beides das gleiche). Dafür müssen wir den Namen des Objekts deklarieren „$meinObjekt“ und eine Instanz der Klasse erzeugen „new MeineKlasse();

Das ist ja bisher alles recht langweilig, deshalb soll unser Objekt jetzt mal was sagen, dafür geben wir einfach den Wert der Eigenschaft „gib_laut“ aus:

<?php

class MeineKlasse
{
	public $gib_laut = 'Hallo Welt';
}

$meinObjekt = new MeineKlasse();

echo $meinObjekt->gib_laut;

?>

Wenn du obigen Quellcode nun mal ausführst, sollte dir folgendes ausgegeben werden:

Hallo Welt

Was du gemacht hast ist folgendes:

1. du hast eine Klasse erstellt:

class MeineKlasse
{
}

2. dieser Klasse hast du eine Eigenschaft/Variable mit dem Wert „Hallo Welt“ gegeben

public $gib_laut = 'Hallo Welt';

3. dann hast du ein Objekt der Klasse erzeugt:

$meinObjekt = new MeineKlasse();

4. und als letztes hast du die Eigenschaft „gib_laut“ des Objekts „meinObjekt“ ausgegeben:

echo $meinObjekt->gib_laut;

Zu Punkt 4 musst du folgendes wissen: du kannst nicht direkt eine Eigenschaft einer Klasse ausgeben (wie wir im Teil Eigenschaften – Variablen einer Klasse gesehen haben), dazu musst du immer erst ein Objekt der Klasse erzeugen und mit dem Objekt kannst du nun auf die Eigenschaft zugreifen und diese ausgeben (oder bearbeiten, sprich den Wert verändern):

<?php

class MeineKlasse
{
	public $gib_laut = 'Hallo Welt';
}

$meinObjekt = new MeineKlasse();

$meinObjekt->gib_laut = "Wuff!";
echo $meinObjekt->gib_laut;

?>

Ausgabe:

Wuff!

Super, das wäre erstmal geschafft. Die Grundlagen der OOP hast du nun gelernt. Derzeit fragst du dich vielleicht noch, wofür das ganze nun gut sein soll, zurecht. Das wird sich hoffentlich in den folgenden Teilen klären. Bevor es nun weitergeht, schau dir nochmal folgenden Artikel an: OO/Klassen Begriffe. Danach gehts weiter und wir werden Raumschiffe bauen… richtig gelesen, RAUMSCHIFFE WOOOOT!!


3.3.5. Klasse: Raumschiff_fabrik

Sooooooo, jetzt weißt du schonmal wie man eine Klasse baut und von dieser Klasse ein Objekt erzeugt. Um die nächsten Beispiele anschaulicher zu machen, begeben wir uns nun in die Weiten des Weltraums und bauen Raumschiffe in unserer Raumschiff_fabrik (yupp, die nächsten Teile werden eine Spur geeky :D )

<?php

class Raumschiff_fabrik
{
	//Eigenschaften und Methoden
}

$raumschiff1 = new Raumschiff_fabrik();

?>

Erklärung: Mit unserer Raumschifffabrik (Klasse: Raumschiff_fabrik) können wir nun Raumschiffe (Objekte) erzeugen. Doch unsere erzeugten Raumschiffe haben derzeit noch keine Eigenschaften oder Methoden und können daher nichts machen.

Was für Eigenschaften können wir unseren Raumschiffen mitgeben?

  • Geschwindigkeit: Ein Raumschiff hat einen Antrieb, umso besser der Antrieb, desto schneller das Raumschiff
  • Schild: im Weltraum gibt es Meteoriten und feindliche Laserstrahlen. Ein Schildgenerator hilft unserem Raumschiff am leben zu bleiben
  • Name: Ein Raumschiff braucht einen Namen.

Das reicht fürs erste. Jetzt müssen wir diese Eigenschaften noch unserer Raumschifffabrik mitteilen damit unsere nächsten Raumschiffe auch damit ausgestattet werden.

<?php

class Raumschiff_fabrik
{
	public $geschwindigkeit = 5;
	public $schild = 1;
	public $name;
}

?>

Unsere Raumschifffabrik ist nun ausgestattet um die ersten Schiffe unserer Flotte zu bauen. Für den anfang wollen wir 2 Schiffe haben:

<?php

class Raumschiff_fabrik
{
	public $geschwindigkeit = 5;
	public $schild = 1;
	public $name;
}

$schiff_1 = new Raumschiff_fabrik();
$schiff_2 = new Raumschiff_fabrik();

print_r($schiff_1);
print_r($schiff_2);

?>

Ausgabe

Raumschiff_fabrik Object ( [geschwindigkeit] => 5 [schild] => 1 [name] => ) 
Raumschiff_fabrik Object ( [geschwindigkeit] => 5 [schild] => 1 [name] => )

Wie du sehen kannst, können wir mit unserer Raumschifffabrik mehrere Schiffe erstellen. Wir sehen das beide Schiffe die gleichen Eigenschaften und Werte haben und die Eigenschaft „Name“ bislang noch keinen Wert hat (weshalb es für uns auch derzeit schwierig ist die beiden Objekte/Raumschiffe voneinander zu unterschieden). Das wird sich aber in Kürze ändern.

Im nächsten Teil gehe ich auf die Methoden/Funktionen einer Klasse ein.


3.3.6. Methoden – Funktionen einer Klasse

Bislang hast du gelernt eine Klasse mit Eigenschaften zu erstellen. Als nächstes behandeln wir Methoden. Methoden sind Funktionen, die innerhalb einer Klasse verwendet werden (sprich: von aussen kann man nicht darauf zugreifen, nur über ein Objekt können diese Funktionen aufgerufen werden).

Die Klasse „Raumschiff_fabrik“ erweitern

Wir werden nun unsere Klasse „Raumschiff_fabrik“ aus dem vorigen Teil erweitern mit einer Methode um unseren Raumschiff-Objekten eindeutige Namen zu vergeben:

<?php

class Raumschiff_fabrik
{
	public $geschwindigkeit = 5;
	public $schild = 1;
	public $name;
	
	public function setName($neuer_name) {
		$this->name = $neuer_name;
	}
}
?>

Als erstes siehst du eine ganz normale Funktion mit dem Schlüsselwort „public“:

public function setName($neuer_name)

Hier sollte nichts neues für dich dabei sein, falls du nicht weißt was dieser Code macht, schau dir nochmal das Kapitel über PHP Funktionen an. Das Schlüsselwort public wird wie bei den Eigenschaften einer Klasse immer vor die Methode gesetzt. Wir gehen darauf später noch genauer ein.

Der nächste Teil sollte aber neu für dich sein:

$this->name = $neuer_name;

Hier wird der Eigenschaft „name“ der Wert der Variablen „$neuer_name“ übergeben. Was aber bedeutet „$this“?

$this – Erklärung

Wenn wir innerhalb einer Klasse einer Eigenschaft einen Wert übergeben wollen, können wir dafür nicht einfach den Namen der Eigenschaft nehmen, folgendes funktioniert also nicht:

public function setName($neuer_name) {
	$name = $neuer_name; //dies funktioniert nicht!
}

Wir können nur die Eigenschaften eines Objekts verändern da eine Klasse selbst keine Eigenschaften hat, sondern sie nur an die Objekte weitergibt. Mittels $this sagen wir daher: „Ändere die Eigenschaft des gerade aktiven Objekts“. Dazu ein Beispiel:

<?php

class Raumschiff_fabrik
{
	public $geschwindigkeit = 5;
	public $schild = 1;
	public $name;
	
	public function setName($neuer_name) {
		$this->name = $neuer_name;
	}
}

$schiff_1 = new Raumschiff_fabrik();
$schiff_2 = new Raumschiff_fabrik();

$schiff_1->setName('Anubis'); //dieses Objekt ist gerade aktiv und nur seine Eigenschaft "name" wird verändert

?>

Daher: immer wenn du in der Methode einer Klasse den Wert einer Eigenschaft verändern möchtest, musst du dies mittels $this machen. (Wenn dir diese Erklärung zum Verständnis nicht ausreicht, bitte hinterlasse einen Kommentar damit ich es vereinfachen kann).

Als nächstes erzeugen wir zwei neue Raumschiffe (Objekte) und geben jeden von ihnen einen eindeutigen Namen:

<?php

class Raumschiff_fabrik
{
	public $geschwindigkeit = 5;
	public $schild = 1;
	public $name;
	
	public function setName($neuer_name) {
		$this->name = $neuer_name;
	}
}

$schiff_1 = new Raumschiff_fabrik();
$schiff_2 = new Raumschiff_fabrik();

print_r($schiff_1);
print_r($schiff_2);

$schiff_1->setName('Anubis');
$schiff_2->setName('Cherti');

print_r($schiff_1);
print_r($schiff_2);

?>

Als Ausgabe erhalten wir:

Raumschiff_fabrik Object ( [geschwindigkeit] => 5 [schild] => 1 [name] => ) 
Raumschiff_fabrik Object ( [geschwindigkeit] => 5 [schild] => 1 [name] => )

Raumschiff_fabrik Object ( [geschwindigkeit] => 5 [schild] => 1 [name] => Anubis ) 
Raumschiff_fabrik Object ( [geschwindigkeit] => 5 [schild] => 1 [name] => Cherti )

Houston, we have a problem!

So, unsere Raumschifffabrik spuckt nun beliebig viele Schiffe aus, die Schiffe können sich mit ihrem Antrieb bewegen und kleinere Asteroiden verpuffen an unserem Schutzschild. Doch was ist mit größeren Asteroiden? Diese durchdringen unseren Schild und beschädigen das Schiff, deshalb brauchen wir jetzt noch:

  • eine Eigenschaft „leben“ (steht für die Hülle des Schiffs, wenn Leben den Wert „0“ erreicht, gilt die Hülle als durchschlagen und unser armes Raumschiff explodiert) und
  • eine Methode „treffer“ (berechnet den Schaden der durch den Asteroiden entstanden ist, reduziert die Eigenschaft „leben“ entsprechend und prüft ob das Raumschiff zerstört wurde
<?php

class Raumschiff_fabrik
{
	public $geschwindigkeit = 5;
	public $schild = 3;
	public $leben = 10;
	
	public $name;
	
	public function setName($neuer_name) {
		$this->name = $neuer_name;
	}
	
	public function treffer($schaden) {
		//prüfe ob der Asteroid unser Schutzschild durchschlagen hat 
		if($this->schild < $schaden)
		{
			//berechne wieviel Schaden trotz des Schilds entsteht
			$rest_schaden = $schaden - $this->schild;
			$this->leben -= $rest_schaden;
			
			if($this->leben <= 0)
			{
				echo 'Raumschiff "'.$this->name.'" wurde zerstört';
			}
		}
	}
}

?>

Erklärung:

  • Eigenschaft „leben“: Unsere Raumschiffe starten mit einer Hülle der Stärke 10
  • public function treffer($schaden): In dieser Funktion passieren mehrere Dinge:
    • als erstes wird geprüft, ob der Asteroid überhaupt den Schild durchschlägt: if($this->schild < $schaden)
    • Danach berechnen wir wieviel Schaden der Asteroid am Raumschiff verursacht. Als Beispiel: der Asteroid hat die Stärke 5, davon ziehen wir unser Schutzschild ab (3) und erhalten einen erzeugten Schaden von 2
    • der erzeugte Schaden ($rest_schaden) wird von unserem Leben abgezogen
    • Als letztes prüfen wir ob unser Raumschiff die Kollision überstanden hat. Wenn nein explodiert es und wir erhalten die Meldung das unser Raumschiff zerstört wurde :(

Die Theorie ist ja ganz interessant, aber nun wollen wir doch mal unsere Raumschifffabrik in einem kleinen Pseudo-Spiel testen: Lazy Space Wars I

Wenn du direkt mit der Theorie weitermachen möchtest, folge diesem Link: Constructor – Objekt erzeugen und Variablen initialisieren


3.3.6.1. Lazy Space Wars I

In diesem Teil werden wir erstmal nichts neues lernen, sondern mit unserer Klasse „Raumschiff_fabrik“ und unseren Objekten rumspielen. Dazu erstellen wir ein kleines Pseudo-Spiel:

Unsere Raumschiffabrik produziert am Anfang des Spiels zwei Raumschiffe. Diese fliegen 10 Runden (Schleifendurchläufe) durch den Raum und haben in jeder Runde eine 33% Wahrscheinlichkeit von einem zufällig großen Asteroiden getroffen zu werden (Größe der Asteroiden = zufällig, zwischen 1-10). In jeder Runde wird geprüft ob eines der beiden Raumschiffe getroffen wurde, welches Raumschiff getroffen wurde (name), die Größe des Asteroiden und wieviel Leben noch für das jeweilige Raumschiff übrig ist.

Am Ende der 10 Runden wird dann geprüft ob die beiden Raumschiffe noch funktionstüchtig sind und mit wieviel Leben sie davongekommen sind.

Lazy Space Wars I – Code

(den folgenden Quellcode kannst du so komplett in eine PHP-Datei packen und ausführen):

<?php

class Raumschiff_fabrik
{
	public $geschwindigkeit = 5;
	public $schild = 3;
	public $leben = 10;
	
	public $name;
	
	public function setName($neuer_name) {
		$this->name = $neuer_name;
	}
	
	public function treffer($schaden) {
		//prüfe ob der Asteroid unser Schutzschild durchschlagen hat 
		if($this->schild < $schaden)
		{
			//berechen wieviel Schaden trotz des Schilds entsteht
			$rest_schaden = $schaden - $this->schild;
			$this->leben -= $rest_schaden;
				
			if($this->leben <= 0)
			{
				$this->leben = 0;
			}
		}
	}
	
	public function status() {
		if($this->leben > 0)
		{
			return 'Leben: '.$this->leben;
		} else {
			return 'zerstoert';
		}
	}
}

$schiff1 = new Raumschiff_fabrik();
$schiff2 = new Raumschiff_fabrik();
$schiff1->setName('Anubis');
$schiff2->setName('Cherti');

$runde = 1;

// unser Pseudo-Spiel soll 10 Runden dauern
while($runde <= 10)
{
	echo '<strong>Runde'.$runde.'</strong><br />';
	
	// erzeuge einen zufälligen Asteroiden
	$asteroid = rand(1, 10);
	
	// Schiff1: prüfe Kollision (Wahrscheinlichkeit 33%), ziehe Leben ab
	if($schiff1->leben > 0) 
	{
		if(rand(1,3) == 1) {
			$schiff1->treffer($asteroid);
			echo $schiff1->name.' wurde getroffen. Asteroid: '.$asteroid.' - Leben: '.$schiff1->leben.'<br />';
		}
	}
	
	// Schiff2: prüfe Kollision (Wahrscheinlichkeit 33%), ziehe Leben ab
	if($schiff2->leben > 0)
	{
		if(rand(1,3) == 1) {
			$schiff2->treffer($asteroid);
			echo $schiff2->name.' wurde getroffen. Asteroid: '.$asteroid.' - Leben: '.$schiff2->leben.'<br />';
		}
	}
	
	echo '<br />';		
			
	// nächste Runde		
	$runde++;
}

echo '<hr />';

//Gib nach den 10 Runden den Status beider Schiffe aus
echo 'Raumschiff "'.$schiff1->name.'" - '.$schiff1->status()."<br />";
echo 'Raumschiff "'.$schiff2->name.'" - '.$schiff2->status();

?>

Erklärung:
In der Klasse „Raumschiff_fabrik“ ist eine weitere Methode hinzugekommen:

public function status() {
	if($this->leben > 0)
	{
		return 'Leben: '.$this->leben;
	} else {
		return 'zerstoert';
	}
}

Diese Methode ist einfach nur dafür da am Ende der 10 Runden den Status der Schiffe abzurufen.

Nach der Deklaration der Klasse „Raumschiff_fabrik“ erstellen wir mithilfe der Klasse zwei Raumschiffe und geben jedem Schiff einen eigenen Namen:

$schiff1 = new Raumschiff_fabrik();
$schiff2 = new Raumschiff_fabrik();
$schiff1->setName('Anubis');
$schiff2->setName('Cherti');

Nun folgt das eigentliche Spiel.

Lazy Space Wars I – Gameloop (Spielschleife)

$runde = 1;

// unser Pseudo-Spiel soll 10 Runden dauern
while($runde <= 10)
{
	echo '<strong>Runde'.$runde.'</strong><br />';
	
	// erzeuge einen zufälligen Asteroiden
	$asteroid = rand(1, 10);
	
	// Schiff1: prüfe Kollision (Wahrscheinlichkeit 33%), ziehe Leben ab
	if($schiff1->leben > 0) 
	{
		if(rand(1,3) == 1) {
			$schiff1->treffer($asteroid);
			echo $schiff1->name.' wurde getroffen. Asteroid: '.$asteroid.' - Leben: '.$schiff1->leben.'<br />';
		}
	}
	
	// Schiff2: prüfe Kollision (Wahrscheinlichkeit 33%), ziehe Leben ab
	if($schiff2->leben > 0)
	{
		if(rand(1,3) == 1) {
			$schiff2->treffer($asteroid);
			echo $schiff2->name.' wurde getroffen. Asteroid: '.$asteroid.' - Leben: '.$schiff2->leben.'<br />';
		}
	}
	
	echo '<br />';		
			
	// nächste Runde		
	$runde++;
}

echo '<hr />';

//Gib nach den 10 Runden den Status beider Schiffe aus
echo 'Raumschiff "'.$schiff1->name.'" - '.$schiff1->status()."<br />";
echo 'Raumschiff "'.$schiff2->name.'" - '.$schiff2->status();

Erklärung:
Die while-Schleife soll 10x mal laufen, am Ende der Schleife wird der Zähler „$runde“ +1 hochgesetzt. Am Anfang jeder Runde wird ein neuer Asteroid erzeugt:

	$asteroid = rand(1, 10);

Die Stärke des Asteroiden ist zufällig, ein Wert zwischen 1-3 wird dem Schiff keinen Schaden zufügen (der Asteroid muss stärker als das Schutzschild sein um dem Schiff Schaden zuzufügen).

Als nächstes wird geprüft ob der Asteroid das Schiff trifft:

// Schiff1: prüfe Kollision (Wahrscheinlichkeit 33%), ziehe Leben ab
if($schiff1->leben > 0) 
{
	if(rand(1,3) == 1) {
		$schiff1->treffer($asteroid);
		echo $schiff1->name.' wurde getroffen. Asteroid: '.$asteroid.' - Leben: '.$schiff1->leben.'<br />';
	}
}

Es besteht eine 33% Wahrscheinlichkeit, dass der Asteroid trifft

rand(1,3) == 1

In diesem Fall wird die Stärke des Asteroiden an unsere Methode „treffer“ weitergegeben. Der Restschaden des Asteroiden wird vom Leben des Schiffs abgezogen. Ein Asteroid der Größe 5 verursacht 2 Schaden (Schutzschild hat die Stärke 3). Wenn das Schiff getroffen wurde wird eine Benachrichtigung ausgegeben.

Am Ende der Spielschleife wird das Ergebnis ausgegeben:

//Gib nach den 10 Runden den Status beider Schiffe aus
echo 'Raumschiff "'.$schiff1->name.'" - '.$schiff1->status()."<br />";
echo 'Raumschiff "'.$schiff2->name.'" - '.$schiff2->status();

Dort können wir feststellen ob eines oder beiden Schiffe zerstört wurde und wieviel Rest-Leben die noch funktionstüchtigen Schiffe haben.

Bei jeder Ausführung des „Spiels“ wirst du ein anderes Ergebnis erhalten. In meinem Fall sah das Ergebnis folgendermaßen aus:

Runde1

Runde2

Runde3
Cherti wurde getroffen. Asteroid: 1 - Leben: 10

Runde4
Anubis wurde getroffen. Asteroid: 7 - Leben: 6
Cherti wurde getroffen. Asteroid: 7 - Leben: 6

Runde5

Runde6
Anubis wurde getroffen. Asteroid: 2 - Leben: 6

Runde7

Runde8
Anubis wurde getroffen. Asteroid: 2 - Leben: 6

Runde9
Cherti wurde getroffen. Asteroid: 6 - Leben: 3

Runde10
Cherti wurde getroffen. Asteroid: 6 - Leben: 0

Raumschiff "Anubis" - Leben: 6
Raumschiff "Cherti" - zerstoert

Natürlich ist dies kein richtiges Spiel aber ich hoffe dieses kleine, anschauliche Beispiel hat dir die Funktionsweise unserer bisherigen Klasse etwas nähergebracht :)


3.3.7. Constructor – Objekt erzeugen und Variablen initialisieren

Im Abschnitt Methoden – Funktionen einer Klasse hast du gelernt wie man mit einer Funktion, die innerhalb einer Klasse angelegt wird (sprich: Methode), jedem erzeugten Objekt einen Namen übergeben kann (mittels „setName“).

In diesem Teil geht es auch wieder um Methoden, diesmal um eine ganz spezielle, dem Konstruktor: __construct().

Der Konstruktur ist eine magische Methode. Magische Methoden sind in PHP vordefiniert und werden ausgeführt wenn eine bestimmte Aktion stattfindet. Die Construct-Methode wird automatisch aufgerufen sobald ein Objekt erzeugt wird, schauen wir uns das an unserer bisherigen Klasse Raumschiff_fabrik an:

<?php

class Raumschiff_fabrik
{
	public $geschwindigkeit = 5;
	public $schild = 3;
	public $leben = 10;
	
	public $name;
	
	public function setName($neuer_name) {
		$this->name = $neuer_name;
	}
}

$schiff1 = new Raumschiff_fabrik();
$schiff2 = new Raumschiff_fabrik();

?>

In Zeile 16 und 17 wird jeweils ein Objekt erzeugt. Auch wenn man es hier nicht sieht, wird jedes mal wenn ein Objekt der Klasse „Raumschiff_fabrik“ erzeugt wird, die magische Methode „__construct()“ aufgerufen. Da wir aber bislang in der Konstruktor-Methode keine Anweisungen vergeben haben, können wir keinen Unterschied feststellen.

Wofür ist die Methode „__construct()“ gedacht?

Da der Konstruktor unmittelbar nach der Objekt-Initialisierung aufgerufen wird, eignet er sich hervorragend um Variablen Werte zuzuweisen. Bisher müssen wir, um unserem Raumschiff einen Namen zu geben, extra noch die Methode „setName()“ aufrufen. Dabei wäre es doch praktisch direkt beim erzeugen des Raumschiffs diesem einen Namen zuzuweisen:

<?php

class Raumschiff_fabrik
{
	public $geschwindigkeit = 5;
	public $schild = 3;
	public $leben = 10;
	
	public $name;
	
	function __construct($neuer_name) {
		$this->name = $neuer_name;
	}
}

$schiff1 = new Raumschiff_fabrik('Imhotep');
$schiff2 = new Raumschiff_fabrik('Isis');
echo $schiff1->name;
echo '<br />';
echo $schiff2->name;

?>

Ausgabe

Imhotep
Isis

Nun müssen wir nicht mehr extra die Methode „setName()“ aufrufen, sondern können einfach bei der Objektinitialisierung einen Wert an die magische Methode „__construct()“ übergeben:

new Raumschiff_fabrik('Imhotep');

Wenn kein Wert an __construct übergeben wird

Doch ein Problem besteht weiterhin. Was passiert, wenn kein Wert an den Konstruktor übergeben wird? Dann fliegen immernoch namenlose Raumschiffe durchs All. Das möchten wir natürlich verhindern und modifizieren dafür unseren Konstruktor:

<?php

class Raumschiff_fabrik
{
	public $geschwindigkeit = 5;
	public $schild = 3;
	public $leben = 10;
	
	public $name;
	
	function __construct($neuer_name = null) {
		if($neuer_name != null)
			$this->name = $neuer_name;
		else
			$this->name = 'Raumschiff-ID#'.rand(999, 99999);	
	}
}

$schiff1 = new Raumschiff_fabrik();
$schiff2 = new Raumschiff_fabrik();
echo $schiff1->name;
echo '<br />';
echo $schiff2->name;

?>

Ausgabe (bei jedem Aufruf anders):

Raumschiff-ID#54344
Raumschiff-ID#20370

Der modifizierte Konstruktor ist leicht erklärt: „$neuer_name = null“ sagt aus, wenn kein Wert an den Konstruktor vergeben wird (sprich, die Variable ist leer), soll der Eigenschaft „name“ eine zufällig ID übergeben werden. Ist $neuer_name nicht leer (sprich, es wurde ein Name für das Raumschiff übergeben), soll die Eigenschaft „name“ einfach diesen Wert erhalten.

Es kann noch vorkommen, dass zwei Raumschiffen die gleiche ID zugewiesen wird. Später werden wir unsere Klasse so modifizieren, dass jedes Raumschiff eine eindeutige ID hat.


3.3.7.1. Magische Methoden in PHP

Auf dieser Seite findest du eine Liste der magischen Methoden die in PHP zur Verfügung stehen. Diese Seite dient als Referenz für später denn um alle magischen Methoden zu verstehen musst du noch mehr über die Konzepte der OOP lernen.

Eine genauere Erklärung zu den einzelnen magischen Methoden findest du weiter unten:

__construct()
Wird direkt nach erzeugen des Objekts aufgerufen

__destruct()
Der Destruktor ist quasi das Gegenteil des Konstruktors. Dieser wird aufgerufen wenn das Objekt explizit zerstört wird oder alle Referenzen zum Objekt entfernt werden

__call()
Mittels __call() kann ein Objekt Methoden aufrufen, die in der Klasse selbst nicht angelegt wurden

__callStatic()
Diese Methode funktioniert ähnlich wie _call mit dem Unterschied, dass damit statische Methoden, die nicht deklariert wurden, aufgerufen werden können.

__set()
Mittels __set() kann ein Objekt Eigenschaften (Variablen) erhalten, die in der Klasse nicht vorher definiert wurden.

__get()
Eigenschaften die mittels __set() deklariert wurden, können mittels __get() abgerufen/ausgegeben werden.

__isset()
Mittels __isset() kann man prüfen, ob eine Eigenschaft existiert. So kann man prüfen ob mittels __set() eine Eigenschaft deklariert wurde.

__unset()
Diese Methode ist das Gegenstück zu __set(). Vorher deklarierte Eigenschaften können mittels __unset() gelöscht werden.

__sleep()
Wird aufgerufen wenn ein Objekt mittels serialize(), in eine Zeichenkette (String) umgewandelt wird

__wakeup()
Wird aufgerufen wenn ein String mittels unserialize() zurück in ein Objekt verwandelt wird.

__toString()
Wenn ein Objekt mittels serialize() in einen String umgewandelt wird, bestimmt diese Methode wie sie darauf reagiert.

__invoke()
Die __invoke()-Methode wird aufgerufen, wenn ein Skript versucht, ein Objekt als Funktion aufzurufen.

__set_state()
Dies ist eine statische Methode die aufgerufen wird, wenn ein Objekt mittels var_export() exportiert werden soll

__clone()
Objekte lassen sich mittels „clone“ klonen. Wenn in einer Klasse die __clone()-Methode definiert ist, wird diese nach dem klonen des Objekts aufgerufen.

__construct()

Möchte man nach der Instanziierung eines Objekts Variablen Werte zuweisen, eignet sich die magische Methode __construct dazu. Diese wird direkt nach erzeugen des Objekts aufgerufen und hilft dadurch bei der Objekt-Initialisierung.

__destruct()

In PHP ist es nicht nötig am Ende des Skripts für jedes Objekt die magische Methode __destruct() aufzurufen. PHP entfernt am Ende des Skripts automatisch alle Referenzen und „räumt“ dadurch auf. Der Destructor kann aber zum Beispiel dazu verwendet werden eine Datenbankverbindung explizit zu schließen.

__call()

__callStatic()

__set()

__get()

__isset()

__unset()

__sleep()

__wakeup()

__toString()

__invoke()

__set_state()

__clone()

– Liste alle magische Methoden von PHP auf
– gib jeweils eine kurze Erklärung dazu ab
– verlinke auf das Kapitel in dem es behandelt wird


3.3.7.2. Magische Konstanten in PHP

PHP bietet 7 magische Konstanten an, die, jenachdem wo sie verwendet werden, einen unterschiedlichen Wert haben. Eine Liste der magischen Konstanten und Anwendungsbeispiele findest du hier: Magische Konstanten in PHP


3.3.7.3. Destructor – Objekt zerstören und Ressourcen freigeben

– Aufräumarbeiten finden in Destructor (Magic Methode) statt
– normalerweise Objekt und referenz löschen (ist das bei z.b. Java wirklich so?)
– Hinweis das PHP automatisch am Ende des Scripts die Objekte freigibt
– Beispiele wofür Destructor genutzt werden kann (DB Verbindung beenden, weitere)?


3.3.8. Vererbung

Vererbung ist ein wichtiges Konzept der objekt-orientierten Programmierung. Wenn eine Klasse von einer anderen Klasse abgeleitet wird, spricht man von Vererbung.

Vererbung, ableiten, Ober-Klasse, Unter-Klasse… bitte was?

Warum gibt es die Vererbung? Angenommen wir haben eine Klasse, nennen wir sie „Oberklasse“, möchten nun aber ein Klasse erstellen, die die gleichen Eigenschaften und Methoden hat wie die Oberklasse + noch ein paar mehr, dann können wir mittels Vererbung alle Eigenschaften und Methoden der Oberklasse an unsere neue „Unterklasse“ übergeben.

Dazu ein abstraktes Beispiel:

<?php

error_reporting(E_ALL); //jegliche Fehlermeldungen und Warnungen werden angezeigt

class Oberklasse
{
	public $zahl1;
	public $zahl2;
	
	public function addieren() {
		return ($this->zahl1 + $this->zahl2);
	}
}

class Unterklasse 
{
	public $zahl1;
	public $zahl2;
	
	public function subtrahieren() {
		return ($this->zahl1 - $this->zahl2);
	}
}

$obj1 = new Oberklasse;
$obj1->zahl1 = 5;
$obj1->zahl2 = 3;

$obj2 = new Unterklasse;
$obj2->zahl1 = 5;
$obj2->zahl2 = 1;

echo $obj1->addieren();
echo '<br />';
echo $obj2->subtrahieren();

?>

In diesem Beispiel passiert noch keine Vererbung. Wir haben zwei Klassen („Oberklasse“ und „Unterklasse“) mit jeweils zwei Eigenschaften („zahl1“ und „zahl2) und jeweils einer Methode. Die Oberklasse kann ihre beiden Zahlen addieren und das Ergebnis ausgeben. Die Unterklasse kann ihre beiden Zahlen subtrahieren und das Ergebnis zurückgeben. Bis hierhin nichts neues.

Nun möchten wir aber, dass die „Unterklasse“ ebenfalls die Methode „addieren()“ hat. Anstelle diese Methode jetzt nochmal neu in der Unterklasse zu erstellen (und sich an zwei Stellen um den gleichen Code kümmern zu müssen), können wir einfach die Unterklasse von der Oberklasse ableiten (mit dem Schlüsselwort extends):

<?php

error_reporting(E_ALL); //jegliche Fehlermeldungen und Warnungen werden angezeigt

class Oberklasse
{
	public $zahl1;
	public $zahl2;
	
	public function addieren() {
		return ($this->zahl1 + $this->zahl2);
	}
}

class Unterklasse extends Oberklasse
{
	public function subtrahieren() {
		return ($this->zahl1 - $this->zahl2);
	}
}

$obj2 = new Unterklasse;
$obj2->zahl1 = 5;
$obj2->zahl2 = 1;

echo $obj2->addieren();

?>

Ohne Vererbung würden wir beim Aufruf der Methode „addieren“ folgende Fehlermeldung erhalten:

Fatal error: Call to undefined method Unterklasse::addieren() ...

So aber erhalten wir das Ergebnis: 6

Vererbung ist also, wenn wir eine Klasse von einer anderen Klasse ableiten. Die abgeleitete Klasse bekommt dabei alle Eigenschaften und Methoden der ableitenden Klasse. Diese Eigenschaften und Methoden müssen daher nicht nochmal in der Unterklasse geschrieben werden. Da auch Eigenschaften vererbt werden brauchen wir „zahl1“ und „zahl2“ nun auch nicht mehr in der Unterklasse deklarieren.

Methoden überschreiben

Angenommen wir haben eine Oberklasse mit einer Methode die nicht ganz so arbeitet wie wir wünschen. Das ist kein Problem, denn wir können Methoden und Eigenschaften in der abgeleiteten Klasse überschreiben.

Folgendes Beispiel macht zwar wenig Sinn, zeigt aber wie Methoden überschrieben werden können:

<?php

error_reporting(E_ALL);

class Oberklasse
{
	public $zahl1;
	public $zahl2;
	
	public function addieren() {
		return ($this->zahl1 + $this->zahl2);
	}
}

class Unterklasse extends Oberklasse
{	
	public function addieren() {
		return ($this->zahl1 - $this->zahl2);
	}
	
	public function subtrahieren() {
		return ($this->zahl1 - $this->zahl2);
	}
}

$obj2 = new Unterklasse;
$obj2->zahl1 = 8;
$obj2->zahl2 = 3;

echo $obj2->addieren();

?>

Ausgabe

5

In der „Unterklasse“ überschreiben wir die Methode „addieren()“. Anstelle die beiden Zahlen nun zu addieren, werden sie voneinander subtrahiert.

Vererben magischer Methoden – __construct()

Die magische Methode __construct() hast du schon kennengelernt.

Auch diese können wir ganz einfach an die Unterklasse vererben:

<?php

error_reporting(E_ALL);

class Oberklasse
{
	public $zahl1;
	public $zahl2;
	
	function __construct($zahl1, $zahl2)
	{
		$this->zahl1 = $zahl1;
		$this->zahl2 = $zahl2;
	}
	
	public function addieren() {
		return ($this->zahl1 + $this->zahl2);
	}
}

class Unterklasse extends Oberklasse
{	
	public function subtrahieren() {
		return ($this->zahl1 - $this->zahl2);
	}
}

$obj1 = new Unterklasse(5, 1);
echo $obj1->addieren();

echo '<br />';

$obj2 = new Unterklasse(14, 5);
echo $obj2->addieren();

?>

Jetzt können wir einfach mit unserem Konstruktor den beiden Variablen „zahl1“ und „zahl2“ einen Wert übergeben. Die Methode __construct wird an die Unterklasse vererbt und daher kann auch unser „$obj2“ diese Variablendeklaration verwenden.

Ausgabe:

6
19

3.3.8.1. Sichtbarkeit – Public, Private & Protected

In den vorigen Kapiteln habe ich immer wieder, wenn es um das Schlüsselwort „public“ ging, eine Erklärung aufgeschoben. An dieser Stelle erfolgt nun die Erklärung.

Public, protected & private – 3 Sichtbarkeiten für Eigenschaften und Methoden

In PHP gibt es 3 Sichtbarkeiten die eine Eigenschaft oder eine Methode in einer Klasse haben kann. Sichtbarkeiten sind dafür da festzulegen, an welcher Stelle im PHP Skript der Wert der Eigenschaft/Methode verändert oder aufgerufen werden kann.

(Beispiele folgen weiter unten)

  • public – eine Methode/Eigenschaft, die mit der Sichtbarkeit „public“ ausgestattet ist, kann überall im Skript über das Objekt aufgerufen werden. Alle bisherigen Beispiele wurden als „public“ deklariert.
  • private – als „private“ deklarierte Methoden/Eigenschaften können nur innerhalb dieser Klasse verändert werden. Auch geerbte Klassen können diese Eigenschaften/Methoden nicht aufrufen oder verändern
  • protected – „protected“ funktioniert genauso wie „private“ mit einem entscheidenden Unterschied: vererbte Klassen können diese Methoden/Eigenschaften aufrufen und/oder verändern

Public

<?php

class Elternklasse
{
	public $public_wert = 'Hallo, ich bin PUBLIC';
	
	public function ausgabe() {
		echo $this->public_wert;
	}
}

$obj1 = new Elternklasse;
echo $obj1->public_wert;
echo '<br />';
echo $obj1->ausgabe();

?>

Ausgabe

Hallo, ich bin PUBLIC
Hallo, ich bin PUBLIC

In diesem Beispiel lernst du noch nichts neues. Wir haben eine Eigenschaft und eine Methode, beide sind mit der Sichtbarkeit „public“ ausgestattet. Die Eigenschaft kann entweder direkt aufgerufen werden (Zeile 13) oder über die Methode „ausgabe“ (Zeile 15).

Protected

Nun verwenden wir zum ersten mal die Sichtbarkeit „protected“. Methoden und Eigenschaften die „protected“ sind, können in der Elternklasse und in der Kindklasse aufgerufen werden. Eigenschaften können allerdings nicht direkt über das Objekt aufgerufen werden:

<?php

class Elternklasse
{
	public $public_wert = 'Hallo, ich bin PUBLIC';
	protected $protected_wert = 'Hallo, ich bin PROTECTED';
	
	public function ausgabe() {
		echo $this->public_wert;
	}
}

class Kindklasse extends Elternklasse
{
}

$obj2 = new Kindklasse;
echo $obj2->public_wert;
echo '<br />';
echo $obj2->protected_wert; //diese Zeile erzeugt einen "fatal error"

?>

Ausgabe

Hallo, ich bin PUBLIC

Fatal error: Cannot access protected property Kindklasse::$protected_wert ...

Wir erhalten diese Fehlermeldung aus folgendem Grund: die Eigenschaft „protected_wert“ ist protected und darf daher nicht direkt über das Objekt aufgerufen werden (Zeile 20). Wir können aber über unsere Methode „ausgabe“ den Wert der Eigenschaft „protected_wert“ ausgeben:

<?php

class Elternklasse
{
	public $public_wert = 'Hallo, ich bin PUBLIC';
	protected $protected_wert = 'Hallo, ich bin PROTECTED';
	
	public function ausgabe() {
		echo $this->public_wert;
	}
}

class Kindklasse extends Elternklasse
{
	public function ausgabe() {
		echo $this->public_wert;
		echo '<br />';
		echo $this->protected_wert;
	}
}

$obj2 = new Kindklasse;
echo $obj2->ausgabe();

?>

erzeugt folgende Ausgabe:

Hallo, ich bin PUBLIC
Hallo, ich bin PROTECTED

Eine „geschützte“ Eigenschaft können wir dennoch ausgeben, solange wir dazu eine Methode innerhalb der Klasse verwenden.

Private

Die Sichtbarkeit „private“ ist noch eingrenzender als „protected“. Eigenschaften und Methoden, die in der Elternklasse mit private deklariert werden, werden nicht an die Unterklassen vererbt:

<?php

error_reporting(E_ALL);  //zeigt Warnungen & Fehler an

class Elternklasse
{
	private $private_wert = 'Hallo, ich bin PRIVATE';
	
	public function ausgabe() {
		echo $this->private_wert;
	}
}

class Kindklasse extends Elternklasse
{
	public function ausgabe() {
		echo $this->private_wert;
	}
}

$obj3 = new Elternklasse;
echo $obj3->private_wert; //fatal error
echo '<br />';
echo $obj3->ausgabe();

$obj4 = new Kindklasse;
echo $obj4->private_wert; //fatal error
echo '<br />';
echo $obj4->ausgabe();

?>

Zeile 22 und Zeile 27 erzeugen eine Fehlermeldung, da man, wie beim Schlüsselwort protected, „private“ Eigenschaften nicht direkt über das Objekt aufrufen kann. Läßt man diese beiden Zeilen weg, erhälst du folgende Ausgabe:

Hallo, ich bin PRIVATE

Notice: Undefined property: Kindklasse::$private_wert ...

Da „private“ Eigenschaften nicht an Kindklassen vererbt werden, können wir diesen Wert nicht mit dem „obj4“ ausgeben. Die „Notice“ sagt, dass die Kindklasse die Eigenschaft „private_wert“ nicht kennt (da sie auch nicht vererbt wurde).

Fazit

Public, Protected und Private sind die drei Sichtbarkeiten, die uns PHP zur Verfügung stellt um das Verhalten unserer Klassen und Objekte zu steuern. In den folgenden Teilen werden wir unsere Klassen auch entsprechend abändern und wo es Sinn macht die Schlüsselworte „protected“ und „private“ nutzen.


3.3.9. Vererben und erweitern – Klasse: Raumschiff_fabrik

Jetzt wollen wir unser theoretisches Wissen über Vererbung und Sichtbarkeiten anhand unserer Klasse Raumschiff_fabrik mal in der Praxis anwenden.

Raumschiff_fabrik: Spezialisierung

Neue Kolonisierungsschiffe sind auf dem Weg zu angrenzenden Sonnensystemen, unser Sternenimperium wächst und der Handel zwischen den Planeten steigt. Jetzt ist es an der Zeit unsere Flotte zu spezialisieren.

Bislang wirft unsere Raumschifffabrik nur einen Typ Raumschiff aus. Doch damit unsere Zivilisation wächst und gedeiht brauchen wir Transporter (für den Handel), Scouts (entdeckt feindliche Raumschiffe, findet kolonisierbare Planeten), Fighter (kleine, bewaffnete Raumschiffe), und Zerstörer (das Kernstück unserer Abschreckungsflotte).

Bevor wir unsere Raumschifffabrik erweitern, hier nochmal der bisherige Stand der Klasse Raumschiff_fabrik:

<?php
//dieser Quellcode kommt nun in die Datei "Raumschiff_fabrik.php"

class Raumschiff_fabrik
{
	protected $geschwindigkeit = 5;
	protected $schild = 3;
	protected $leben = 10;

	protected $typ;
	protected $name;

	public function __construct($neuer_name = null) 
	{
		if($neuer_name != null)
			$this->name = $neuer_name;
		else
			$this->name = 'Raumschiff-ID#'.rand(999, 99999);
	}
	
	protected function treffer($schaden) 
	{
		if($this->schild < $schaden)
		{
			//berechne wieviel Schaden trotz des Schilds entsteht
			$rest_schaden = $schaden - $this->schild;
			$this->leben -= $rest_schaden;

			if($this->leben <= 0)
			{
				echo 'Raumschiff "'.$this->name.'" wurde zerstört';
			}
		}
	}
}

?>

Lege nun eine neue Datei mit Namen Raumschiff_fabrik.php an und packe obigen Quellcode in diese Datei. Wie dir wahrscheinlich aufgefallen ist, habe ich einige Änderungen vorgenommen. Alle Eigenschaften sind nun „protected„, da ich nicht möchte, dass die Werte der Eigenschaften direkt über das Objekt verändert werden können. Allerdings möchte ich, dass unsere spezialisierten Raumschiffe auf die gleichen Eigenschaften zugreifen können (deshalb nicht „private„).

Zusätzlich habe ich noch eine Eigenschaft „typ“ hinzugefügt, die in der nächsten Klasse einen Wert erhalten wird.

Spezialklasse: Fighter

Lege im gleichen Ordner, indem auch die Datei Raumschiff_fabrik.php liegt eine neue Datei Fighter.php an. Dies ist eine spezialisierte Klasse, die von der Klasse „Raumschiff_fabrik“ erbt:

<?php
	require_once('Raumschiff_fabrik.php');

	class Fighter extends Raumschiff_fabrik
	{
		protected $geschwindigkeit = 7;
		protected $schild = 5;
		protected $leben = 20;
		
		protected $laser = 8;
		
		public function __construct() 
		{
			// rufe den Konstruktor der Klasse Raumschiff_fabrik auf
			parent::__construct();   
        	$this->typ = __Class__;
			
			//alternative Schreibweise: $this->typ = 'Fighter';
		}
		
		protected function attack() 
		{
			return $this->laser;
		}
	}
	
//nur zum testen, soll nicht mit in der Datei stehen
	$fighter1 = new Fighter;
	print_r($fighter1);
?>

Erklärung:
Als erstes binden wir die Klasse „Raumschiff_fabrik“ mittels „require_once“ in unser Skript ein. Dies ist nötig damit die Klasse „Fighter“ von der Klasse „Raumschiff_fabrik“ vererbt werden kann (Zeile 4 „extends“). Als nächstes erhöhen wir die Werte „Geschwindigkeit“, „Schild“ und „Leben“ um unsere Kampfflieger ein bisschen widerstandsfähiger zu machen. Zusätzlich geben wir der Klasse „Fighter“ noch die Eigenschaft „laser“. Wenn unser Fighter-Objekt angreift, kann es pro Attacke 8 Schaden zufügen.

Der Konstruktor ist neu:

public function __construct() 
{
	// rufe den Konstruktor der Klasse Raumschiff_fabrik auf
	parent::__construct();   

	$this->typ = __Class__; //alternative Schreibweise: $this->typ = 'Fighter';
}

Wir möchten, dass unser Fighter-Konstruktor genau das gleiche macht wie der Konstruktor der Klasse „Raumschiff_fabrik“ doch zusätzlich noch der Eigenschaft „typ“ den Typ des Raumschiffs zuweist. Wenn wir lediglich eine neue Methode „__constuct()“ anlegen, wird der Konstruktor der Elternklasse überschrieben und die Funktionalität geht verloren. Daher nutzen wir:

parent::__construct();

Damit rufen wir die Funktionalität der Methode „__construct“ der Elternklasse auf. Das Schlüsselwort „parent“ können wir auch in anderen Methoden verwenden um auf die Funktionalität einer bestimmten Methode der Elternklasse zuzugreifen. Nun weisen wir der Eigenschaft „typ“ noch einen Wert zu. Jedes spezialisierte Objekt soll ihren Typ mit aufnehmen (sprich: Objekte der Klasse Fighter, sollen den Typ „Fighter“ haben). Dies können wir auf zwei Arten machen:

$this->typ = 'Fighter';

$this->typ = __Class__; 

Standardmäßig wird man hier einfach einen String übergeben. In Zeile 3 möchte ich euch aber mal an einem Beispiel zeigen, wie man magische Konstanten verwenden kann. Die magische Konstante __Class__ beinhaltet den Namen der Klasse in der wir uns gerade befinden („Fighter“).

Als letztes erhält die Klasse „Fighter“ eine Methode „angriff“. Wenn ein Fighter-Objekt ein feindliches Raumschiff angreift, gibt diese Methode den erzeugten Schaden aus (Stärke des Lasers).

Die weiteren Raumschiff-Typen (Scout, Transporter und Zerstörer) werden in den Unterartikeln angelegt und erklärt.


3.3.9.1. Klasse: Scout

Wir erweitern unsere Raumschifffabrik um Scout-Schiffe zu bauen. Diese haben weniger Panzerung („leben“), ein schwächeres Schutzschild („schild“) und keinen „laser“, haben dafür aber eine erhöhte Geschwindigkeit um vor Feinden zu fliehen. Erzeuge die Datei Scout.php und füge folgenden Code ein:

<?php
	require_once('Raumschiff_fabrik.php');

	class Scout extends Raumschiff_fabrik
	{
		protected $geschwindigkeit = 20;
		protected $schild = 2;
		protected $leben = 8;
		
		public function __construct() 
		{
			parent::__construct();   
			$this->typ = __Class__;
		}
	}
	
//der folgende Teil ist nur zum testen und sollte nicht mit in der Datei stehen
	$scout1 = new Scout;
	print_r($scout1);
?>

Das war es in dieser Klasse auch schon. Weiter geht es mit der Klasse: Transporter.


3.3.9.2. Klasse: Transporter + Schlüsselwort: „self“

Als nächstes brauchen wir Transporter um den Handel zwischen den Planeten in Schwung zu bringen. Transporter haben keine Waffen („laser“), aber dafür einen Frachtraum. Transporter können be- und entladen werden und können ihre maximale Frachtkapazität nicht übersteigen. Lege eine Datei Transporter.php an (im gleichen Verzeichnis wie die anderen Klassen) und füge den folgenden Quellcode ein:

<?php
	require_once('Raumschiff_fabrik.php');

	class Transporter extends Raumschiff_fabrik
	{
		protected $geschwindigkeit = 10;
		protected $schild = 3;
		protected $leben = 12;
		
		protected $frachtraum = 0;
		const FRACHTRAUM_MAX = 20;
		
		public function __construct() 
		{
			parent::__construct();   
			$this->typ = __Class__;
		}
		
		public function beladen($last) 
		{
			if(($this->frachtraum + $last) > self::FRACHTRAUM_MAX)
			{
				echo 'Soviel Last kann der Frachtraum nicht laden, bitte reduzieren Sie die Last um '.(($this->frachtraum + $last) - self::FRACHTRAUM_MAX).' Einheiten';
			} else {
				$this->frachtraum += $last;
				echo 'Frachtraum beladen. Noch '.(self::FRACHTRAUM_MAX - $this->frachtraum).' Einheiten Last moeglich';
			}
		}
		
		public function entladen() 
		{
			$this->frachtraum = 0;
			echo 'Transporter: '.$this->name.' wurde entladen';
		}  
	}

//der folgende Teil ist nur zum testen und soll nicht mit in der Datei Transporter.php stehen.

	$transporter1 = new Transporter;
	print_r($transporter1);

	echo '<br /><br />'; 
	
	$transporter1->beladen(10);
	echo '<br />';
	$transporter1->beladen(12);
	echo '<br />';
	$transporter1->entladen();
?>

Diese Klasse hat zwei neue Dinge:
1. const FRACHTRAUM_MAX = 20; – hierbei handelt es sich um eine Konstante. Jeder Transporter hat einen Frachtraum, der in diesem Fall die Größe 20 hat.

2. Um innerhalb einer Klasse eine Konstante zu verwenden, benötigt man das Schlüsselwort self. „Self“ bezieht sich dabei auf die gerade aktive Klasse. Alternativ könnte man auch einfach den Namen der Klasse verwenden, beides ist demnach möglich um innerhalb der Klasse „Transporter“ auf den Wert der Konstante zuzugreifen:

echo self::FRACHTRAUM_MAX;

echo Transporter::FRACHTRAUM_MAX;

Jetzt fehlt nur noch ein Raumschiff Typ: der Zerstörer. Der Fighter ist ein kleines, wendiges Raumschiff mit einer relativ schwachen Bewaffnung. Damit feindliche Aliens garnicht erst auf die Idee kommen unsere Heimatwelt anzugreifen, brauchen wir eine Abschreckungsflotte. Eine Flotte, bis an die Zähne bewaffneter, Zerstörer.


3.3.9.3. Klasse: Zerstoerer

Bis auf ein paar zusätzliche Waffen und veränderte Werte unterscheidet sich die Klasse „Zerstoerer“ nicht sonderlich von der Klasse Fighter. Deshalb erbt „Zerstoerer“ auch nicht von der Klasse Raumschiff_fabrik, sondern direkt von der Klasse Fighter. Lege eine neue Datei Zerstoerer.php und füge folgenden Quellcode ein:

<?php
	require_once('Fighter.php');

	class Zerstoerer extends Fighter
	{
		protected $geschwindigkeit = 15;
		protected $schild = 7;
		protected $leben = 80;
		
		protected $laser = 20;
		protected $raketen = 30;
		
		public function __construct() 
		{
			parent::__construct();   
			$this->typ = __Class__;
		}
		
		protected function attack()
		{
			return ($this->laser + $this->raketen);
		}
	}
	
	//nur zum testen, sollte nicht mit in der Datei stehen
	$zerstoerer1 = new Zerstoerer;
	print_r($zerstoerer1);
?>

Das war es auch schon, unsere Raumschiff_fabrik ist spezialisiert und wir können uns eine Flotte bauen. In den folgenden Teilen tauchen wir noch tiefer ein in die OOP ein und werden unsere spezialisierten Klassen optimieren.


3.3.10. Static


3.3.11. Abstract


3.3.12. Interfaces


3.3.13. Überladen


3.3.14. Final


3.4. Fehler finden und beheben für Fortgeschrittene