titel.fm Seite 1 Dienstag, 8. Oktober 2002 2:13 14
Liebe Leserin, lieber Leser, wir freuen uns, dass Sie sich für ein Buch der Reihe Galileo Design entschieden haben. Galileo Design ist die Reihe für professionelle Screen-, Web- und Grafik-Designer und Experten im Prepress-Bereich. Unsere Bücher zeigen, wie man es macht – strikt aufgabenbezogen und mit Beispielmaterial professioneller Designer erschließen sie die Anwendung aller relevanten Tools und Techniken. Sie vermitteln das technische Know-how, und sie sind Ideengeber und überraschen mit originellen und inspirierenden Lösungen. Wissen teilt sich nicht nur sprachlich, sondern auch visuell mit. Satz und Layout tragen dem Rechnung. Und wo immer es dienlich ist, ist ein Buch vierfarbig gestaltet. Unsere Bücher sind eine Augenschule: indem sie gefallen, setzen sie Kreativität frei. Denn Designer lesen anders. Jedes unserer Bücher will Sie überzeugen. Damit uns das immer wieder neu gelingt, sind wir auf Ihre Rückmeldung angewiesen. Bitte teilen Sie uns Ihre Meinung zu diesem Buch mit. Ihre kritischen und freundlichen Anregungen, Ihre Wünsche und Ideen werden uns weiterhelfen. Wir freuen uns auf den Dialog mit Ihnen. Ihre Ruth Wasserscheid Lektorat Galileo Design Galileo Press Gartenstraße 24 53229 Bonn
[email protected] www.galileodesign.de
titel.fm Seite 2 Dienstag, 8. Oktober 2002 2:13 14
titel.fm Seite 3 Dienstag, 8. Oktober 2002 2:13 14
Christof Marte
Flash MX und PHP, MySQL und XML Dynamische Webseiten generieren mit Flash
titel.fm Seite 4 Dienstag, 8. Oktober 2002 2:13 14
Die Deutsche Bibliothek – CIP-Einheitsaufnahme Ein Titeldatensatz für diese Publikation ist bei der Deutschen Bibliothek erhältlich ISBN 3-89842-257-7 © Galileo Press GmbH, Bonn 2003 Das vorliegende Werk ist in all seinen Teilen urheberrechtlich geschützt. Alle Rechte vorDer Name Galileo Press geht auf den italieni-
behalten, insbesondere das Recht der Über-
schen Mathematiker und Philosophen Galileo
setzung, des Vortrags, der Reproduktion, der
Galilei (1564–1642) zurück. Er gilt als Grün-
Vervielfältigung auf fotomechanischem oder
dungsfigur der neuzeitlichen Wissenschaft
anderen Wegen und der Speicherung in elek-
und wurde berühmt als Verfechter des moder-
tronischen Medien.
nen, heliozentrischen Weltbilds. Legendär ist
Ungeachtet der Sorgfalt, die auf die Erstellung
sein Ausspruch Eppur se muove (Und sie be-
von Text, Abbildungen und Programmen ver-
wegt sich doch). Das Emblem von Galileo
wendet wurde, können weder Verlag noch
Press ist der Jupiter, umkreist von den vier
Autor, Herausgeber oder Übersetzer für mög-
Galileischen Monden. Galilei entdeckte die
liche Fehler und deren Folgen eine juristische
nach ihm benannten Monde 1610.
Verantwortung oder irgendeine Haftung übernehmen.
Lektorat Ruth Wasserscheid
Die in diesem Werk wiedergegebenen
Korrektorat Alexander Reischert, Köln
Gebrauchsnamen, Handelsnamen, Waren-
Einbandgestaltung Helmut Kraus, Düsseldorf
bezeichnungen usw. können auch ohne
Herstellung Sandra Gottmann Satz reemers
besondere Kennzeichnung Marken sein und
publishing services gmbh, Krefeld Druck und
als solche den gesetzlichen Bestimmungen
Bindung Bercker Graphischer Betrieb, Kevelaer
unterliegen.
titel.fm Seite 5 Dienstag, 8. Oktober 2002 2:13 14
flashIVZ.fm Seite 6 Dienstag, 8. Oktober 2002 2:13 14
Inhalt 8 Vorwort
12 PHP
166 MySQL 168 Relationale Datenbanken
14 Einstieg in PHP
174 Normalisierung und Datenmodelle
20 PHP-Grundlagen
182 SQL und MySQL
84 HTML-Formulare und PHP
238 ODBC
108 Beispiel: PHP-Bildergalerie
252 Volltextsuche
116 Dateien, Verzeichnisse und Zugriffsrechte
278 Testdatengenerierung
124 PHP-Cookies und Sessions 140 Ming
6
0
Inhalt
flashIVZ.fm Seite 7 Dienstag, 8. Oktober 2002 2:13 14
290 XML 292 XML-Grundlagen
352 Workshops 354 Anwendungen 356 Verarbeitung von Sonderzeichen
552 Anhang 554 Funktionen in ActionScript, PHP und MySQL 580 ActionScript-Assembler 590 Ereignisbehandlung in Flash 596 Internet-Ressourcen 600 Index
364 Diagrammkomponenten 420 Tabellenbrowser 442 Zahnräder 462 Online: »Vier gewinnt« 496 comMX
Inhalt
7
1_00.fm Seite 8 Dienstag, 8. Oktober 2002 2:13 14
Vorwort
0
Das Flash-Format hat sich mittlerweile nicht nur zur Darstellung von Animationen und Comics, sondern auch für komplexe Infografiken und datenbankgestützte Anwendungen durchgesetzt. Flash MX hat mit den neuesten ActionScript-Erweiterungen den letzten Schritt gemacht, der für die umfassende Programmierung und Darstellung von dynamischen Inhalten noch erforderlich war. Im Gegensatz zu statischen HTML-Seiten verlangt der Aufbau von dynamischen Webseiten neben der grafischen Gestaltung auch Programmierkenntnisse. Die Programmierung erfolgt in Flash auf der Client-Seite mit ActionScript. Auf der Server-Seite steht eine Vielzahl von Skript-Sprachen zur Verfügung. PHP in Kombination mit MySQL als Datenbank spielt dabei eine Hauptrolle. Die Suche nach PHP+MySQL ergibt in Google 2,5 Millionen Treffer – vermutlich mehr als jede andere derartige Kombination. Der Erfolg beruht wesentlich auf der Open-Source-Gemeinde, die diese Programme unentgeltlich zur Verfügung stellt und ständig weiterentwickelt. XML, die universelle Markup-Sprache, dient in diesem Umfeld in erster Linie als Transportmittel für Informationen zwischen Datenbank und Flash. Das Buch beschreibt auf dieser Basis die Grundlagen der Programmierung dynamischer Webseiten und soll auch dem Programmieranfänger einen Überblick über die Möglichkeiten der Verbindung von Flash, PHP, MySQL und XML geben. Die ersten drei Teile über PHP, MySQL und XML können für sich allein gelesen werden, während die Workshops im vierten Teil alle Elemente verwenden. Doch auch in den ersten Teilen sind einige Verweise, Vorund Rückgriffe auf die anderen Bereiche vorhanden, soweit es für das Verständnis hilfreich erschien. Bei der Programmierung ist es sinnvoll, mit kleinen Schritten zu beginnen und Anwendungen in Teilen aufzubauen:
8
Vorwort
1_00.fm Seite 9 Dienstag, 8. Oktober 2002 2:13 14
Wenn es um die erste Version eines neuen Sytems geht, dann weiß ich wirklich keinen anderen Weg, als es in fast völlig unabhängige Teile zu teilen und jedes dieser Teile nur einer einzigen Person zu übelassen. Die einzelnen Leute müssen miteinander über die Schnittstellen reden, aber nicht über ihre eigene Arbeit Donald E. Knuth, c't 5/2002. Diese Aufteilung – ob sie sich auf die Aufteilung im Team oder die Aufteilung in den verschiedenen Programmierumgebungen bezieht – hat sich bei der Programmierung in komplexeren Umgebungen als extrem nützlich erwiesen. Der Leser verschafft sich vielleicht am besten zuerst einen Gesamtüberblick. Je nach Interessen und Vorkenntnissen kann er dann mit dem einen oder anderen Kapitel im Detail beginnen oder gleich eine WorkshopAnwendung aufbauen und bei Bedarf in den anderen Teilen weiterlesen. Die Abbildung zeigt einen Überblick zur Softwareumgebung, die für die Entwicklung der Beispiele verwendet wurde. In jedem Fall erforderlich ist ein HTTP-Server (Apache) mit PHP und MySQL. Für die clientseitige Entwicklung ist Flash MX Voraussetzung. Weitere Tools sind zwar nicht unbedingt notwendig, machen das Leben aber angenehmer. In der Abbildung und im Anhang sind die wichtigsten Tools aufgeführt. Die Entwicklungsumgebungen des Autors sind Windows 2000 und Windows 98, die Produktionsumgebung für das Internet ein Linux-Server mit Apache, PHP und MySQL. Hinweise zur Installation und Konfiguration der LAMP (Linus, Apache, MySQL, PHP)- und WAMP (Windows, Apache, MySQL, PHP)-Umgebungen gibt es auf der Buch-CD. Als Entwicklungsumgebung kommen prinzipiell aber auch Mac OS X oder Linux in Frage. In der Frage der »besten« Betriebssystemumgebung ist eine deutliche Konvergenz zu erkennen, da jeder Hersteller ein Interesse daran hat, dass die Software auf möglichst vielen Plattformen arbeitet. Auch der Flash Player ist mittlerweise für Linux verfügbar. PHP wurde in den Versionen 4.05 bis 4.2.1 verwendet. Besonders wichtige Änderungen zwischen den Versionen in PHP, vor allem die Einführung superglobaler Variablen, werden deutlich gemacht. MySQL wird in der Version 4.0.1 verwendet. Mit MySQL 3.xx werden die meisten Beispiele im Buch genauso funktionieren, nicht aber die Volltextsuche, für die sich ab Version 4 wesentlich erweiterte Möglichkeiten ergeben.
Vorwort
9
1_00.fm Seite 10 Dienstag, 8. Oktober 2002 2:13 14
Macromedia Studio Flash MX
Freehand
Dreamweaver
Bildbearbeitungsprogramm
XML-Editor
PHPEntwicklungsumgebung
Browser: -IE -Navigator -Opera mit Plugins
http
phpMyAdmin Lokales Dateiensystem mit lokalem Apache-Server
weitere Tools
MySQL-Konsole
-Texteditor -Textverarbeitung -Zip-Programm
MySQL ODBC
ftp
Microsoft Access u.a.
Browser
http
Internet-Sever
ftp
왖 Abbildung 1
Die Softwarekonstellation zur Entwicklung dynamischer Web-Inhalte
Mein Dank gilt allen, die in irgendeiner Weise am Buch mitgearbeitet haben, insbesondere Doris Beimler für die Gestaltung der Grafiken und zahlreicher Flash-Beispiele, den Korrektoren Franz Huber und René Schönian sowie dem Lektorat Galileo Design des Galileo-Verlages: Ruth Wasserscheid und Sonja Schramm. Danke auch an flashforum.de und die Open-Source-Gemeinschaft. Viel Spaß beim Lesen und Programmieren! Heidelberg, im Oktober 2002 Christof Marte
10
Vorwort
1_00.fm Seite 11 Dienstag, 8. Oktober 2002 2:13 14
teil01.fm Seite 12 Dienstag, 8. Oktober 2002 2:13 14
PHP 0 14 Einstieg in PHP 14 Programmiersprachen 16 PHP – Ein Minimalprogramm
37 Dateien einbinden 38 Programmstrukturen 44 Arrays 55 Reguläre Ausdrücke
20 PHP-Grundlagen 20 PHP-Markierungen und -Kommentare
67 Objekte
84 HTML-Formulare und PHP
22 Ausdrücke und Anweisungen 23 Operatoren 26 Variablen 30 Globale Variablen in PHP 34 Konstanten 35 Funktionen und Funktionsparameter 37 Statische Variablen in Funktionen
84 Formulare, GET und POST 86 HTTP-Anfragen und MIMETypen 89 Formularelemente 91 Formularvariablen und PHP 94 Formulargestaltung 95 Aktivierung und Deaktivierung von Eingabefeldern 95 Eine Umfrageanwendung
12
teil01.fm Seite 13 Dienstag, 8. Oktober 2002 2:13 14
108 Beispiel: PHP-Bildergalerie 108 Rekursionen 110 Verzeichniseinträge lesen 110 Die Bildergalerie
116 Dateien, Verzeichnisse und Zugriffsrechte 116 Lesen und Schreiben von Dateien 119 Informationen zu einer einzelnen Datei 120 Kopieren und Löschen von Dateien
121 Verwalten und Lesen von Benutzerrechten 122 Funktionen für Verzeichnisse
124 PHP-Cookies und Sessions 124 Cookies 133 Sessions 138 Browser-Cache
140 Ming 140 Flash, Ming und PHP 141 Die Ming-Objekte 142 Beispielanwendungen 155 Ming-Referenz
13
1_01.fm Seite 14 Dienstag, 8. Oktober 2002 2:14 14
Einstieg in PHP
0
Einstieg und Anwendung Die Programmiersprache PHP steht im Mittelpunkt dieses Teils. Zunächst wollen wir aber einen kurzen Blick auf andere Programmiersprachen werfen, um PHP richtig einordnen zu können. Anschließend beginnen wir direkt mit der Praxis: ein kleines PHP-Beispiel wird aufgebaut.
Programmiersprachen
Compiler
Interpreter
14
Ein Programm besteht aus einer Menge von Anweisungen, die vom Computer schrittweise abgearbeitet werden. Schrittweises Abarbeiten bedeutet hier, dass der Prozessor Anweisungen in Form von Maschinensprachencode erhält, die beispielsweise einzelne Speicherzellen lesen oder elementare Rechenoperationen ausführen. Ein Computerprogramm kann mithilfe eines Assemblers direkt im Maschinencode programmiert werden. Dies stellt aber die Ausnahme dar. Höhere Programmiersprachen (C++, Java, SmallTalk) bieten bei der Programmierung zwei wesentliche Vorteile: eine fortschrittliche Syntax, die häufig an die Problemstellung angepasst ist (Grafikprogrammierung, Datenbankprogrammorientierung), und die Unabhängigkeit vom Prozessor. Für die Umsetzung des Codes gibt es zwei verschiedene Ansätze. Ein Compiler (dt.: Kompilierer) übersetzt den in der höheren Programmiersprache abgefassten Quellcode in Maschinencode. Der Maschinencode kann ein ausführbares Programm (EXE-Datei, executable) oder eine Bibliotheksdatei (DLL, Dynamic Link Library) sein – mit Funktionen, die aus einem anderen Programm heraus aufgerufen werden können. Ein Interpreter ist ein Programm, das den Quellcode liest und die darin enthaltenen Befehle während der Laufzeit direkt in Maschinencode umsetzt. Dabei entsteht keine EXE-Datei. PHP, JavaScript und ActionScript sind Interpreter-Sprachen, die teilweise auf dem Server, teilweise auf dem Client ablaufen. Server und
Einstieg in PHP
1_01.fm Seite 15 Dienstag, 8. Oktober 2002 2:14 14
Client beziehen sich hier auf eine Internet- oder eine lokale Verbindung. ActionScript kann außerdem in einer Flash-Projektor-EXE-Datei selbstständig ablaufen. Sprache
Umgebung
Interpreter
ActionScript
Client
Flash-Player oder Interpreter im Projektor
Server
Server-seitiges ActionScript, z.B. mit dem FlashCommunication-Server
Client
JavaScript-Interpreter des Browsers, DHTML
JavaScript
Server
Server-seitiges JavaScript
PHP
Server
Server-PHP-Module (DLLs) oder php.exe (bei Installation als CGI)
Java
Client
Java-Applets
Server
Java-Servlets
Java verwendet für die Programmausführung eine Mischform von Compiler und Interpreter. Ein Java-Programm wird von der für verschiedene Betriebssysteme erhältlichen Java Virtual Machine ausgeführt. Der ausgeführte Code ist so genannter Byte-Code, eine maschinenunabhängige, aber kompilierte Form des Java-Quellcodes. Die Virtual Machine interpretiert diesen Byte-Code.
Elemente der Programmiersprachen Wenn auch Umgebung und Syntax der Programmiersprachen unterschiedlich sind, enthalten sie doch alle ähnliche Elemente. Dazu gehören: 왘 Ausdrücke und Operatoren 왘 Variablen und Konstanten, Datentypen 왘 Verzweigungen und Schleifen 왘 Funktionen und Unterprogramme 왘 Arrays und Texte 왘 Objekte – bei objektorientierten Sprachen 왘 Fehlerbehandlungsmöglichkeiten 왘 Ereignisbehandlung – bei ereignisorientierten Sprachen Je nach Anwendungsbereich, Umgebung und Historie sind diese Elemente in den verschiedenen Programmiersprachen unterschiedlich ausgeprägt. Programme mit viel Interaktion mit dem Benutzer sind eher ereignisorientiert ausgelegt. Sie müssen auf Tasten- und Maussignale rea-
Programmiersprachen
15
1_01.fm Seite 16 Dienstag, 8. Oktober 2002 2:14 14
왘 Seite 590
gieren und grafische Oberflächen verwalten können. Die Ereignisbehandlung kann sich als sehr komplexe Aufgabe erweisen, da das Programm auf die unterschiedlichsten Ereignisse zuverlässig reagieren soll. Programme, die auf einem entfernten Server laufen oder rechenintensive Aufgaben ausführen, sind dagegen weniger ereignisorientiert. In diesem Kapitel werden wir die Grundlagen der Programmierung in PHP kennen lernen. Dabei orientieren wir uns an der oben genannten Gliederung. Alle Beispiele sind auf PHP bezogen. Im Abschnitt mit den Funktionsbibliotheken werden, wenn möglich, gleichzeitig mit der Vorstellung der einzelnen Funktionen die Syntax von ActionScript und MySQL gegenübergestellt. Im Abschnitt zur objektorientierten Programmierung werden wir PHP und Flash-Objekte explizit vergleichen. Die Ereignisbehandlung fällt in PHP sehr kurz aus – vor allem deshalb, weil es keine Maus- und Tastaturereignisse gibt. Um einen Einblick in ereignisorientierte Programmierung zu gewinnen, wurde im Anhang ein Abschnitt mit dem Ereignismodell von Flash MX aufgenommen, das im Vergleich zu Flash 5 wesentlich erweitert wurde.
PHP – Ein Minimalprogramm Mit dem Abschluss der Installation von PHP kann ein kleines Programm »phpinfo.php« mit den Informationen zu der aktuellen installierten PHPVersion aufgerufen werden.
Der Server erhält eine Anfrage nach der Datei »phpinfo.php«. Aufgrund der Server-Einstellungen für Dateiendungen entscheidet der Server, diese Datei nicht direkt auszugeben, wie es mit phpinfo.htm der Fall wäre, sondern als PHP-Skript zu verarbeiten. Bei der PHP-Verarbeitung erkennt der PHP-Interpreter die erste und letzte Zeile als Tags, die den eigentlichen Programmcode einschließen. Alles was nicht in Verarbeitungs-Tags eingeschlossen ist, gibt der Interpreter unverändert an die Ausgabe weiter. Hier wird phpinfo(); als PHP-Code verarbeitet. Der Interpreter erkennt, dass es sich um eine Funktion handelt, die Informationen zur
16
Einstieg in PHP
1_01.fm Seite 17 Dienstag, 8. Oktober 2002 2:14 14
PHP-Konfiguration ausgeben soll. Er ruft die Funktion auf, und die Funktion schreibt diese Informationen als formatierte HTML-Seite in die Ausgabe. Ohne weitere Hilfsmittel können wir dieses dreizeilige Programm mit einem Texteditor schreiben, unter dem Namen phpinfo.php speichern und im Web-Browser die lokale Adresse http://localhost/phpinfo.php aufrufen, um es auszuführen. Der lokale Server muss hierbei gestartet sein. Für die weitere Programmierung empfiehlt sich die Verwendung eines PHP-Editors, der folgende Möglichkeiten aufweisen kann: 왘 Vereinfachte Eingabe von Funktionen, indem zu angefangenen Tags entsprechende End-Tags gesetzt werden. 왘 Farbliche Hervorhebung von Schlüsselwörtern und Variablen. 왘 Verwaltung von Codebibliotheken. 왘 Online-Hilfe mit Anzeige von Parametern bei der Eingabe von Funktionen. 왘 Die Möglichkeit der Programmausführung in der Entwicklungsumgebung. 왘 Vielfältige Möglichkeiten zur Fehlersuche (debugging). Einige Beispiele für PHP-Editoren sind im Anhang »Links« aufgeführt. Das hier gezeigte Minimalprogramm gibt eine komplette HTML-Seite aus. Ein Programm in der Form
liefert nur den Text »Hallo Welt.«. Es fehlt eine HTML-Einbettung, die zur korrekten Darstellung erforderlich ist. Zwar können die meisten Browser oder PHP-Editoren die Ausgabe auch ohne einrahmendes HTML darstellen, doch die Form
Hallo! sollte verwendet werden, wenn das Skript eine echte HTML-Ausgabe liefern soll. Im Buch wurde bei einfachen Beispielen der HTML-Teil weggelassen. Für einen einfachen Test genügt dies; für reale Anwendungen sollte die HTML-Ausgabe aber immer vollständig sein.
18
Einstieg in PHP
1_01.fm Seite 19 Dienstag, 8. Oktober 2002 2:14 14
Für Ihre Notizen
PHP – Ein Minimalprogramm
19
1_02.fm Seite 20 Dienstag, 8. Oktober 2002 2:14 14
PHP-Grundlagen
0
Die Basics Beginnend bei einfachen Programmbeispielen werden allgemeine Aspekte der Programmierung, Funktionen, Objekte und Arrays behandelt. Wo es sinnvoll ist, wird ein direkter Vergleich mit ActionScript und MySQL-Funktionen gezogen.
PHP-Markierungen und -Kommentare Neben der oben gezeigten Form der Einbettung von ausführbarem PHPCode in nicht interpretiertem Text mit sind folgende Möglichkeiten vorhanden: Anfang
Ende
oder php?> Die übersichtlichste Form
Bemerkung
Die herkömmliche Form
Der SGML-Stil als kürzeste Form. Programmkommentare sind Anmerkungen des Programmierers, die in den Programmcode eingefügt werden. Eine gute Kommentierung und Dokumentation des Programms wird man erst dann zu schätzen wissen, wenn man ein Programm nach einem halben Jahr modifizieren möchte oder von einem anderen Programmierer übernimmt. Besonders nützlich ist die Kommentierung von Funktionen bzw. Variablen und die Erläuterung komplizierter Routinen. Auch die Namensgebung bei Variablen und Funktionen spielt hier eine wesentliche Rolle. Sie sollte einheitlich sein und den Zweck des Objekts beschreiben. Bei PHP-Kommentaren werden für einzeilige Kommentare zwei Schrägstriche verwendet: // Dies ist ein Kommentar Mehrzeilige Kommentartexte werden mit den Markierungen /* und */ eingeschlossen.
Summe Im Beispiel oben wird – im Vorgriff auf die Beschreibung in den nächsten Abschnitten – eine Funktion verwendet, die mit einer Programmschleife eine Summe bildet. Diese Funktion könnte in einer kompakteren Form so aussehen:
function summeVonBis($n1, $n2) { for ($i=$n1,$s=0; $i -> -> ->
0 0 0 1
Oder-Verknüpfung
OR ||
$a || $b
0 0 1 1
|| || || ||
0 1 0 1
-> -> -> ->
0 1 1 1
Exklusiv-Oder-Verknüpfung
XOR
$a || $b
0 0 1 1
XOR XOR XOR XOR
Umkehrung, Inversion
!
0 1 0 1
-> -> -> ->
0 1 1 0
!0 -> 1 !1 -> 0
Die Operatoren && und || haben gegenüber AND bzw. OR eine höhere Priorität bei der Auswertung. Bit-Operatoren arbeiten mit dem Integer-Datentyp (32 Bit Datenlänge) und beeinflussen die einzelnen Bits der Variablen. Im Beispiel werden die Zahlen 35 und 7 verwendet, die im Binärsystem als 00010011 und 00000111 geschrieben werden. Die Verschiebung nach links und nach rechts entspricht Multiplikationen und Divisionen um Vielfache von 2. Operation
Operator
Ausdruck
Ergebnis
UND-Verknüpfung der Bits
&
35 & 7
3
ODER-Verknüpfung der Bits
|
35 & 7
39
XOR-Verknüpfung
^
35 ^ 7
36
Komplement (Umkehrung aller Bits)
~
~35
-36
Verschiebung nach links
7 >> 2
1
Operatoren
25
1_02.fm Seite 26 Dienstag, 8. Oktober 2002 2:14 14
Operatoren in ActionScript und PHP
Zwischen den Operatoren von PHP und denen von Flash ActionScript gibt es nur unwesentliche Unterschiede. So erfolgt die Verknüpfung von Zeichenketten in Flash nicht mit dem Punkt, sondern mit dem Pluszeichen.
Variablen
Groß- und Kleinschreibung
Variablennamen werden in PHP durch ein Dollarzeichen gekennzeichnet. Variablen einer Programmiersprache sind Verweise auf Speicherplätze, an denen sich zu unterschiedlichen Zeiten während des Programmablaufs unterschiedliche Werte oder Objekte befinden können – ähnlich wie Briefkästen, in denen sich Postkarten, Briefe oder Pakete mit jeweils unterschiedlichen Inhalten befinden. Das Lesen einer Variable entspricht hier einem Blick in den Briefkasten, das Schreiben entspricht einem Briefeinwurf. Variableninhalte können Zahlen, Texte, Dateinamen oder komplexere Objekte sein. Bei den Variablennamen wird in PHP – ebenso wie bei den Funktionsnamen – zwischen Groß- und Kleinschreibung unterschieden.
$text="Hallo Welt"; echo $Text; wird also nicht das Ergebnis »Hallo Welt« ausgeben, sondern gar nichts. Variablen werden bei der ersten Zuweisung initialisiert und sind vorher nicht definiert. Flash ActionScript dagegen berücksichtigt die Groß- und Kleinschreibung bei Schlüsselwörtern, nicht aber bei der Benennung von Variablen und Objekten. Die falsche Verwendung der Groß- und Kleinschreibung in PHP ist eine häufige Fehlerquelle. Die Wahl einer möglichst einheitlichen Syntax ist daher empfehlenswert. Bei der Zuweisung von Werten an Variablen wird in der bisher betrachteten Form eine Speicherstelle mit dem Variableninhalt belegt. Diese Art der Zuweisung ist eine Zuweisung »by value«. Der Wert wird in den Speicher geschrieben. Eine andere Art der Zuweisung ist die indirekte Zuweisung »by reference«. Hier wird ein Verweis auf eine bestehende Speicherstelle übergeben. Erkennbar ist die Zuweisung »by reference« an einem &-Zeichen rechts vom Gleichheitszeichen.
26
PHP-Grundlagen
1_02.fm Seite 27 Dienstag, 8. Oktober 2002 2:14 14
Im Beispiel unten wird die Variable $a wie bisher mit 100 initialisiert (»by value«). Die Anweisung $b=&$a; (»by reference«) bewirkt, dass die Variablen $b auf dieselbe Speicherstelle wie $a verweist. Die Ausgabe von $b zeigt dies an. Anschließend wird $b auf 200 gesetzt (»by value«). Nun hat auch $a den Wert 200.
Die Zuweisung »by reference« wird häufig bei der Übergabe von Funktionsparametern verwendet. Die Funktion ist damit in der Lage, auch Variablen in dem Programmteil zu modifizieren, der die Funktion aufgerufen hat. Je nach Inhalt der Variablen verwendet PHP folgende Datentypen, von denen die Art der internen Speicherung abhängt: 왘 integer: eine Ganzzahl zwischen –2147483647 und +2147483647. Eine Integer-Variable benötigt 4 Bytes an Speicherplatz. 왘 double: eine Fließkommazahl mit 8 Bytes Speicherplatz 왘 string: eine Zeichenkette mit variabler Länge 왘 boolean: ein logischer Wert WAHR oder FALSCH (seit PHP 4) 왘 array: eine Liste mit Variablen (Näheres auf Seite 44) 왘 object: ein Objekt (Näheres auf Seite 67) 왘 Der Variablentyp wird bei der Initialisierung festgelegt und bei Bedarf geändert.
Datentypen
Das Beispiel zeigt die Ausgabe
123 -> integer 1.23 -> double 123 -> string 1 -> boolean integer double
Boolesche Variablen
Die ersten vier Ausgabezeilen resultieren aus der Initialisierung der Variablen, die mit reinen Zahlen, mit Dezimalpunkt, mit Anführungszeichen und mit der Konstanten true vorgenommen wird. Eine boolesche Variable wird mit true oder false initialisiert. Die Funktion gettype($var) gibt den Variablentyp als Text zurück. Bei den unteren beiden Zeilen erfolgt eine Typumwandlung von integer nach double, da bei der Multiplikation eine Fließkommazahl verwendet wird. Boolesche Variablen werden als true oder false initialisiert. Die Ausgabe eines booleschen Wertes ergibt 1 für true und nichts für false. Um anstelle dieses »nichts« eine darstellbare Ausgabe zu erhalten, kann der Typ in eine Ganzzahl umgewandelt werden, die dann 0 oder 1 lautet:
28
PHP-Grundlagen
1_02.fm Seite 29 Dienstag, 8. Oktober 2002 2:14 14
In der Ausgabe wird der false-Wert nicht direkt als 0 angezeigt. Bei der Weiterverarbeitung zählt er aber als boolescher Wert false.
t f t f
-> 1 -> -> 1 -> 0
Eine Umwandlung mit den cast-Operatoren (integer), (double), (string), (array) und (boolean) ist jedoch nur in Ausnahmefällen erforderlich, da bei Bedarf eine automatische Typumwandlung stattfindet. Mit den Funktionen is_integer, is_string, is_boolean, is_array, is_object und is_string kann geprüft werden, ob eine Variable den jeweils abgefragten Typ aufweist. Das Ergebnis ist true oder false. Neben den Typprüfungen gibt es noch drei andere Prüfmöglichkeiten für die Art des Eintrags. 1. is_set(variable) prüft, ob eine Variable definiert wurde. Besonders bei der Übergabe von Variablen an das Skript ist diese Überprüfung wichtig. 2. is_empty(variable) prüft, ob die Variable leer ist. Eine integer- oder double-Variable ist leer, wenn sie 0 ist. Eine string-Variable ist leer, wenn sie eine leere Zeichenkette oder »0« ist. 3. is_numeric(variable) prüft, ob eine Variable eine Zahl oder ein numerischer String ist. Ein numerischer String ist eine Zeichenkette, der direkt einem Zahlenwert entspricht. Die Variable muss definiert sein. Das Beispiel ergibt für $v="0" in allen drei Prüfungen true (1), da die Variable definiert, leer (=0) und numerisch ist.
Variablen
29
1_02.fm Seite 30 Dienstag, 8. Oktober 2002 2:14 14
Die Ausgabe sieht so aus:
isset -> 1 empty -> 1 numeric -> 1 Die Definition von Zeichenketten kann auf drei Arten erfolgen: 왘 Eingeschlossen in einfachen Anführungszeichen
$text='Mein Name ist John.'; Das ist die einfachste Variante. Einfache Anführungszeichen sind meist besser lesbare als doppelte. 왘 Eingeschlossen in doppelten Anführungszeichen
$text="Mein Name ist $myname."; In dieser Form werden mit Dollarzeichen gekennzeichnete Variablen ausgewertet. 왘 Mit der so genannten Heredoc-Notation, bei der der Text mit drei Kleiner-Zeichen und einem beliebigen Bezeichner beginnt. Das Ende der Zeichenkette ist mit dem linksbündig stehenden Bezeichner und dem Semikolon erreicht.
$text=
32
PHP-Grundlagen
1_02.fm Seite 33 Dienstag, 8. Oktober 2002 2:14 14
Das Ergebnis für die Server-Variablen $_SERVER ist hier mit einer Erläuterung der häufig benötigten Variablen aufgeführt. In eckigen Klammern stehen Beispiele für die Variablen. 왘 DOCUMENT_ROOT: Anfangsverzeichnis des Servers [/homepages/2/htdocs/webserver]. 왘 HTTP_ACCEPT: Header der HTTP-Anfrage, falls vorhanden [*/*]. 왘 HTTP_ACCEPT_ENCODING: Header der HTTP-Anfrage, falls vorhanden [gzip, deflate]. 왘 HTTP_HOST: Header der HTTP-Anfrage, falls vorhanden [www.webserver.de]. 왘 HTTP_PRAGMA: Header der HTTP-Anfrage, falls vorhanden [no-cache]. 왘 HTTP_PROXY_CONNECTION: Header der HTTP-Anfrage, falls vorhanden [Keep-Alive]. 왘 HTTP_USER_AGENT: Informationen zum anfragenden Browser-Typ und Betriebssystem [Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)]. 왘 REDIRECT_STATUS: Die HTTP-Statusnummer, die gesendet werden wird [200]. 왘 REMOTE_ADDR: IP-Adresse der Anfrage [80.132.49.193]. 왘 REMOTE_PORT: Portnummer, die der User für die Anfrage benutzt [4295]. 왘 SERVER_ADDR: IP-Adresse des Servers [195.20.244.110]. 왘 SERVER_ADMIN: E-Mail-Adresse des Administrators [
[email protected]]. 왘 SERVER_NAME: Name des Webservers [webserver.de]. 왘 SERVER_PORT: Nummer des Ports, über den der Server die Anfrage erhält. Standard ist Portnummer 80. Für FTP und SSL werden andere Ports verwendet. 왘 SERVER_SOFTWARE: Die verwendete Server-Software mit Versionsnummer [Apache/1.3.26 (Unix)]. 왘 GATEWAY_INTERFACE: Die im Server benutzte CGI-Version [CGI/1.1]. 왘 SERVER_PROTOCOL: Protokollname und Version der Anfrage [HTTP/1.0]. 왘 REQUEST_METHOD: Methode der HTTP-Anfrage (GET, POST, o.Ä.). 왘 QUERY_STRING: Die Liste der GET-Variablen oder Parameter, falls vorhanden [ort=ötztal].
Globale Variablen in PHP
33
1_02.fm Seite 34 Dienstag, 8. Oktober 2002 2:14 14
왘
REQUEST_URI: Die URI, die für den Aufruf des Skripts verwendet wurde. Enthält auch die GET-Variablen. 왘 PATH_TRANSLATED: Vollständiger Pfad mit dem Skriptnamen im ServerDateisystem. 왘 PHP_SELF: Der Dateiname des momentan ausgeführten Skripts relativ zum Pfad DOCUMENT_ROOT [/fpmx/globals.php]. 왘 argv und argc: Array mit den an das Skript übergebenen Argumenten und die Anzahl dieser Argumente. Die $_ENV und die $_SERVER-Variablen überschneiden sich zum größten Teil. Nicht in den $_ENV-Variablen enthalten sind PHP_SELF, argv und argc. Allen diesen globalen Variablen übergeordnet ist $GLOBALS. Mit dem Funktionsaufruf listvars('$GLOBALS'); im oben aufgeführten Skript werden sämtliche global zugänglichen Variablen aufgelistet.
Konstanten Neben einigen vordefinierten Konstanten können in PHP zusätzliche Konstanten definiert werden. Mit dem Befehl
define (konstantenname, konstantenwert) wird die Konstante festgelegt. Die Typen von Konstanten werden wie bei Variablen automatisch festgelegt (integer, double, boolean, string). Das Beispiel listet die vordefinierten Konstanten auf und definiert noch eine weitere Konstante PGM_VERSION.
Die vordefinierten Konstanten sind: Konstante
Beispiel
Inhalt
PHP_VERSION
4.1.2
Zeichenkette mit der Versionsnummer des PHPInterpreters.
PHP_OS
WINNT
Name des Betriebssystems, auf dem der Interpreter läuft.
__FILE__
konstanten.php
Der Name der aktiven Skriptdatei.
__LINE__
127
Zeilennummer, die gerade verarbeitet wird. Es handelt sich hier nicht um eine Konstante im eigentlichen Sinn. Das Symbol für einen nicht festgelegten Wert.
NULL TRUE, true 1
Der logische Wert WAHR (1).
FALSE, false
0
Der logische Wert FALSCH (0).
E_ERROR
1
Fehlercode für einen schweren Fehler, der zum Abbruch der Skriptverarbeitung führt.
E_WARNING
2
Code für eine Warnung. Die Skriptverarbeitung läuft weiter.
E_PARSE
4
Syntaxfehler im Skript, Abbruch der Verarbeitung.
E_NOTICE
8
Hinweis zum Skript, Fortsetzung.
Funktionen und Funktionsparameter Der Begriff »Funktion« wurde bereits erwähnt. Damit ein Skript übersichtlich bleibt, werden häufiger benutzte Programmteile als Funktionen definiert, die aus anderen Programmteilen heraus aufgerufen werden können. An Funktionen können Parameter übergeben werden, von denen das Ergebnis der Funktion abhängt. Eine Funktion wird mit der return-Anweisung beendet, die einen Wert an den aufrufenden Programmteil zurückliefern kann.
Funktionen und Funktionsparameter
35
1_02.fm Seite 36 Dienstag, 8. Oktober 2002 2:14 14
PHP-Funktionen für mathematische Ausdrücke, Zeichenketten und Datumsangaben sind ab Seite 554 im Vergleich mit den entsprechenden Funktionen aus MySQL und ActionScript dargestellt. Die in PHP besonders wichtigen Array-Funktionen und reguläre Ausdrücke für Zeichenketten werden in eigenen Abschnitten weiter unten diskutiert. Wichtig im Zusammenhang mit Funktionen sind die Gültigkeitsbereiche von Variablen. Lokale Variablen werden in Funktionen definiert und gelten nur innerhalb der Funktion. Innerhalb einer Funktion kann nicht auf die Variablen des Hauptteils oder einer anderen Funktion zugegriffen werden. Globale Variablen werden im Hauptteil des Skripts definiert. In Funktionen können sie verwendet werden, indem dort eine Deklaration der Variablen als global erfolgt. Im folgenden Beispiel wird der Text nur ausgegeben, wenn die Variable $v in der Funktion anzeige als globale Variable definiert wurde.
Superglobale Variablen gelten überall im Skript. Bei den superglobals handelt es sich um vordefinierte Speicherstrukturen für die Skriptumgebung und die an das Skript übergebenen Parameter. Näheres zu diesen superglobalen Variablen findet sich auf Seite 30. Das Array $GLOBALS ist ein Array, das alle Variablen enthält, die global definierbar sind. Das vorige Beispiel funktioniert auch in der Form
Statische Variablen in Funktionen Wird eine Funktion mehrmals aufgerufen, werden lokale Variablen jedes Mal neu initialisiert. Möchte man anstelle der Neuinitialisierung die zuletzt verwendeten Werte nutzen, ist eine Definition als statische Variable notwendig. Statische Variablen sind beispielsweise für Zähler denkbar, die registrieren, wie oft eine Funktion aufgerufen wurde.
Dateien einbinden Teile eines PHP-Skripts können in separate Dateien ausgelagert werden. Damit ist es möglich, Funktionen, die in mehreren Skripts benutzt werden, immer wieder zu verwenden. Änderungen brauchen dann nur an einer Stelle vorgenommen zu werden. Das Programm lässt sich übersichtlicher verwalten. Auch wenn häufiger bestimmte Parameter geändert werden müssen, kann der Programmteil mit den Parametern ausgelagert werden. Dies empfiehlt sich zum Beispiel bei den Zugangsdaten für eine MySQL-Verbindung, die in verschiedenen Umgebungen getestet wird. Die Befehle include(dateiname) und require(dateiname) stehen als Platzhalter für den einzulesenden Code und laden die angegebenen Skriptdateien. Sie unterscheiden sich hinsichtlich des Ladezeitpunkts.
require(dateiname);
Statische Variablen in Funktionen
37
1_02.fm Seite 38 Dienstag, 8. Oktober 2002 2:14 14
wird nur einmal zu Beginn geladen. Das Hauptskript lädt zuerst die mit require eingebunden Dateien und analysiert sie. Sie müssen also allein stehend gültige PHP-Formatierungen aufweisen und PHP-Code in den entsprechenden Tags einschließen.
include(dateiname); wird erst dann geladen, wenn das Skript bei der Ausführung auf die include-Anweisung trifft. Dadurch ist es möglich, Code direkt aus dem Editor auszuschneiden und durch das include zu ersetzen. In einer Schleife würde ein include jedes Mal neu geladen. Das verschlechtert die Ausführungsgeschwindigkeit. Es ist daher sinnvoll, das Skript so zu strukturieren, dass ausgelagerte Dateien nur selten geladen werden müssen. Ein Beispiel für eine include-Anweisung ist in Kapitel 11 zu finden. Dort werden die Daten für die MySQL-Verbindung mit include geladen. Dies geschieht zu Beginn der Skriptausführung.
Programmstrukturen
if
Ein Programm wird Schritt für Schritt abgearbeitet. Damit auch komplexere Aufgaben lösbar sind, gibt es die Möglichkeit, abhängig von variablen Bedingungen Verzweigungen im Programmablauf einzuplanen. Zur Strukturierung des Ablaufs mit bedingten Verzweigungen gibt es in PHP verschiedene Konstruktionen. Eine einfache if-Bedingung hat die Form
if ([Ausdruck]) [Anweisung]
if...else
Dabei kann die Anweisung eine einzelne Anweisung oder eine in geschweifte Klammern eingeschlossene Reihe von Anweisungen (ein Anwendungsblock) sein. Der Ausdruck wird berechnet und geprüft, ob er logisch wahr ist. Falls ja, wird die anschließende Anweisung ausgeführt, falls nicht, wird diese übersprungen. Eine if-Bedingung mit einem alternativen Zweig hat die Form
if ([Ausdruck]) [Anweisung] else [Anweisung]
38
PHP-Grundlagen
1_02.fm Seite 39 Dienstag, 8. Oktober 2002 2:14 14
Die switch-Anweisung fasst mehrere ähnliche if-Bedingungen übersichtlich zusammen. Einfache Beispiele für diese Strukturen sind in der Tabelle weiter unten gezeigt. Schleifenstrukturen können einen Programmblock mehrfach durchlaufen. Die Anzahl der Wiederholungen kann fest oder variabel definiert werden und hängt von Bedingungen ab.
do...while...
while...do... continue
Anweisungen [continue;] [break;] continue
ja
whileBedingung erfüllt? break
nein
whileBedingung erfüllt?
ja
nein
Anweisungen [continue;] [break;] break
왖 Abbildung 1
Flussdiagramm für die do...while... und while...do...-Schleifen. Mit den optionalen continue- und break-Anweisungen wird der Anweisungsblock verlassen und zum Test der Bedingung oder ans Ende der Schleife gesprungen.
Die while-Schleife prüft zunächst eine Testbedingung. Ist diese Testbedingung erfüllt, wird ein Anweisungsblock durchlaufen. Anschließend wird die Bedingung erneut geprüft.
while
while ( [Ausdruck] ) [Anweisung] Im Beispiel unten wird mithilfe des newtonschen Iterationsverfahrens die Quadratwurzel aus einer Zahl näherungsweise berechnet. Bei jedem Schleifendurchlauf wird anfangs geprüft, ob das Quadrat der Wurzel bereits in hinreichender Nähe zur Zahl liegt, hier 1e-12. Ist das Ergebnis noch nicht genau genug, wird mit der Formel w=(w+z/w)/2 die nächste Iteration berechnet.
Programmstrukturen
39
1_02.fm Seite 40 Dienstag, 8. Oktober 2002 2:14 14
Die Ausgabe zeigt eine immer bessere Näherung an die Quadratwurzel der Zahl 10:
3.5 3.1785714285714 3.1623194221509 3.1622776604441 3.1622776601684 do...while
Eine Abwandlung der while-Schleife stellt die do ... while-Schleife dar. Hier wird zunächst ein Anweisungsblock abgearbeitet und dann eine Testbedingung geprüft. Ist diese Bedingung erfüllt, wird der Block erneut abgearbeitet. Bei beiden Varianten wird eine Problematik von Schleifen deutlich: Falls die Testbedingung immer erfüllt ist und kein Abbruch des Ablaufs innerhalb der Schleife erfolgt, liegt eine Endlosschleife vor, die nicht mehr verlassen wird und die das Programm oder den Rechner leicht zum Absturz bringen kann.
while (1) { echo "das hat kein Ende"; } for
Die for-Schleife fasst Initialisierungsanweisungen, Testbedingungen und Iterationsanweisungen zusammen.
for (Initialisierung; Bedingung; Iteration) [Anweisung] Mit der Schleife unten werden die Monate eines Jahres mit der Anzahl der Tage im Monat ausgegeben.
40
PHP-Grundlagen
1_02.fm Seite 41 Dienstag, 8. Oktober 2002 2:14 14
Das Ergebnis sieht so aus:
31 January 29 February 31 March ... 31 December Diese Schleife könnte auch mithilfe einer while-Schleife realisiert werden:
$i=1; while ($i array('Planet'=>'Erde' ,'Bahnradius'=>364083 ), 'Phobos' => array('Planet'=>'Mars' ,'Bahnradius'=>6180 ), 'Deimos' => array('Planet'=>'Mars' ,'Bahnradius'=>23500 ), Arrays
47
1_02.fm Seite 48 Dienstag, 8. Oktober 2002 2:14 14
'Io'
=> array('Planet'=>'Jupiter' ,'Bahnradius'=>421600) );
Die Array-Elemente werden mit den Schlüsselwerten ausgelesen:
echo "".$daten['Io']['Planet']; → Jupiter In den folgenden Abschnitten werden die wichtigsten Array-Funktionen gruppenweise zusammengestellt.
Sortierfunktionen Für die Sortierung von Arrays stehen neun Funktionen zur Verfügung. Sortiert werden kann vorwärts, rückwärts oder mithilfe einer individuell festgelegten Funktion. Für einfache Arrays, Schlüssel von assoziativen Arrays und Inhalte von assoziativen Arrays werden unterschiedliche Funktionen verwendet. vorwärts
rückwärts
funktionsabhängig
einfaches Array
sort($arr)
rsort($arr)
usort($arr, f)
assoziatives Array (Schlüssel)
ksort($arr) krsort($arr)
uksort($arr, f)
assoziatives Array (Inhalt)
asort($arr) arsort($arr)
uasort($arr, f)
Für die Sortierung mehrdimensionaler Arrays kann die Funktion array_ multisort verwendet werden, mit der für verschiedeneArray-Felder unterschiedliche Sortierschlüssel und Sortierrichtungen festgelegt werden können. natsort und natcasesort werden wie sort($arr) aufgerufen, verwenden aber einen anderen Sortieralgorithmus. natcasesort sortiert ohne Berücksichtigung der Groß- und Kleinschreibung. Der Algorithmus sortiert Zahlen entsprechend ihrem gesamten Zahlenwert, sodass 34 Das Resultat sieht so aus: 왘 왘
Merge A B C F C D E F G ($a1 und $a2 hintereinander gereiht) Plus A B C F G (überstehende Elemente aus $a2 werden an $a1 angefügt)
왘 왘
Diff A B (Elemente aus $a1, die in $a2 nicht vorhanden sind) Intersect C F (Elemente, die in beiden Arrays vorhanden sind)
Um mehrfach vorhandene Werte im Array zu entfernen, kann die Funktion array_unique verwendet werden:
Das Ergebnis enthält die unsortierten einzelnen Werte:
Unique B F A C array_chunk zerlegt ein Array in kleinere Arrays. Die kleineren Arrays ihrerseits sind Elemente eines Arrays, das von array_chunk zurückgegeben wird.
Arrays
51
1_02.fm Seite 52 Dienstag, 8. Oktober 2002 2:14 14
$chunks=array_chunk($arr, $laenge, $flagKeys) array_fill (ab PHP 4.2.0) und array_pad füllen Arrays mit Werten. array_fill($startindex, $n, $wert) erzeugt dabei ein neues Array, während array_pad($arr, $n, $wert) ein Array auf eine bestimmte Länge erweitert. Bei der Erweiterung wird das Array so lange verlängert, bis die Anzahl der Elemente $n erreicht. Der Wert wird für positives $n rechts, für negatives links eingefügt.
Ausgabe:
Pad rechts A B Y Y Y Pad links X X X A B Y Y Y Andere Funktionen in_array($wert,$arr) prüft, ob ein Wert in einem Array enthalten ist. array_rand($arr,$n) gibt für $n=1 einen zufällig ausgewählten Indexwert zurück. Für größere Werte von $n wird ein Array mit zufällig ausgewählten Indexen zurückgegeben. Die Initialisierung des Zufallsgenerators sollte am Anfang des Skripts vorgenommen werden. array_sum($arr) bildet die Summe über die Indexwerte. Zeichenketten werden dabei ignoriert.
$arr=array('11','45','12','17','3'); echo 'in_array '.in_array('45',$arr); echo 'rand 1 '.array_rand($arr,1); echo 'rand 2 '.join(' ',array_rand($arr,2)); echo 'sum '.array_sum($arr);
52
PHP-Grundlagen
1_02.fm Seite 53 Dienstag, 8. Oktober 2002 2:14 14
Die Funktionen array_filter, array_map, array_reduce und array_walk verwenden Verweise auf andere Funktionen, mithilfe derer ein Array bearbeitet werden kann. array_filter Aus dem Array mit den Werten 1,2,3,4,5,6,7,8,9 sollen alle ungeraden Zahlen entfernt werden. Dies geschieht mit array_filter:
$arr=array(1,2,3,4,5,6,7,8,9); function ungerade($i) { return ($i%2 ==0); } echo 'filter '.join(' ',array_filter($arr, 'ungerade')); Ergebnis:
filter 2 4 6 8 array_map Aus dem Array soll ein anderes Array mit den Quadraten der Zahlen erzeugt werden. Die array_map-Funktion bildet ein Array in ein anderes ab:
$arr=array(1,2,3,4,5,6,7,8,9); function quad($i) { return $i*$i; } echo 'map '.join(' ',array_map('quad',$arr)); Ergebnis:
map 1 4 9 16 25 36 49 64 81 Auch mehrere Arrays als Argumente für array_map und eine map-Funktion mit entsprechend mehreren Parametern sind möglich. array_walk
array_walk durchläuft das Array und ruft für alle Elemente eine Funktion auf. Die Funktion kann die Elemente verändern, wenn der Wert »by reference« übergeben wird (hierfür dient das &-Zeichen vor der Variablen):
Arrays
53
1_02.fm Seite 54 Dienstag, 8. Oktober 2002 2:14 14
$arr=array(1,2,3,4,5,6,7,8,9); function quadwalk(&$i) { $i=$i*$i*$i; } reset($arr); array_walk($arr,'quadwalk'); echo 'walk '.join(' ',$arr); Ergebnis:
walk 1 8 27 64 125 216 343 512 729 compact compact sammelt einzelne Variablen in ein assoziatives Array. extract
extract erzeugt umgekehrt aus einem assoziativen Array einzelne Variablen, wobei es zum Schutz bestehender Variablen Flags gibt, die das Verhalten der Funktion bestimmen, wenn Namenskonflikte auftreten. list
list ordnet den Elementen eines einfachen Arrays Variablen zu. list($a,$b,$c)=array(1,2,3); echo $a."-".$b."-".$c; Ergebnis:
1-2-3 range($von, $bis)
range($von, $bis) baut ein Array aus Zahlen in einem vorgegebenen Bereich auf. shuffle($arr)
shuffle($arr) mischt die Elemente in einem Array zufällig. Die Zufallsverteilung ist nicht sehr gut. Für eine bessere Verteilung sollten andere Möglichkeiten genutzt werden. Das Beispiel baut ein Array mit den Zahlen 10 bis 20 auf und mischt es zweimal. Die Array-Werte werden mit join in eine Zeichenkette umge-
54
PHP-Grundlagen
1_02.fm Seite 55 Dienstag, 8. Oktober 2002 2:14 14
wandelt und ausgegeben. Betrachtet man einige Mischergebnisse, sieht man bald, dass keine wirklich zufällige Mischung entsteht.
Ausgabe:
10 11 12 13 14 15 16 17 18 19 20 10 12 18 13 11 14 15 20 16 17 19 11 14 20 18 13 15 10 12 17 16 19
Reguläre Ausdrücke Was sind reguläre Ausdrücke? Bei den Textfunktionen gibt es verschiedene Funktionen für einfache Such- und Ersetzungsfunktionen in Zeichenketten (die Funktionen sind im Anhang ab Seite 554 im Vergleich mit ActionScript und MySQL gezeigt). Für viele Aufgaben reichen die einfachen Suchmuster aber nicht aus, mit denen fest definierte Zeichenketten-Bestandteile gesucht werden. Häufig sind Ersetzungen verlangt, die auf nur teilweise bekannten Suchmustern basieren. Besonders in HTML-Schablonen ist die Verwendung von solchen Suchmustern sinnvoll, wenn beispielsweise die Inhalte von Tags ersetzt werden sollen. Platzhalter ersetzen dann die variablen Textpositionen. Mit regulären Ausdrücken lassen sich komplexe Aufgaben mit Zeichenketten kompakt lösen. Für viele Aufgaben wäre ohne Verwendung von regulären Ausdrücken eine umfangreiche Programmierung erforderlich. Diese Programmierung wird ersetzt durch die Definition und Auswertung von Mustern.
Reguläre Ausdrücke
55
1_02.fm Seite 56 Dienstag, 8. Oktober 2002 2:14 14
Der Name PHP Hypertext Preprozessor, abgekürzt PHP, zeigt bereits an, dass die Sprache für die Verarbeitung von Texten und Hypertexten geeignet ist. Viele mit PHP zu lösende Aufgaben spielen sich im HTML-Umfeld ab, beispielsweise die Generierung von Tabellen. Neben den ursprünglich in PHP vorhanden Funktionen für reguläre Ausdrücke gibt es die Perl-kompatiblen Funktionen für reguläre Ausdrücke. Für den Einsatz dieser Funktionen ist die Aktivierung des PHPModuls PCRE (Perl Compatible Regular Expressions) erforderlich. Die Aktivierung ist mittlerweile Standard. Dieses Modul ist moderner, arbeitet schneller und hat einige zusätzliche Möglichkeiten. Die Syntax für Such- und Ersetzungsmuster ist aber eine etwas andere. Im Folgenden werden zuerst die älteren und dann ausführlicher die Perl-kompatiblen Funktionen gezeigt.
Standardfunktionen Generell gibt es bei den mit regulären Ausdrücken operierenden Funktionen zwei Varianten. Die erste Variante prüft, ob ein Ausdruck in einem String enthalten ist, die andere ersetzt das Vorkommen des Ausdrucks durch einen anderen. Die Suche mit dem Suchmuster 53..9 findet zum Beispiel alle Texte, die Zeichenketten wie 53229, 53009 oder 53xx9 enthalten, nicht aber 53228. Der Punkt steht im Suchmuster als Platzhalter für ein beliebiges Zeichen.
Die umfangreichen Möglichkeiten haben ihren Preis in einem recht hohen Zeitaufwand für die Bearbeitung. Deshalb sollten reguläre Ausdrücke nur dort eingesetzt werden, wo die Standard-Zeichenketten-Funktionen (str_pos, str_replace usw.) nicht ausreichen. Hier ein etwas erweitertes Beispiel für die Suche, in dem die Suchmuster und Suchtexte in Variablen übergeben werden:
Ausgehend von einem Array mit den Planetennamen rufen wir die Funktion untersuche auf, die jedes Wort in dem Array mit einem Suchmuster vergleicht. Passt das Wort zum Suchmuster, wird es ausgegeben. Wesentlich ist die Funktion ereg($Muster,$Wort). Die beiden Muster n bzw. ur führen zu folgendem Ergebnis:
Muster: n findet Venus Saturn Uranus Neptun Muster: ur findet Merkur Saturn n findet alle Planeten mit einem n. Neptun wird gefunden, weil ein n am Ende steht, nicht wegen des N am Anfang. ereg unterscheidet zwischen Groß- und Kleinschreibung. ur findet daher Merkur und Saturn, nicht Uranus. Wird anstelle von ereg die hinsichtlich Groß- und Kleinschreibung nicht unterscheidende Funktion eregi benutzt, sieht das Ergebnis so aus;
Muster: ur findet Merkur Saturn Uranus Muster: n findet Venus Saturn Uranus Neptun Folgende Funktionen stehen für herkömmliche reguläre Ausdrücke zur Verfügung: 왘 ereg: Sucht in einem Text nach einem Muster 왘 ereg_replace: Ersetzt in einem Text ein Muster mit einem Ersatz 왘 split: Wirkt ähnlich wie explode und teilt einen Text in ein Array von Texten auf, wobei im Suchmuster alle Separatoren enthalten sind. 왘 eregi, eregi_replace und spliti reagieren wie die anderen Funktionen, aber ohne Berücksichtigung von Groß- und Kleinschreibung. Reguläre Ausdrücke
57
1_02.fm Seite 58 Dienstag, 8. Oktober 2002 2:14 14
Schneller und vielseitiger als diese Funktionen sind aber die im nächsten Abschnitt beschriebenen Perl-kompatiblen Ausdrücke und Funktionen. Da sie insbesondere bei den Suchzeichen mit Sonderfunktionen eine andere Syntax haben, sollte man sich nach Möglichkeit auf diese Ausdrücke konzentrieren und die hier genannten Funktionen nur verwenden, wenn die Perl-Funktionen nicht zur Verfügung stehen.
Perl-kompatible reguläre Ausdrücke Suchmuster werden bei Perl-kompatiblen regulären Ausdrücken in Schrägzeichen eingeschlossen. Das Muster '/
/' findet alle Textstellen, die | enthalten. Zur Suche von Sonderzeichen und Zeichen, die eine besondere Bedeutung als Suchmuster haben, werden diese mit einem Backslash versehen. Das Muster '//' findet alle Textstellen, die | enthalten. Die folgende Tabelle stellt die Zeichen und Ausdrücke mit einer besonderen Aufgabe zusammen. Für die Suche gibt es verschiedene durch Buchstaben gekennzeichnete Suchoptionen, die weiter unten beschrieben sind. Zeichen
Bedeutung
\
Zeigt ein nachfolgendes Sonderzeichen an
.
Ein Punkt. Platzhalter für jedes beliebige Zeichen außer dem Zeilenwechsel (Option s, PCRE_DOTALL, beachten)
^
Prüft Übereinstimmung ab Beginn der Zeichenkette (Option m, PCRE_
MULTILINE, beachten $
58
Prüft Übereinstimmung am Ende der Zeichenkette (Option m, PCRE_
MULTILINEbeachten)
*
Beliebig viele Wiederholungen des vorangegangenen Zeichens
+
Das voranstehende Zeichen muss mindestens einmal auftreten
?
Das voranstehende Zeichen darf höchstens einmal auftreten
{min,max}
Genauere Festlegung der Wiederholungen: Mindestanzahl und Maximalanzahl
[....]
Liste mit möglichen Zeichen
(...)
Gruppierung eines Ausdrucks
|
Oder
PHP-Grundlagen
1_02.fm Seite 59 Dienstag, 8. Oktober 2002 2:14 14
Besondere Zeichenklassen Zeichen können in Gruppen zusammengefasst werden. Die Gruppe [0123456789] oder kurz gefasst [0-9] als Suchmuster sucht nach irgendeiner der Ziffern in der zu durchsuchenden Zeichenkette. Die folgenden Gruppen können durch Zeichenklassen ersetzt werden: Zeichenklasse
Schreibweise als Gruppe
Inhalt
\d
[0-9]
Dezimalziffer
\D
[^0-9]
keine Dezimalziffer
\w
[0-9_A-Za-z]
Ziffern, Buchstaben, Unterstrich
\W
[^0-9_A-Za-z]
Umkehrung von \w
\s
[\n\r\t\f ]
Whitespace (unsichtbare Zeichen und Leerzeichen)
\S
[^\n\r\t\f ]
kein Whitespace
Die Zeichenklassen können auch innerhalb von Gruppen verwendet werden. [/dA-Fa-f] kann als Muster für Hexadezimalzahlen verwendet werden. Mit dem bisher beschriebene können die Suchmuster aufgebaut werden. Die Funktionen, in denen sie zum Einsatz kommen, sind die Folgenden. preg_match
int preg_match($muster,$text[,$matcharray[,$flagOffset]]); Prüft die Vorkommen des Suchmusters im Text und gibt 0 zurück (keine Übereinstimmung) oder 1 (gefunden, Suche wird nicht fortgesetzt). Im optionalen $matcharray werden die Suchgruppen gespeichert, wobei der erste Eintrag das vollständige Muster enthält und die weiteren die aus den mit runden Klammern eingeschlossen Suchmustergruppen extrahierten Werte. $flagOffset ist in PHP 4.3.0 neu und bewirkt, dass zusätzlich zu den im matcharray enthaltenen Elementen ihre Anfangsposition gespeichert wird. preg_match_all
int preg_match_all($muster,$text,$matcharray[,$flags]]);
Reguläre Ausdrücke
59
1_02.fm Seite 60 Dienstag, 8. Oktober 2002 2:14 14
Schreibt alle Vorkommen des Musters in ein Array und gibt die Gesamtzahl der Treffer zurück, 0 bei nicht gefundenem Muster und FALSE bei Fehlern. Für die Flags sind folgende Konstanten vorgesehen: 왘 PREG_PATTERN_ORDER: Das Array ist ein Array mit Unterarrays, die so wie bei preg_match aufgebaut sind. Es kann als zweidimensionales Array behandelt werden. 왘 PREG_SET_ORDER: Vertauscht die Zeilen und Spalten gegenüber PREG_ 왘
PATTERN_ORDER PREG_OFFSET_CAPTURE (ab PHP 4.3.0): Anstelle der Inhalte der Treffer werden Arrays mit dem Inhalt und der Offset-Position im Text zurückgegeben.
preg_grep
array preg_grep($muster,$textarray); Schreibt in das resultierende Array alle Werte aus dem Textarray, für das die Suchbedingung erfüllt ist. preg_replace
preg_replace($muster, $ersatz, $text [, $anzahl]) Ersetzt die im Text gefundenen Suchmuster durch einen Ersatz. Die Suche wird solange fortgesetzt, bis der Text durchlaufen ist oder die im optionalen Parameter $anzahl angegebene Maximalzahl von Ersetzungen vorgenommen wurde. preg_quote
string preg_quote($rohmuster,$begrenzer) Ersetzt in einem Text, der als Suchmuster verwendet werden soll, alle Zeichen, die im Suchmuster Spezialfunktionen haben durch Escape-Sequenzen. Der Begrenzer sollte als »/« angegeben werden, damit auch dieses Zeichen ersetzt wird und nicht das Ende des Suchmusters markiert.
60
PHP-Grundlagen
1_02.fm Seite 61 Dienstag, 8. Oktober 2002 2:14 14
Suchoptionen Das Verhalten der PCRE-Funktionen kann durch die Einstellung von Optionen modifiziert werden. Die Optionen werden an das Suchmuster angehängt. Das Muster /text/ findet nur text in Kleinschreibung, /text/i findet TEXT, Text und text. In der folgenden Tabelle sind die Optionen aufgelistet. Vorsicht: Großbuchstaben und Kleinbuchstaben stehen teilweise für unterschiedliche Optionen. Option PCRE-Konstante
Funktionsweise
i
PCRE_CASELESS
Keine Unterscheidung von Groß- und Kleinschreibung
m
PCRE_MULTILINE
Zeichenketten mit Zeilenumbrüchen werden bei aktivierter Option m ausgewertet, als sei jede Zeile eine vollständige Zeichenkette. Die Muster ^ für Zeilenanfang und $ für Zeilenende werden dann mehrfach ausgewertet.
s
PCRE_DOTALL
Mit dieser Option wird auch der Zeilenumbruch \n vom Punkt-Suchmuster erfasst.
x
PCRE_EXTENDED
Mit dieser Option werden Lücken (Leerzeichen, Zeilenumbrüche) im Suchmuster ignoriert.
e
-
Nur bei preg_replace(): Die Ersatzzeichen werden als PHP-Code interpretiert. Ist $i=10, so wird der Ersatz mit "$i*2" ohne Option 10*2, mit der Option 20.
A
PCRE_ANCHORED
Suche beginnt am Zeichenketten-Beginn. Besser mit dem Suchmuster ^ realisierbar.
S
-
Optimierung der Ausführungsgeschwindigkeit. Sinnvoll, wenn das Muster mehrfach verwendet wird.
U
PCRE_UNGREEDY
Suchmuster verhalten sich nicht »greedy« (s.u.)
X
PCRE_EXTRA
Erkennt falsch gesetzte Backslashes in einem Suchmuster.
u
PCRE_UTF8
Muster werden UTF-8 kodiert.
Greedy-Suchen Greedy (dt: gierig) verhält sich der Such- und Ersetzungsalgorithmus, wenn er für Platzhalter mit beliebiger Länge das längstmögliche Ergebnis auswählt. Wenn in der Zeichenkette »paprika und peperoni« als Suchmuster der Text zwischen p und r eingegeben wird und dieses Muster durch pir ersetzt werden soll, ergeben sich eventuell unerwartete Resultate:
Das Muster /p.*r/ bedeutet: Suche nach einem p, dann nach beliebig vielen anderen Zeichen und nach einem r. Zunächst erhält man als Ergebnis
pironi PHP verhält sich »greedy« und ersetzt den Text zwischen dem ersten p und dem letzten r. Mit der Option U (Ungreedy) ist das Ergebnis anders:
$muster="/p.*r/U"; echo preg_replace($muster, $ersatz, $str); Man erhält
pirika und pironi Warum aber lautet das Ergebnis nicht papirika und pepironi? Die Suche beginnt links und findet ein p. Die weiteren Zeichen sind beliebig, solange, bis ein r auftritt. Also wird aus papr pir, ebenso wie aus peper. Um das mittlere p auszuschließen, kann statt die beliebigen, durch .* bemusterten Zeichens der Ausdruck [^p]* verwendet werden, der alles sucht, was kein p enthält. Die Suche beginnt wieder links, stößt aber dann auf das zweite p und wird abgebrochen und mit dem zweiten p neu gestartet. Code:
$muster="/p[^p]*r/"; echo preg_replace($muster, $ersatz, $str); Ergebnis:
papirika und pepironi
62
PHP-Grundlagen
1_02.fm Seite 63 Dienstag, 8. Oktober 2002 2:14 14
Als letzte Variante noch ein Suchmuster mit dem Pluszeichen. Das Pluszeichen erwartet mindestens ein Zeichen, sodass pr nicht zu pir wird.
$muster="/p[^p]+r/"; echo "".preg_replace($muster, $ersatz, $str); paprika und pepironi Auf einen Blick noch mal die Suchmuster und die Resultate. Bei den Varianten mit dem ausgeschlossenen p ist die ungreedy-Option in diesem Fall unerheblich, da nach den zwischendurch gefundenen p die Suche beendet wird.
$muster="/p.*r/"; $muster="/p.*r/U"; $muster="/p[^p]*r/"; $muster="/p[^p]*rU/"; $muster="/p[^p]+r/"; $muster="/p[^p]+rU/";
pironi pirika und pironi papirika und pepironi papirika und pepironi paprika und pepironi paprika und pepironi
Die regulären Ausdrücke sind oft verwirrend. Oft ist es günstiger, eine Umwandlung zuverlässig in zwei Schritten durchzuführen, als einen extrem komplexen Ausdruck aufzubauen, dessen Funktion man bereits nach einem Tag nicht mehr nachvollziehen kann.
Beispiel: HTML-Tabelle mit Städten Eine Zeichenkette enthält eine HTML-Tabelle mit Städtenamen und Telefonvorwahlen, umschlossen von einem dünnen Rand:
$str='
Heidelberg | 06221 |
Mannheim | 0621 |
Frankfurt | 069 |
'; Die Zeichenkette ist in einfache Anführungszeichen eingeschlossen. Deshalb können innerhalb der Anführungszeichen doppelte Anführungszeichen verwendet werden. Diese Schreibweise ist für reines HTML übersichtlicher als Reguläre Ausdrücke
63
1_02.fm Seite 64 Dienstag, 8. Oktober 2002 2:14 14
$str=" verwendet, der die komplette Tabellenzeile entfernt. Die Färbung aller Städtenamen in Rot ist etwas schwieriger. Im Ergebnis müssen die einzelnen Tabellenzeilen so aussehen:
.. | .. |
64
PHP-Grundlagen
1_02.fm Seite 65 Dienstag, 8. Oktober 2002 2:14 14
Hier muss um den Tag-Inhalt ein weiterer Tag geschrieben werden. Die runden Klammern im Suchmuster markieren eine Gruppe, deren aktueller Inhalt bei der Ersetzung wiederverwendet werden kann. Als Platzhalter im Ersetzungsmuster steht hier \\1. Auf diese Weise kann auch auf andere Gruppen Bezug genommen werden: \\n steht für die n-te Gruppe. Die zweite Gruppe dient als Bedingung, markiert durch ?=. Sie verlangt, dass eine zweite Tabellenspalte folgt, wird aber nicht ausgegeben. Als Suchmuster verwenden wir
$muster="/
(.*)(?= | )/U"; und als Ersetzungstext $ersatz=" | \\1 | "; Die Ersetzung erfolgt dann mit der Funktion preg_replace:
echo preg_replace($muster, $ersatz,$str); Filtern von externen Links aus einer HTML-Seite Wie effizient es sich mit regulären Ausdrücken und Arrays programmieren lässt, zeigt das folgende Beispiel. Ziel ist es, aus einer HTML-Seite die externen Links herauszufiltern. Externe Links haben die Form href="http://zieldeslinks". Das Suchmuster muss auf die Begriffe href und http reagieren, für das Ziel des Links aber ein variables Muster enthalten. Verwenden wir zu Übungszwecken irgendeine Seite aus dem Internet, die externe Links aufweist, z.B. www.spiegel.de, und speichern Sie die HTML-Seite unter test.htm ab. Wie ein direkter Zugriff mit PHP auf HTTPoder FTP-Inhalte erfolgt, ist ab Seite 86 beschrieben. Mit den Programmzeilen
$dateiname="test.htm"; $fp=fopen($dateiname,"r"); $html = fread ($fp, filesize ($dateiname)); wird die Datei eingelesen. fopen öffnet die Datei im Lesemodus und liefert ein Datei-Handle. Der Befehl fread liest aus der Datei eine
Reguläre Ausdrücke
65
1_02.fm Seite 66 Dienstag, 8. Oktober 2002 2:14 14
bestimmte Anzahl von Bytes. Hier wird die filesize-Funktion verwendet, um die Dateilänge zu bestimmen. Die Variable $html beinhaltet nun Datei als Zeichenkette. Der Programmteil
$muster="/href=\"(http:\/\/.*)\"/U"; preg_match_all ( $muster, $html, $ergebnis); führt nun die eigentliche Arbeit aus. Das Suchmuster steht zwischen Schrägstrichen, die Option U dahinter aktiviert das Greedy-Suchen. Gesucht wird nach dem Muster href=\"(http:\/\/.*)\". Die runden Gruppierungsklammern enthalten das Muster (http:\/\/.*) für das Ziel des Links in der Form http://www.irgendwo.de. Vor und nach dem Ziel muss href=" bzw. ein Anführungszeichen als Abschluss stehen. Die Funktion preg_match_all durchsucht die Zeichenkette $html nach allen Vorkommen des Suchmusters. Jeder Treffer wird in das Array $ergebnis gespeichert. Dieses Array besteht am Ende aus zwei Arrays. Das erste Array $ergebnis[0] speichert die Treffer des vollständigen Suchmusters. Das zweite Array $ergebnis[1] nimmt die Ergebnisse der ersten Gruppe des Musters auf. Dadurch sparen wir die erneute Zerlegung des Treffers in die eigentliche Adresse des Links. Das Array wird sortiert, dann mit implode in eine durch HTML-Zeilentrenner separierte Zeichenkette umgewandelt und anschließend ausgegeben.
sort($ergebnis[1]); $ausgabe=implode($ergebnis[1], ""); echo $ausgabe; Das Ergebnis ist eine sortierte Liste der auf der Seite vorhandenen externen Links.
... http://boerse.spiegel.de/kl.asp?std_id=65 http://spiegel.parship.de/ http://www.donnerwetter.de http://www.manager-magazin.de/ ...
66
PHP-Grundlagen
1_02.fm Seite 67 Dienstag, 8. Oktober 2002 2:14 14
Zwei Erweiterungen ermöglichen eine Verbesserung des Skripts. Zum einen könnten bestimmte Links ausgeschlossen werden. Im Spiegel-Beispiel tauchen eine Menge Links auf, die über einen Adserver zur Registrierung von Werbeklicks umgeleitet werden. Diese Links beginnen mit adserv. Um diese Links aus der Liste herauszunehmen, verwenden wir im Suchmuster anstelle von .* den Ausdruck [^adserv].*) und prüfen damit, ob der variable Teil mit dem Text adserv beginnt. Außerdem möchten wir vielleicht mehrfache Ausgaben vermeiden. Dazu ersetzen wir den letzten Teil durch das Skript
sort($ergebnis[1]); $hrefAlt=""; foreach ($ergebnis[1] as $href) { if ($hrefAlt!=$href) echo $href.""; $hrefAlt=$href; } Hier verwenden wir die foreach-Schleife für den Array-Zugriff. Bei jedem Array-Element prüfen wir, ob das Element bereits ausgegeben wurde. Falls nicht, wird es ausgegeben. Dies funktioniert natürlich nur, weil das Array vorher sortiert wurde.
Objekte Objektorientiertes Programmieren ist der Versuch, ein Programm systematisch in kleine, unabhängige Elemente aufzuteilen. Jedes Element wird dabei als Einheit mit bestimmten Eigenschaften und Möglichkeiten gesehen, die mit den anderen Elementen kommuniziert. Wichtige Begriffe für die objektorientierte Programmierung sind: 왘 Klasse oder Objektklasse: Die abstrakte Definition eines Objektes, in der festgelegt ist, welche Eigenschaften und Methoden ein Objekt hat. Ein Objekt ist häufig die Modellierung eines natürlichen Gegenstandes, dessen Verhalten im Programm abgebildet werden soll. Außerdem wird in der Klassendefinition ein so genannter Konstruktor festgelegt, der aufgerufen wird, wenn von einem Objekt eine Instanz angelegt wird.
Objekte
67
1_02.fm Seite 68 Dienstag, 8. Oktober 2002 2:14 14
왘 왘 왘
왘
왘 왘 왘
왘
왘
68
Falls die Klasse von einer anderen Klasse abgeleitet wird, spricht man von Vererbung. Alle Eigenschaften und Methoden der ursprünglichen Klasse (Superklasse) werden von der abgeleiteten Klasse (Subklasse) übernommen. Sie erben diese Eigenschaften und Methoden, können diese aber neu definieren oder variieren (überlagern). Methode: In einem Objekt enthaltene Funktion, die das objektspezifische Verhalten definiert. Eigenschaft: In einem Objekt enthaltenes Element. Die meisten Eigenschaften sind Variablen, die das Objekt beschreiben. Konstruktor: Funktion oder Methode, die bei der Initialisierung eines Objektes aufgerufen werden. Initialisiert wird ein Objekt, wenn eine neue Instanz eines Objektes gebildet wird. Instanz oder Objektinstanz: Klassen, Methoden, Eigenschaften und Konstruktoren bilden den Rahmen, der ein Objekt definiert. Sie stellen einen Bauplan dar, der aber noch nicht ausgeführt ist. Erst mit der Erstellung einer Objektinstanz wird ein Objekt angelegt oder instantiiert und dabei Speicherplatz für das Objekt belegt. Um eine Instanz zu erstellen, wird in fast allen Programmiersprachen der new-Operator verwendet. Superklasse: Klasse, deren Eigenschaften und Methoden von einer Subklasse übernommen weden. Subklasse: Klasse, die alle Eigenschaften und Methoden von einer Superklasse übernimmt. Vererbung: Automatische Übernahme der Eigenschaften und Methoden einer Superklasse in eine Subklasse. Dadurch brauchen die bereits vorhandenen Möglichkeiten nicht nochmals programmiert zu werden, jedoch können sie erweitert werden. Überlagerung: Ersetzung einer von einer Superklasse geerbten Methode durch eine Neudefinition dieser Methode innerhalb der Subklasse. Dadurch entsteht ein polymorphes Verhalten der Methoden. Je nach Kontext arbeitet eine Methode intern anders, wird aber von außen gleich verwendet. Kapselung: Alle Eigenschaften und Fähigkeiten eines Objekts sind im Programmcode dieses Objektes enthalten. Der Code kann in vielen Programmiersprachen so gegenüber anderen Objekten abgeschlossen werden, dass nur bestimmte, bewusst freigegebene Eigenschaften direkt verfügbar sind.
PHP-Grundlagen
1_02.fm Seite 69 Dienstag, 8. Oktober 2002 2:14 14
왘 Mehrfachvererbung: Ein Konzept, bei dem Objekte Methoden und
Eigenschaften von mehreren anderen Objekten übernehmen und dadurch erweitern. Ein beliebtes Beispiel sind Amphibienfahrzeuge: Diese erben ihre Eigenschaften sowohl von Schiffen als auch von Autos. Eine Schwierigkeit hierbei sind Namenskonflikte. Mehrfachvererbung wird hauptsächlich bei C++ verwendet, in PHP, ActionScript, Java und C# ist sie nicht vorgesehen. Das alles klingt sehr theoretisch und ist beim Einstieg schwer verständlich. Ich habe bei einem C++-Objekt die Syntax noch nie auf einen Blick verstanden. Das ist eine andere Gedankenwelt. Donald E. Knuth, c't 5/2002.
Klassen und Objekte in PHP Zur Verdeutlichung dient hier ein klassisches Beispiel: das Automobil. Ein Automobil soll als Objekt dargestellt werden. Dabei ist es uns zunächst egal, ob es sich um ein Motorrad, ein Auto oder einen Bus handelt. Unser Automobil hat als Eigenschaften eine Typbezeichnung, eine Farbe, eine Höchstgeschwindigkeit und eine momentane Geschwindigkeit. Als Ergänzung werden wir nun zum Beispiel die Klasse für einen Autobus einführen, welche die Fähigkeiten des Automobils umfasst und weitere Methoden aufweist. Das Automobil soll sich beschleunigen und abbremsen lassen. Dafür werden zwei Methoden verwendet. 1. Die Beschleunigung soll physikalisch realistisch sein. Als Parameter wird eine Zahl von 0 bis 100 verwendet, die dem Druck aufs Gaspedal entspricht. Je näher die Geschwindigkeit bei der Endgeschwindigkeit liegt, desto schwächer wird die Beschleunigung. Zur Berechnung verwenden wir die Formel
tempoIst= tempoIst + (tempoMax-tempoIst)*gaspedal/100/2; 2. Beim Abbremsen gehen wir von einer Vollbremsung aus. Eine geeignete Formel lautet:
tempoIst=tempoIst-(6*tempoIst-2*tempoMax)/5;
Objekte
69
1_02.fm Seite 70 Dienstag, 8. Oktober 2002 2:14 14
Erreicht man kleine oder negative Werte, wird die Geschwindigkeit auf 0 gesetzt. Das Auto hat angehalten. Mit dieser Formel wird berücksichtigt, dass die Geschwindigkeitsabnahme bei hoher Geschwindigkeit geringer ist als bei niedrigerem Tempo. Die Klassendefinition für das Automobil sieht so aus:
Innerhalb der Klassenstruktur werden zunächst Klassenvariablen definiert.
70
PHP-Grundlagen
1_02.fm Seite 71 Dienstag, 8. Oktober 2002 2:14 14
In der Konstruktorfunktion, die den Namen der Klasse tragen muss, werden Parameter übergeben, die einige der Klassenvariablen initialisieren. In der Klasse werden Eigenschaften und Methoden mit dem Operator $this-> referenziert. Abbildung 4 und Abbildung 5 zeigen die Möglichkeiten des Maguma Studios für die Programmierung von Klassen. Mit dem Klassen-Wizard lassen sich Klassen und Objekte übersichtlich verwalten. Um ein erstes Objekt zu testen, fügen wir folgenden Code hinzu (die nun folgenden Codeteile werden nach und nach unten in den Code der Klassendefinition eingefügt):
//Testaufrufe für das Automobil-Objekt echo "Ein Automobil-Objekt"; $meinAuto=new Automobil("Ente",120,"rot"); echo($meinAuto->typ.", "); echo($meinAuto->farbe.""); while ($meinAuto->tempoIst beschleunige(80)).""); while ($meinAuto->tempoIst>0) echo("Langsamer: ".intval($meinAuto->bremse()).""); Mit $meinAuto=new Automobil("Ente",120,"rot"); wird ein neues Objekt aufgebaut. Der Speicherplatz für die Klasse wird reserviert und die Konstruktorfunktion aufgerufen. Die Parameter der Konstruktorfunktion werden hier dazu verwendet, die Klassenvariablen zu initialisieren. Die Variable für die momentane Geschwindigkeit wird bereits bei der Definition auf 0 gesetzt. Die Ausgabe zeigt dann folgenden Verlauf für die weiteren Aktionen:
Ein Automobil-Objekt Konstruktor Automobil rot Ente, rot Schneller: 48 Schneller: 76 Schneller: 94 Schneller: 104
Objekte
71
1_02.fm Seite 72 Dienstag, 8. Oktober 2002 2:14 14
Schneller: Langsamer: Langsamer: Langsamer: Langsamer:
110 84 53 16 0
Hier wird der Aufruf des Konstruktors angezeigt. Dann werden zwei Eigenschaften des Autos gezeigt. Die erste while-Schleife ruft dann solange die Methode beschleunige auf, bis eine Geschwindigkeit von 110 erreicht ist. Anschließend wird das Auto wieder gebremst, bis es zum Stillstand kommt. In dem folgenden Codesegment werden einige PHP-Funktionen benutzt, die Informationen zu einem Objekt liefern:
echo "Informationen zur Klasse Automobil"; echo "Klasse: ".get_class($meinAuto),""; echo "Parent-Klasse: ".get_parent_class($meinAuto); echo "Methoden: "; print_r(get_class_methods(get_class($meinAuto))); echo "Klassenvariablen: "; print_r(get_class_vars(get_class($meinAuto))); echo "Objektvariablen: "; print_r(get_object_vars($meinAuto)); Die Funktion print_r gibt ein Array in einer lesbaren Darstellung mit Schlüsseln und Werten aus. Die Ausgabe sieht so aus:
Informationen zur Klasse Automobil Klasse: automobil Parent-Klasse: Methoden: Array ( [0] => automobil [1] => beschleunige [2] => bremse ) Klassenvariablen: Array ( [tempoIst] => 0 ) Objektvariablen: Array ( [tempoIst] => 0 [typ] => Ente [farbe] => rot [tempoMax] => 120 ) Die darin verwendeten Funktionen sind: 왘 get_class($objekt): Ausgabe des Klassennamens eines Objekts
72
PHP-Grundlagen
1_02.fm Seite 73 Dienstag, 8. Oktober 2002 2:14 14
왘
get__parent_class($objekt): Ausgabe des Namens der übergeordneten Klasse, falls das Objekt von einem anderen abgeleitet wurde 왘 get_object_vars($objekt): Ausgabe der Objektvariablen eines initialisierten Objekts 왘 get_class_vars($klasse): Ausgabe der Klassenvariablen 왘 get_class_methods($klasse): Ausgabe der Klassenmethoden Weitere Funktionen, mit denen Informationen über Klassen und Objekte gewonnen werden können, sind: 왘 class_exists($klassenname): Prüft, ob eine Klasse deklariert wurde 왘 method_exists($objekt, $methodenname): Prüft, ob für ein Objekt eine bestimmte Methode vorhanden ist 왘 is_subclass_of($objekt, $klassenname): Prüft, ob das Objekt der Klasse untergeordnet ist 왘 get_declared_classes(): Zeigt die deklarierten Klassen an. Neben den immer vorhandenen Klassen, wie z.B. Directory, werden je nach Einbindung von Bibliotheken unter Umständen zusätzliche Klassen angezeigt. Die selbst definierten Klassen stehen am Ende. Nun wird aus der Automobilklasse eine andere Klasse abgeleitet. Die Klasse Autobus zählt zusätzlich die Anzahl der Passagiere im Bus und hat dafür die Methoden einsteigen und aussteigen.
// Konstruktor des Autobus-Objektes class Autobus extends Automobil { var $mitfahrerMax=40; var $mitfahrerIst=0; // Konstruktorfunktion function Autobus($farbe) { Automobil::Automobil("Bus",100,$farbe); echo("Konstruktor Autobus ".$farbe.""); } function einsteigen() { if ($this->mitfahrerIstmitfahrerMax) $this->mitfahrerIst++; $this->mitfahrer();
Objekte
73
1_02.fm Seite 74 Dienstag, 8. Oktober 2002 2:14 14
} function aussteigen() { if ($this->mitfahrerIst>0) $this->mitfahrerIst--; $this->mitfahrer(); } function mitfahrer() { echo "$this->mitfahrerIst"; if ($this->mitfahrerIst==$this->mitfahrerMax) echo " - der Bus ist voll"; if ($this->mitfahrerIst==0) echo " - der Bus ist leer"; } } Bei der Klassendefinition wird mit extends angegeben, aus welcher Klasse die neue Klasse hergeleitet wird:
class Autobus extends Automobil Die Initialisierung erfolgt in der Konstruktormethode mit dem Ausdruck:
Automobil::Automobil("Bus",100,$farbe); Dadurch wird zunächst ein Automobil mit dem Typ Bus und einer Höchstgeschwindigkeit von 100 vorgegeben (diese beiden Variablen sollen bei einem Bus immer so gesetzt sein). Die Farbe wird in der Autobus-Konstruktorfunktion übergeben. Nun hat der Autobus die Methoden des Automobils. Zusätzlich werden die Methoden einsteigen und aussteigen definiert, die jeweils die Methode mitfahrer aufrufen, welche zur Kontrolle die Anzahl der Passagiere ausgibt. Mit dem folgenden Code werden zum Test zwei Busse initialisiert:
echo "Zwei Autobus-Objekte"; $meinBusGelb=new Autobus("gelb"); $meinBusBlau=new Autobus("blau"); $meinBusBlau->beschleunige(50); $meinBusBlau->einsteigen();
74
PHP-Grundlagen
1_02.fm Seite 75 Dienstag, 8. Oktober 2002 2:14 14
$meinBusBlau->einsteigen(); $meinBusBlau->aussteigen(); $meinBusBlau->aussteigen(); In der zugehörigen Ausgabe erkennt man die Abfolge der Konstruktoraufrufe und das Geschehen beim Ein- und Ausstieg von zwei Passagieren:
Zwei Autobus-Objekte Konstruktor Automobil gelb Konstruktor Autobus gelb Konstruktor Automobil blau Konstruktor Autobus blau 1 2 1 0 - der Bus ist leer Auch hier können mit dem folgenden Programmteil Informationen zu den Objekten ausgegeben werden. Der Autobus ist eine abgeleitete Klasse des Automobils (get_parent_class). Zusätzlich werden am Ende alle definierten Klassen aufgelistet.
echo "Informationen zur Klasse Autobus"; echo "Klasse: ".get_class($meinBusGelb),""; echo "Parent-Klasse: ".get_parent_class($meinBusGelb); echo "Methoden: "; print_r(get_class_methods(get_class($meinBusGelb))); echo "Klassenvariablen: "; print_r(get_class_vars(get_class($meinBusGelb))); echo "Objektvariablen: "; print_r(get_object_vars($meinBusGelb)); echo "Klassendefinitionen: "; print_r(get_declared_classes());
Objekte
75
1_02.fm Seite 76 Dienstag, 8. Oktober 2002 2:14 14
Die Ausgabe der Informationen ergibt folgenden Code:
Informationen zur Klasse Autobus Klasse: autobus Parent-Klasse: automobil Methoden: Array ( [0] => automobil [1] => beschleunige [2] => bremse [3] => autobus [4] => einsteigen [5] => aussteigen [6] => mitfahrer ) Klassenvariablen: Array ( [tempoIst] => 0 [mitfahrerMax] => 40 [mitfahrerIst] => 0 ) Objektvariablen: Array ( [tempoIst] => 0 [mitfahrerMax] => 40 [mitfahrerIst] => 0 [typ] => Bus [farbe] => gelb [tempoMax] => 100 ) Klassendefinitionen: Array ( [0] => stdClass [1] => __PHP_ Incomplete_Class [2] => OverloadedTestClass [3] => Directory [4] => COM [5] => VARIANT [6] => swfshape [7] => swffill [8] => swf gradient [9] => swfbitmap [10] => swftext [11] => swftextfield [12] => swffont [13] => swfdisplayitem [14] => swfmovie [15] => swfbutton [16] => swfaction [17] => swfmorph [18] => swfsprite [19] => automobil [20] => autobus )
왖 Abbildung 3
Die Programmierung von Objekten in PHP
76
PHP-Grundlagen
1_02.fm Seite 77 Dienstag, 8. Oktober 2002 2:14 14
왖 Abbildung 4
Der Klassen-Wizard des Maguma Studios, mit dem sich Klassen und Objekte verwalten lassen
Klassen und Objekte in Flash Die Arbeit mit Objekten in Flash ActionScript ist ganz ähnlich. Zum Vergleich werden hier die Automobil- und Autobus-Objekte noch einmal implementiert. Konstruiert werden Objekte in Flash über Konstruktorfunktionen. Eine explizite Klassendefinition ist nicht erforderlich. Objektmethoden werden als Prototypen definiert. Der this-Operator greift wie bei PHP auf das aktuelle Objekt zu.
// Konstruktor und Methoden des Automobil-Objektes function Automobil(typ, tempoMax, farbe) { this.typ=typ this.farbe=farbe; this.tempoMax=tempoMax; this.tempoIst=0; trace("Konstruktor Automobil "+this.farbe); }
AS
Objekte
77
1_02.fm Seite 78 Dienstag, 8. Oktober 2002 2:14 14
Automobil.prototype.beschleunige = function(gaspedal) { d=(this.tempoMax-this.tempoIst)*gaspedal/100/2; this.tempoIst+=d; return this.tempoIst; } Automobil.prototype.bremse = function() { this.tempoIst=(6*this.tempoIst-2*this.tempoMax)/5; if (this.tempoIst