php 4 egon schmid christian cartus unter mitarbeit von wolfgang drews hartmut holzgraefe uwe steinmann christian wenz
new technology Bitte beachten Sie: Der originalen Printversion liegt eine CD-ROM bei. In der vorliegenden elektronischen Version ist die Lieferung einer CD-ROM nicht enthalten. Alle Hinweise und alle Verweise auf die CD-ROM sind ungültig.
Markt+Technik Verlag
Die Deutsche Bibliothek – CIP-Einheitsaufnahme Ein Titeldatensatz für diese Publikation ist bei Der Deutschen Bibliothek erhältlich.
Die Informationen in diesem Produkt werden ohne Rücksicht auf einen eventuellen Patentschutz veröffentlicht. Warennamen werden ohne Gewährleistung der freien Verwendbarkeit benutzt. Bei der Zusammenstellung von Texten und Abbildungen wurde mit größter Sorgfalt vorgegangen. Trotzdem können Fehler nicht vollständig ausgeschlossen werden. Verlag, Herausgeber und Autoren können für fehlerhafte Angaben und deren Folgen weder eine juristische Verantwortung noch irgendeine Haftung übernehmen. Für Verbesserungsvorschläge und Hinweise auf Fehler sind Verlag und Herausgeber dankbar.
Alle Rechte vorbehalten, auch die der fotomechanischen Wiedergabe und der Speicherung in elektronischen Medien. Die gewerbliche Nutzung der in diesem Produkt gezeigten Modelle und Arbeiten ist nicht zulässig. Fast alle Hardware- und Softwarebezeichnungen, die in diesem Buch erwähnt werden, sind gleichzeitig auch eingetragene Warenzeichen oder sollten als solche betrachtet werden. Umwelthinweis: Dieses Buch wurde auf chlorfrei gebleichtem Papier gedruckt. Die Einschrumpffolie – zum Schmutz vor Verschmutzung – ist aus umweltverträglichem und recyclingfähigem PE-Material.
10 9 8 7 6 5 4 3 2 05 04 03 02 01
ISBN 3-8272-5877-4
© 2001 by Markt+Technik Verlag, ein Imprint der Pearson Education Deutschland GmbH, Martin-Kollar-Straße 10–12, D 81829 München/Germany Alle Rechte vorbehalten Lektorat: Boris Karnikowski,
[email protected] Fachlektorat: Ralf Geschke, Hürth, Timo Ernst, Endingen, Markus Walser, Tettnaug Herstellung: Claudia Bäurle, cbä
[email protected] Satz: reemers publishing services gmbh, Krefeld Einbandgestaltung: adesso21, München Druck und Verarbeitung: Bercker, Kevelaer Printed in Germany
Inhaltsverzeichnis Vorwort Vorwort von Andi Gutmans und Zeev Suraski Danksagung der Autoren Kapitel 1
Kapitel 2
Kapitel 3
13 14 16
Systematik
17
1.1 1.2 1.3 1.4
18 18 18 19
Zweck des Buches Aufbau Für wen sich das Buch eignet Einsteiger oder Profi?
PHP 4 – Einsatzmöglichkeiten und Hintergrund
21
2.1 2.2 2.3 2.4
22 22 23 24
In aller Kürze Welche Vorteile hat PHP? Was kann man alles mit PHP tun? Geschichte und Umfeld von PHP
Syntax und Grammatik
31
3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13
32 33 33 34 34 35 35 36 38 38 39 40 40
PHP in HTML einbinden Trennung von Anweisungen Kommentare Variablentypen Variablen-Initialisierung Initialisierung von Arrays Objekt-Initialisierung Gültigkeitsbereiche von Variablen Variable Variablen Automatische Typenkonvertierung Erzwungene Typenkonvertierung Stringkonvertierung Bestimmung der Variablentypen
6
Kapitel 4
Kapitel 5
Inhaltsverzeichnis
Sprachbeschreibung
43
4.1 4.2 4.3 4.4 4.5
44 45 48 56 59
Konstanten Operatoren Anweisungen Benutzerdefinierte Funktionen Klassen
Parameterübergaben in PHP
65
5.1 5.2 5.3
66 67 72
Definition der Methoden GET und POST Mit GET Parameter übergeben Formularverarbeitung mit POST
Kapitel 6
Cookies
81
Kapitel 7
Upload
89
7.1 7.2 Kapitel 8
Umgang mit Dateien 8.1
Kapitel 9
Kapitel 10
Upload-Funktionalität File-Upload
Einen E-Mail-Verteiler entwickeln
90 90 95 100
Dateien und Benutzerrechte
109
9.1 9.2
110 112
Unix-Rechtesystem Sicherheitsrisiken
MySQL und PHP
115
10.1 10.2 10.3 10.4 10.5 10.6
116 132 148 158 162 196
Grundlagen Arbeiten mit MySQL für Fortgeschrittene Beispiel einer Datenbankanwendung MySQL Datentypen PHPs MySQL-Funktionen ODBC
Inhaltsverzeichnis
7
Kapitel 11
PHP und JavaScript
209
Kapitel 12
PHP und Java
215
12.1 12.2 12.3
216 226 239
Kapitel 13
Kapitel 14
Kapitel 15
Kapitel 16
Bildmanipulation
241
13.1 13.2 13.3 13.4
242 244 245 246
Bilder mit GD und TTF erzeugen PostScript-Schriften Verwendung von Bildern Ein komplexeres Beispiel
Erstellen von PDF- und FDF-Dokumenten
253
14.1 14.2 14.3
254 255 270
Installation PDF-Funktionen FDF-Funktionen
PHP und XML
273
15.1 15.2 15.3
275 280 284
SAX DOM WDDX
E-Mail 16.1 16.2
Kapitel 17
Java PHP als Servlet Support
287 Standardfunktion mail() Mail abfragen POP
288 293
PHP-Funktionen selbst gemacht
297
17.1 17.2 17.3 17.4 17.5 17.6 17.7
298 298 299 301 302 333 344
Allgemeines Die Entwicklungsumgebung Das CVS Der erste Kompilierungsvorgang Die PHP-Programmierschnittstelle Der Modulaufbau Ein Beispielmodul
8
Kapitel 18
Inhaltsverzeichnis
PHPLIB 18.1 18.2 18.3 18.4
Kapitel 19
Anhang A
363 Was leistet PHPLIB? Wo bekommt man PHPLIB (und was kostet sie)? PHPLIB installieren Zugriff auf Datenbanken mit PHPLIB
364 366 367 370
Sessions
415
19.1 19.2 19.3
416 417 420
Sinn und Zweck von Sessions Cookies PHP Modul Session
Funktionskurzreferenz
425
A.1 A.2 A.3 A.4 A.5 A.6 A.7 A.8 A.9 A.10 A.11 A.12 A.13 A.14 A.15 A.16 A.17 A.18 A.19 A.20 A.21 A.22 A.23 A.24
430 433 435 436 439 439 440 467 468 474 474 475 476 477 477 477 477 478 479 479 479 479 479 480
Allgemeine Funktionen Zend-Buildin-Funktionen Apache-Funktionen Array-Funktionen Browscap-Funktionen CURL-Funktionen Datenbank-Funktionen COM-Funktionen Datum, Zeit und Kalender DAV-Funktionen Debugging DOMXML-Funktionen DNS-Funktionen Dynamisches Linken EXIF-Funktionen Packen und Entpacken Zlib-Funktionen Funktionen zur formatierten Ausgabe Identifizierer-Funktion Konstanten Kyrillische Funktion Mail-Funktion Output-Buffering-Funktionen Payflow Pro
Inhaltsverzeichnis
A.25 A.26 A.27 A.28 A.29 A.30 A.31 A.32 A.33 A.34 A.35 A.36 A.37 A.38 A.39 A.40 A.41 A.42 A.43 A.44 A.45 A.46 A.47 A.48 A.49 A.50 A.51 A.52 A.53 A.54 A.55 A.56 A.57 A.58 A.59 A.60 A.61
9
Programmausführung Rechtschreibprüfung Readline-Funktionen Sonderzeichen Sonstige Funktionen (set_time_limit) Sonstige Funktionen (Soundex, Levenshtein, Metaphone) Soundex-Funktion xx.Levenshtein-Funktion xx.Metaphone-Funktion Systemlog-Funktionen Verschlüsselungsfunktionen Zeichenketten-Funktionen BC – beliebig genaue mathematische Funktionen GD- und TTF-Grafik-Funktionen Bildgröße-Funktion Filesystem- und Datei-Funktionen POSIX-Funktionen FTP-Funktionen Gettext-Funktionen Link-Funktionen HTML- und HTTP-Funktionen HyperWave-Funktionen IMAP-Funktionen IPTC-Funktionen LDAP-Funktionen Mathematische Funktionen MD5-Funktion Mhash-Funktionen Zufallszahlen und Verschlüsselungsfunktionen Netzwerk-Funktionen (Socket-Funktionen) PHP-Optionen und -Informationen PDF-, CPDF- und FDF-Funktionen PDF-Funktionen CPDF-Funktionen FDF-Funktionen Session-Funktionen Skeleton-Funktion
480 481 482 483 483 483 483 484 484 484 484 488 492 493 497 497 501 503 505 505 506 506 511 515 516 518 520 520 520 521 524 525 525 531 535 537 538
10
Inhaltsverzeichnis
A.62 A.63 A.64 A.65 A.66 A.67 A.68 A.69 A.70 A.71 Anhang B
538 539 540 541 546 546 547 548 549 550
Installation und Konfiguration von PHP
551
B.1 B.2 B.3
552 552
B.4 B.5 B.6 B.7 B.8 B.9 B.10 B.11 B.12 B.13 B.14 B.15 B.16 B.17 Anhang C
Reguläre Ausdrücke SNMP-Funktionen Semaphoren- und Shared-Memory-Funktionen Shockwave-Flash-Funktionen URL-Funktionen Virtuelle-Mailbox-Funktionen WDDX-Funktionen XML-Funktionen YP/NIS: Gelbe Seiten YAZ-Funktionen
Wie installiert man PHP? Die Installation vorbereiten Konfigurationsänderungen bei PHP und allgemeine Installationshinweise553 Konfiguration als Skriptprozessor oder Apache-Modul Wichtige Erweiterungsmodule Installationsreihenfolge, Konfigurationsschalterbeschreibung Konkretes Installationsbeispiel (Apache 1.3, PHP und MySQL) Installation unter Windows Unterstützte Server Allgemeine Vorarbeiten Server installieren Installation eines WAMP-Systems Omni HTTPd 2.0b1 für Windows Windows NT und IIS 4 MS PWS Wie konfiguriert man PHP? Inkompatibilitäten mit PHP 3
554 554 555 556 560 560 560 560 564 568 569 571 574 588
Weiterführende Informationen
593
C.1 C.2 C.3 C.4
594 595 598 599
Literaturverzeichnis Online-Quellen Mailinglisten Newsgroups
Inhaltsverzeichnis
11
Anhang D
Inhalt der CD
601
Anhang E
Glossar
603
Stichwortverzeichnis
611
Vorwort Vorwort von Andi Gutmans und Zeev Suraski Danksagung der Autoren 16
14
14
Vorwort von Andi Gutmans und Zeev Suraski
Vorwort von Andi Gutmans und Zeev Suraski In den wenigen Jahren seit seiner Entstehung hat es PHP schon weit gebracht. Seine Entwicklung nahm ihren Anfang mit ein paar Perl-Scripts, mit denen Zugriffe auf einen Online-Lebenslauf protokolliert werden sollten, führte dann weiter über eine schon wesentlich anspruchsvollere C-Implementierung, die Anwendung in zahlreichen Web-Projekten fand (PHP/FI 2.0), und mündete schließlich in die vielfältig einsetzbaren Webentwicklungsumgebungen wie PHP 3.0 und seinem erwachsenen Bruder, PHP 4.0. Die Beliebtheit von PHP hat in den letzten Jahren auf eine Weise zugenommen, mit der niemand gerechnet hätte. Man schätzt, dass heutzutage ca. 15% aller Internet-Domains PHP unterstützen, womit PHP im Open Source-Bereich die bei weitem verbreitetste Webscripting-Sprache ist. PHP genießt damit eine ähnliche Beliebtheit wie Microsofts ASP. Dass wir so weit kommen würden, hätten wir uns selbst in unseren kühnsten Träumen nicht auszumalen gewagt. Besonders interessant erscheint uns dabei die Beliebtheit von PHP auf dem deutschen Markt, der nach dem US-Markt der weltweit zweitgrößte Markt für PHP sein dürfte (und prozentual gesehen ist er vermutlich der größte). Wir vermuten, dass der Grund hierfür in der in Deutschland allgemein großen Akzeptanz für Open Source-Technologien wie z.B. Linux liegt. Es ist nicht ganz einfach, die genauen Gründe für den Erfolg von PHP zu nennen. Was sicherlich wesentlich dazu beigetragen hat, ist das Open Source-Modell, das es Rasmus Lerdorf eingangs erlaubt hat, PHP/FI 2.0 weit über seine ursprünglich gesteckten Ziele hinaus zu entwickeln. Zeev und mir wiederum erlaubte es Einblick in die Schwachstellen seiner Lösung, so dass wir uns an eine vollständig neue Implementierung und ein neues Framework machen konnten. Ein paar Monate und einige schlaflose Nächte später ging hieraus das revolutionäre PHP 3.0 hervor. Dank der fruchtbaren Zusammenarbeit in der Open Source-Gemeinde und dank des neuartigen, ausbaufähigen Designs von PHP 3.0 und seinem Nachfolger PHP 4.0 mit der Zend Engine erschließen sich PHP nun neue Horizonte. Wohin diese Entwicklung führen wird, lässt sich zum gegenwärtigen Zeitpunkt nur ahnen. Natürlich gibt es immer noch eine Menge zu tun. Sprachverbesserungen, Internationalisierung und die Unterstützung aufkommender Technologien sind nur einige der Dinge, die sich die PHP-Entwickler für die Zukunft auf ihre Agenda geschrieben haben. Das Open Source-Modell, in dem PHP fest verwurzelt ist, stellt dabei sicher, dass sich immer neue Entwickler an der Entwicklung beteiligen und PHP damit auch in den kommenden Jahren zu einer der führenden Webtechnologien gehören wird. Zusätzlich werden Firmen wie Zend Technologies, die für PHP kommerzielle Unterstützung in Gestalt von Unternehmenslösungen und Support anbieten, PHP bei seiner Verbreitung im Unternehmensmarkt unterstützen. Ohne diese Unterstützung würden die Unternehmen Open Source-Software nur zögerlich oder gar nicht einsetzen.
Vorwort von Andi Gutmans und Zeev Suraski
15
Einer der Autoren dieses Buches, Egon Schmid, ist eines der aktivsten Mitglieder des PHP Documentation Team und hat mit seiner hervorragenden Arbeit wesentlich zur Verbreitung von PHP in Deutschland beigetragen (und tut dies noch). Wir sind überzeugt, dass Sie als beginnender PHP-Entwickler dieses Buch sehr hilfreich und interessant finden werden. Schließlich möchten wir diese Gelegenheit noch nutzen, um uns beim PHP Development Team zu bedanken, ebenso bei den übrigen Angehörigen des PHP Documentation Team und dem gerade frisch aus der Taufe gehobenen PHP Quality Assurance Team. Weiter so! Andi Gutmans Zeev Suraski PHP Development Team Tel Aviv, Israel, November 2000
16
Danksagung der Autoren
Danksagung der Autoren Im Lauf der Zeit haben uns die verschiedensten Menschen unterstützt. Ohne diese Hilfe wäre es nicht möglich gewesen, in der kurzen Zeit, die uns zur Verfügung stand, zurechtzukommen. Wir können uns leider nicht bei wirklich allen bedanken, nur einige Namen stellvertretend herausgreifen. Wir bedanken uns herzlich insbesondere bei: Der gesamten devedge von I-D Gruppe, Timo Ernst, Holger Blaschka, Tobias Ratschiller, Christine Kühnel, Johannes M. Becher und allen anderen, die wir hier nicht nennen. Unseren technischen Lektoren, Timo Ernst, Tobias Ratschiller, Ralf Geschke und -mat- filid brandy. Zwar ist dieses Buch der überarbeitete Nachdruck der Neuauflage unseres ersten Versuchs, doch wird es wohl auch diesmal wieder so sein, dass wir einiges übersehen oder vergessen haben. Wir freuen uns daher über Hinweise und Vorschläge für weitere, verbesserte Auflagen. Wolfgang Drews hat unter http://www.phpbuch.de eigens für dieses Buch eine Website eingerichtet, auf der Errata, Anmerkungen und dergleichen eingereicht werden können. Die folgenden Nachdrucke dieser Auflage werden von diesen Korrekturen profitieren. Ach ja – Sie erfahren dort auch das eine oder andere über uns:). Wir hoffen, dass auch dieses Buch den Kollegen und Freunden im Netz eine Hilfe sein wird. April 2001
Chris, Egon und ihre Co-Autoren Wolfgang, Uwe, Christian und Hartmut
Kapitel 1 Systematik von Christian Cartus und Egon Schmid
1.1 1.2 1.3 1.4
Zweck des Buches 18 Aufbau 18 Für wen sich das Buch eignet Einsteiger oder Profi? 19
18
18
1.1
Zweck des Buches
Zweck des Buches Der eigentliche Hauptteil des Buches versucht weniger, konkrete Vorgaben zu machen, sondern will Ihnen Wege aufzeigen, wie man in PHP vorgeht, um bestimmte Probleme zu lösen.
1.2
Aufbau Wir denken, dass Sie öfter programmieren als installieren werden. Aus diesem Grund finden Sie die Kapitel zu Installation und Konfiguration im Anhang. Das übrige Buch ist – nach einigen einführenden Kapiteln – modular aufgebaut. So können Sie sofort und ohne die meisten anderen Kapitel lesen zu müssen, geradewegs auf die Information zugreifen, die Sie für Ihr Problem benötigen.
1.3
Für wen sich das Buch eignet Denjenigen, die jetzt das Gefühl haben, ein Wörterbuch für Chinesisch in der Hand zu halten, empfehlen wir, erst einmal ein paar Zeilen weiterzulesen, bevor sie das Buch kaufen. Hinweis PHP eignet sich vor allem für Programmierer. Wenn Sie nicht programmieren können oder Lust haben, es zu erlernen, werden Sie nicht den vollen Nutzen aus PHP ziehen können. PHP eignet sich nur begrenzt für Leser ohne Programmierkenntnisse. PHP ist sehr gut geeignet, wenn Sie bereits in einer oder mehreren Sprachen programmiert haben. Wir haben im Anhang und auf CD allerdings einige oft gefragte Anwendungen erwähnt bzw. beigelegt, um auch den Nichtprogrammierern einen Nutzwert anzubieten. Um wirklich Spaß und Nutzen aus der Arbeit mit PHP zu ziehen, sollten Sie jedoch Vorkenntnisse in Unix und Programmierung haben, bereits mit Webservern gearbeitet haben, oder aber den festen Vorsatz hegen, sich mit diesen Themen auseinanderzusetzen. Für alle fortgeschrittenen Programmierungen unter PHP benötigen Sie zudem Datenbankkenntnisse. Sie finden deshalb im Anhang eine kleine Liste mit weiterführender Literatur und Online-Quellen zu den verwandten Themen, keineswegs vollständig, aber hoffentlich geeignet, Ihnen als Einsteiger eine erste Orientierung zu ermöglichen. Dieses Buch ist kein Ersatz für die hervorragende Dokumentation, die Sie im Netz unter http://www.php.net, aber auch auf unserer CD finden können. Die Dokumentation finden Sie im RTF-, PDF- und HTML-Format übrigens auch auf der beiliegenden CD.
Kapitel 1 • Systematik
19
Wir empfehlen Ihnen dringend, sie sich auszudrucken: Das Buch ist eine Einführung und Ergänzung dazu, und Sie werden am meisten Nutzen daraus ziehen, wenn Sie beides verwenden. Die Profis unter den Käufern schätzten nach eigenen Angaben erwartungsgemäß die Funktionsreferenz im Anhang A sowie das Kapitel 17, in dem Christian Cartus und Uwe Steinmann aus der Praxis heraus beschreiben, wie man PHP um eigene Funktionen erweitern kann. Dieser Teil ist ausschließlich für echte Programmierer gedacht und fällt im Grunde genommen aus dem Buch heraus, da es sich dabei nicht um eigentliche PHP-Programmierung handelt. Aber dieses Kapitel gibt einen intimen Einblick in den Aufbau und die Strukturen von PHP aus der Sicht eines Entwicklers. Wir haben dieses Kapitel im Bewusstsein mit aufgenommen, dass es nur für einen kleinen Teil der Leser relevant ist und nicht zum eigentlichen Thema gehört. Unsere Intention dabei war, den PHP-Entwicklern eine Einführung an die Hand zu geben, die im Effekt allen PHPlern zum Vorteil gereichen kann, da wir hoffen, dass sich noch mehr Entwickler als bisher finden, die PHP um neue Funktionen bereichern.
1.4
Einsteiger oder Profi? Wie schon gesagt sind wir der Meinung, dass sich PHP nicht unbedingt für »absolute beginners« eignet. Aber: Der Dienstleistungssektor im Bereich Internet ist nicht homogen. Es gibt verschiedene Nischen mit unterschiedlichen Strukturen, sowohl was die Preise als auch was das Leistungsspektrum angeht. Wir wollen es keineswegs allen recht machen, haben aber trotzdem auch die Bedürfnisse verschiedener Anwender abzuwägen versucht. Diejenigen, die in Datenbankanbindung und Webprogrammierung fit genug sind, verdienen im Moment ein Heidengeld. Wir wissen aber aus der Praxis, dass es eine Menge kleiner und kleinster Betriebe gibt, in denen weder das nötige Umfeld noch die nötigen Kunden noch die Ressourcen vorhanden sind, um das benötigte Wissen und entsprechendes Handwerkszeug aufzubauen. Wir wollen diese Situation nicht aufschlüsseln und belassen es bei unserem Hinweis, dass nicht jeder alles kann und können muss. Im Niedrigpreisbereich können Lösungen, die einem Profi als mangelhaft erscheinen, durchaus als gute und praktikable Anwendung wirken. PHP ist ein skalierbares System, das mit den Ansprüchen des Benutzers wächst. So können Sie, wenn Sie nicht mit Datenbanken vertraut sind und im Moment auch nicht die Zeit und die Nerven haben, sich damit zu beschäftigen, anfangs durchaus mit »flat files« (das sind einfache Textdateien, in die geschrieben/aus denen gelesen wird) arbeiten. Für kleine Webschmieden, die kunden- und ergebnisorientiert arbeiten, ist dies eine schöne Möglichkeit, kleinere Lösungen zu realisieren, die auf anderem Wege teurer und/oder schwieriger wären.
20
Einsteiger oder Profi?
Andererseits bietet PHP dem fortgeschrittenen Programmierer Wege der absolut professionellen Problemlösung auch im hochperformanten Umfeld an. Mittlerweile hat sich rund um die deutschsprachige Mailingliste zum Thema PHP, die übrigens eine gute Anlaufstelle für (fundierte!) Fragen ist, einiges getan. Unter http://www.php-center.de findet sich ein guter deutschsprachiger Server zum Thema PHP, den wir Ihnen hier empfehlen möchten. Sie werden dort vielfältige Hilfen und Anregungen entdecken. Wenn Sie in der erwähnten Mailingliste mitlesen möchten, finden Sie die entsprechenden Hinweise unter http://info soc.uni-koeln.de/mailman/listinfo/php/. Wir erwähnen dies, weil wir etliche Anfragen von PHP-Anfängern nach weiteren Beispielskripten usw. erhalten haben. Möglicherweise werden wir in einiger Zeit dieses Buch entsprechend erweitern können, sofern es das Interesse der PHPGemeinde daran zulässt.
Kapitel 2 PHP 4 – Einsatzmöglichkeiten und Hintergrund von Christian Cartus, Egon Schmid und Wolfgang Drews
2.1 2.2 2.3 2.4
In aller Kürze 22 Welche Vorteile hat PHP? 22 Was kann man alles mit PHP tun? 23 Geschichte und Umfeld von PHP 24
22
2.1
In aller Kürze
In aller Kürze PHP ist eine Erweiterung für Webserver, die es ermöglicht, schnell und mit verhältnismäßig wenig Aufwand dynamische Websites im Internet zu erstellen. Besonders bemerkenswert an PHP ist die breite Unterstützung für eine ganze Reihe von Datenbanken. Dadurch empfiehlt sich PHP u.a. ganz besonders für professionelle E-Commerce-Lösungen. In vielen Bereichen überschneidet sich die Funktionalität von PHP mit anderen Programmen, Tools und Methoden. Viele der in PHP möglichen Programmierungen lassen sich auch in Perl realisieren oder finden ihre Entsprechung in ASP. Anfangs verwirrt die Konzeption von PHP etwas – denn es gibt in Wirklichkeit kein starres Konzept dahinter. Es ist eine Entwicklung aus der Praxis, in welche ganz persönliche Vorstellungen und Wünsche von Praktikern eingeflossen sind. Entsprechend bunt ist die Palette der Funktionalitäten, die zudem jederzeit erweitert werden kann und auch wird.
2.2
Welche Vorteile hat PHP?
2.2.1
Für Programmierer Der Vorteil von PHP liegt dabei in einer erheblich einfacheren Programmierbarkeit, in der Vielzahl der vorhandenen Module, in der systemübergreifenden Verfügbarkeit und in der Tatsache, dass der komplette Quellcode zur Verfügung steht. Übrigens wird in dem Buch auch die Programmierung eigener Module zur Funktionserweiterung von PHP beschrieben. Das Kapitel »PHP-Funktionen selbstgemacht« hat eigentlich nichts mehr mit der Programmierung in PHP zu tun und verlangt von Ihnen fortgeschrittene Kenntnisse in C. Aber gerade die echten Programmierer unter Ihnen dürfte dieses Kapitel am meisten interessieren. Durch die Möglichkeit, eigene PHP-Funktionen zu schreiben, lässt sich das Potential von PHP beliebig erweitern. Interessant ist möglicherweise auch der Einsatz von PHP außerhalb eines Webservers als Standalone-Skriptsprache. Diese Option wird bislang (noch?) wenig genutzt, bietet sich aber als Alternative zu anderen Lösungen in der Praxis gelegentlich an.
2.2.2
Agenturen, Provider, Systemhäuser Nicht zuletzt der schnelle und freundliche Support, der dem einzelnen aus der Gemeinschaft der PHP-Programmierer entgegengebracht wird, mag als weiteres Argument dienen, PHP einzusetzen. Erstaunlicherweise (oder logischerweise?) sind Fehlerbereinigungen bei kommerziellen Unternehmen etwas langsamer als bei den freien Projekten, und nicht selten bezahlen Sie den weniger guten Service auch noch über teure Hotlines oder Servicepakete.
Kapitel 2 • PHP 4 – Einsatzmöglichkeiten und Hintergrund
23
Als Provider können Sie in PHP Ihren Support automatisieren und Ihren Kunden somit schneller und mit dem Anschein persönlicher Ansprache Hilfestellung leisten. Das spart Kosten und schont Ressourcen. Neue Konzepte, mit denen sich Märkte erschließen lassen, die vorher in einem unattraktiven Preissegment lagen, können mit PHP realisiert werden.
2.2.3
Marketing Für die Marketingexperten ist PHP ein hochperformantes, vielseitiges und kostengünstiges System, um die Wünsche ihrer Kunden erfüllen zu können. Die Entwicklungszeit ist im Allgemeinen deutlich kürzer im Vergleich zu ASP. PHP ist mittlerweile zu einem ernstzunehmenden und etablierten System erwachsen. Damit entfällt die unangenehme Aufgabe, dem Kunden eine Außenseiterlösung verkaufen zu müssen. Es gibt im Moment neben diesem Buch weitere Bücher in neun verschiedenen Sprachen. Eine Liste aller bekannten Bücher finden Sie unter http://www.php.net/books.php. Die Dokumentation wird in verschiedene Sprachen übersetzt. Kurzum: Das Interesse an PHP ist groß, und es handelt sich längst nicht mehr um eine Insellösung für Freaks. Neben all diesen vernünftigen Gründen, die für PHP sprechen, soll aber auch ein weniger seriöser genannt werden: PHP ist cool! Yeah.
2.3
Was kann man alles mit PHP tun? PHP eignet sich für die fortgeschrittene Formularauswertung, für das Arbeiten mit Cookies, für das Bearbeiten von verschiedenen Dateien (auch die Manipulation und Generierung von Bildern), stellt überlegene Funktionen für Uploads zur Verfügung und unterstützt eine umfassende Liste von Datenbanken. Namentlich arbeitet PHP mit folgenden Datenbanken zusammen: •
Adabas D
•
dBase
•
DBM
•
Empress
•
FilePro
•
Informix
•
Ingres
•
InterBase
•
mSQL
24
Geschichte und Umfeld von PHP
•
MSSQL
•
MySQL
•
ODBC
•
Oracle
•
PostgreSQL
•
Solid
•
Sybase
•
Velocis
Die Implementierung weiterer Schnittstellen zu anderen Datenbanken dürfte eine Frage der Zeit sein. Objektorientierte Datenbanken werden im Moment leider nicht unterstützt, was am mangelnden Interesse seitens der Entwickler liegen dürfte. Des weiteren enthält PHP eine Reihe seltener genutzter kryptografischer Funktionen zur Verschlüsselung und sicheren Übertragung von Daten. Auch eine andere häufig gestellte Frage lässt sich mit Ja beantworten: PHP arbeitet mit JavaScript und Java zusammen. Mit einem Wort: PHP ist das Schweizer Taschenmesser des Webmasters, das ihm einfache Standardarbeiten noch mehr erleichtert und fortgeschrittene Datenbankanbindungen ermöglicht.
2.4
Geschichte und Umfeld von PHP
2.4.1
Wie PHP entstanden ist Eine erste Vorversion wurde bereits im Herbst 1994 von Rasmus Lerdorf geschrieben, der es dazu benutzte, sich einen Überblick über Interessenten an seinem Online-Lebenslauf zu verschaffen. Anfangs handelte es sich nur um einen kleinen Parser und einige Utilities, die unter dem Namen »Personal Home Page Tools« auch von anderen frei benutzt werden durften. So entstand auch der heutige Name »PHP«, der zunächst nur eine Abkürzung für »Personal Home Page« darstellte. Da sich die Nutzung von PHP zunehmend von »Personal Home Pages« zu professionellen Webapplikationen verlagerte, wurde durch eine Wahl nach einer neuen offiziellen Bezeichnung gesucht. Seitdem steht PHP für »PHP: Hypertext Preprocessor«. In der Anfangsphase konnte man mit PHP nur ein paar kleine Dinge tun, die ebenso mit einem Perl-Skript oder einem CGI in einer beliebigen Sprache leicht realisierbar gewesen wären. Unter anderem gab es einen Zähler für Besucher und ein Gästebuch, die in PHP schnell umgesetzt werden konnten.
Kapitel 2 • PHP 4 – Einsatzmöglichkeiten und Hintergrund
25
Interessanter wurde PHP 1995, als der Parser neu geschrieben und unter dem Namen PHP/FI verteilt wurde. Der Zusatz »FI« ist nur eine Abkürzung für eine weitere Möglichkeit, die neu in PHP eingebracht worden war, nämlich »Form Interpreter«, also eine Lösung, um HTML-Formulare auszuwerten. PHP/FI, nun in der Version 2, war ein flexibles und brauchbares Werkzeug für fortgeschrittene Internet-Programmierung und fand schnell eine treue Fangemeinde. Binnen kurzem wurde die Entwicklung von PHP/FI von freiwilligen Programmierern vorangetrieben, die anfangs ungeordnet ihre Ideen und Programmierungen in das Paket einbrachten. Etwa Mitte 1997 bildete sich ein Team um Rasmus Lerdorf, und PHP begann eine immer komplexere und professionellere Software zu werden. Die Zahl der Installationen stieg sprunghaft an und führte dazu, dass sich PHP von einer kleinen Insellösung für Freaks zu einer ernstzunehmenden Alternative zu anderen, auch kommerziellen Lösungen entwickelte. Im Moment ist PHP 4/Zend die aktuelle Version auf dem Markt. Die Weiterentwicklung ist zu großen Teilen rückwärtskompatibel zu ihrem Vorgänger. Die meisten vorhandenen Scripts können also ohne Änderung auch unter PHP 4 in die Lösungen integriert werden. Unter http://www.php.net/version4/ sind mögliche Inkompatibilitäten zwischen PHP 4/Zend und PHP 3 dokumentiert. Der Name »Zend« ist eine Zusammensetzung aus »ZEev« und »aNDi«, nach den Vornamen der beiden Entwickler Zeev Suraski und Andi Gutmans. Einer der großen Vorteile von Zend wird in der Vorkompilierung des Codes liegen, was einen Geschwindigkeitsvorteil um den Faktor Hundert gegenüber PHP 3 ermöglichen soll. Sie finden im Netz unter http://www.php-buch.de/ einen Webserver, auf dem wir deutschsprachigen Benutzern aktuelle Infos und Kommunikationsmöglichkeiten auch zu Zend bieten werden. Weitere Informationen finden Sie im Internet, entsprechende Adressen entnehmen Sie bitte unserer Website und dem Anhang des Buches.
2.4.2
Ein Wort zum Thema freie Software Falls Sie gewohnt sind, für Ihre Software zu bezahlen, steht Ihnen jetzt ein kleiner Kulturschock bevor: Tatsächlich ist PHP ebenso wie Linux, Apache und MySQL nach wie vor kostenfrei erhältlich. All diese Software wird nicht zentral von irgendeiner Softwarefirma hergestellt, verwaltet und verkauft, sondern völlig frei auch im Quellcode jedem Interessierten zur Verfügung gestellt. Sie können alle benötigten Programme einfach aus dem Internet laden oder auf CD von einem der »Distributoren« für einen kleinen Unkostenbeitrag beziehen.
26
Geschichte und Umfeld von PHP
Sie dürfen die Software nicht nur benutzen, sondern auch anpassen, verändern, weiterentwickeln. Sogar die Programmierumgebungen, die Sie dazu benötigen, bekommen Sie kostenlos. Diese – zugegeben – anarchistisch und ungeordnet erscheinende Form der Entwicklung wirkt vielleicht befremdend auf Sie. Jenseits jugendlicher Hackersentimentalität und utopischer Gefühlsduselei spricht aber, auch vom kaufmännischen Standpunkt aus betrachtet, vieles für freie Systeme. Oft als Argument gegen freie Software wird die Problematik der Verantwortlichkeit und der Investitionssicherheit angeführt. Wir wollen niemandem unsere Ansicht verkaufen, nur der Hinweis, dass auch sehr große Firmen mittlerweile mit Linux und freier Software selbstverständlich arbeiten, sei uns gestattet. Die Problematik fehlenden Supports kann mittlerweile als moderne Sage angesehen werden. Die meisten Distributoren leisten gegen geringes Entgelt oder sogar kostenfrei Unterstützung, und daneben wird Ihnen im Internet die Hilfsbereitschaft einer riesigen Fangemeinde zugute kommen. Im Moment arbeiten Hunderttausende freiwillige Entwickler an der Weiterentwicklung freier Software im Linux-Umfeld. Dieses Potential kann keine kommerzielle Softwarefirma für Sie zur Verfügung stellen. Sie können an späterer Stelle zum Thema freie Software und der dahinterstehenden Philosophie noch mehr erfahren, wenn Sie möchten.
2.4.3
Was braucht man, um mit PHP zu arbeiten? PHP kann auch standalone verwendet werden, ist aber für ernsthafte Skriptprogrammierung nicht mächtig genug. Immerhin besteht die Möglichkeit, in PHP automatisiert z.B. HMTL-Seiten erstellen zu lassen. Die wirklichen Stärken von PHP zeigen sich allerdings erst im Server-Client-Umfeld des Internet. Weniger abstrakt ausgedrückt: PHP ist eine Sprache fürs Web und sollte auf einem Webserver aufsetzen. Sie benötigen also einen geeigneten Webserver (den Sie lokal auf Ihrem System installieren) und, sofern Sie Datenbankanbindungen realisieren wollen, natürlich auch eine Datenbank. LAMP und WAMP Die Entwicklung von PHP ist eng mit dem Server Apache und dem Betriebssystem Linux verknüpft. Da PHP besonders gut geeignet ist, auf Datenbanken zuzugreifen, und sich als frei verfügbare und schnelle Datenbank MySQL in der Entwicklergemeinde großer Beliebtheit erfreut, kam es zu einer Abkürzung, die mittlerweile als fester Begriff existiert: LAMP ist die Abkürzung für »Linux, Apache, MySQL, PHP«. Es ist die häufigste und gebräuchlichste Konfiguration. Falls Sie Apache, MySQL und PHP auf der Windows-Plattform einsetzen, spricht man naheliegender Weise von WAMP.
Kapitel 2 • PHP 4 – Einsatzmöglichkeiten und Hintergrund
27
Ein Sonderfall: LAMPS Wie Sie vielleicht wissen, sind Übertragungen im Internet nicht sonderlich sicher. Tatsächlich kann im Grunde genommen jeder Datenaustausch im Internet abgefangen und mitgelesen werden. Solange es sich dabei um harmlose Daten handelt, spielt dies auch keine große Rolle. Schwieriger ist es, wenn Sie vertrauliche Daten versenden, zum Beispiel die Daten Ihrer Kreditkarte u.ä. In diesem Fall benötigen Sie Schutz vor der Einsicht Fremder. Apache bietet dazu die Möglichkeit an, SSL (Secured Socket Layer) zu aktivieren. Sie benötigen dazu eine speziell gepatchte Version des Apache, die Sie unter http://www.apache-ssl.org/ bekommen. Der Unterschied zwischen normalen Seiten und solchen, die über SSL angefordert werden, liegt darin, dass zum Transport nicht das normale HTTP-Protokoll, sondern ein sicheres Übertragungsverfahren angewandt wird. Die Details dazu finden Sie in der Dokumentation des Apache. Seiten über SSL werden mit demselben Servernamen, aber über das Protokoll https aufgerufen. Um also eine sichere Verbindung zum Apache aufzubauen, wäre der nötige URL https://ihr.server.at/ihre.seite.html. Voraussetzung ist natürlich, dass Sie die SSL-Erweiterung installiert haben. Wir gehen im Anhang B noch darauf ein. LAMP-Server, die zusätzlich SSL verwenden, werden mit dem Ausdruck LAMPS (Linux, Apache, MySQL, PHP, SSL) bezeichnet. Sie finden solche Server dort, wo vertrauliche Daten geschützt übertragen werden sollen.
2.4.4
Wo bekommen Sie die Software? Apache, PHP, Linux Die Installationsdateien für Apache und PHP finden Sie auf der beiliegenden CD bzw. in der aktuellsten Version unter http://www.apache.org/ bzw. http:// www.php.net/. Linux bekommen Sie kostenlos im Internet, oder Sie besorgen sich eine für Sie geeignete Distribution auf CD. Sie bekommen die Red-Hat-Distribution unter http://www.redhat.com/, die von SuSE unter http://www.suse.de/ und die Debian-Distribution unter http://www.debian.org/. MySQL MySQL steht seit dem 28. Juli 2000 mit der Version 3.23.19 (Beta) unter der GPL (Gnu Public License), ist also ab dieser Version frei verfügbar (und das für alle großen Plattformen). Aktuelle Versionen können Sie unter http:// www.mysql.com/ herunterladen, die zum Zeitpunkt der Drucklegung dieses Buches aktuelle Version 3.23.27 (Beta) finden Sie für die Plattformen Unix (Solaris), Linux, PowerPC und Windows auch auf CD. Sollten Sie mit den Bedingungen der GPL nicht vertraut sein, erfahren Sie alles Nötige unter http:// www.gnu.org/.
28
Geschichte und Umfeld von PHP
Unter Windows Analog zu LAMP gibt es eine ähnliche Kombination unter Windows mit dem schönen Namen WAMP. WAMP hat einige Nachteile gegenüber LAMP: Unter Windows stehen andere und weniger ausgereifte Sicherheits- und Benutzerverwaltungsmöglichkeiten zur Verfügung. Apache ist für Windows nicht so ausgereift wie unter Linux. Es gibt zeitlich befristete Windows-Lizenzen (NT) von Microsoft unter http:// www.microsoft.com/, die übrige Software finden Sie auf denselben Servern wie bei LAMP angegeben.
2.4.5
Geeignete Webserver Wenn Sie bis jetzt noch keinen Webserver auf ihrem lokalen System laufen hatten, sollten Sie erst einen installieren. Neben Apache, der das beste, aber auch das anspruchsvollste System darstellt, können Sie PHP mit einer Reihe anderer Webserver benutzen. Im Anhang wird die Installation vom PHP auf verschiedenen Servern beschrieben. Wir werden in diesem Buch noch mehrfach darauf hinweisen: Am meisten Spaß und Nutzen ziehen Sie bei der PHP-Programmierung unter einer Unixrespektive Linux-Umgebung. Aber auch unter Windows gibt es brauchbare Kombinationen. Windows: PWS, IIS, OmniHTTPd, Apache Sie können zum Einarbeiten unter Windows sowohl mit den verschiedenen Microsoft-Webservern wie IIS und PWS, als auch mit Omnicrons OmniHTTPd, als auch mit dem Windows-Port von Apache arbeiten. Dabei sollten Sie beachten, dass PHP unter Windows nicht als Apache-Modul arbeiten kann, was zu einem Verlust an Performance führt. Linux/Unix: Apache Wenn Sie sich zur Arbeit unter Linux oder einem kommerziellen Unix entscheiden, sollten Sie sich auch mit der Thematik der Benutzerrechte etc. auseinandersetzen. Unter Unix gibt es ebenfalls verschiedene Server, die in Frage kommen (Netscape Enterprise u.a.), wir gehen in diesem Buch allerdings nur auf den Apache ein, da dies der am häufigsten verwendete Server ist. Apache bekommen Sie kostenlos im Internet unter http://www.apache.org/. Unter Linux/Unix finden Sie ein ausgereiftes Rechte- und Benutzerverwaltungssystem vor. Dieses Konzept ist für Neulinge schwerer zu verstehen, ist aber bei vernetztem Arbeiten sinnvoll und wichtig. Die Tatsache, dass Windows erheblich unproblematischer in dieser Beziehung zu sein scheint, sollten Sie keineswegs als Vorteil ansehen. Einen Server im WAN ohne vernünftige Sicherheitskonzepte zu betreiben, ist einfacher, aber nicht besser.
Kapitel 2 • PHP 4 – Einsatzmöglichkeiten und Hintergrund
29
Server bei einem Provider Keinen Einfluss auf die Konfiguration haben Sie, wenn Sie Webspace nicht auf einem eigenen Server hosten, sondern bei einem Provider anmieten. Erkundigen Sie sich bitte bei Ihrem Provider, ob Ihr Server für die Arbeit mit PHP eingerichtet ist und ob Sie dort Zugriff auf eine Datenbank haben. Ebenfalls beachtenswert in diesem Zusammenhang ist, dass bei vielen Providern der Webserver unter den Benutzerrechten »Nobody« oder ähnliches läuft. Das bedeutet nicht, dass Sie Ihre Projekte nicht bei einem Provider hosten können, aber es bedeutet möglicherweise, dass Sie keine vernünftigen Benutzerrechte setzen können oder für bestimmte Aufgaben die Hilfe Ihres Providers benötigen. Das Problem umfassend zu schildern, würde ziemlich weit in das Thema Unix führen und wäre sicher nicht brauchbar, um jeden Einzelfall zu erfassen, daher auch hier der Rat, sich mit Unix zu beschäftigen und sich mit dem Provider in Verbindung zu setzen. Das Problem dabei ist übrigens nicht, Ihre Skripte zum Laufen zu bringen, sondern den Rest der Welt davon abzuhalten, Ihre Skripte zu benutzen, um auf dem Server Aktionen auszuführen, die Sie so nicht geplant haben. Ein Sicherheitsproblem also, dass Sie ganz genauso mit jedem CGI und mit Perl haben.
Kapitel 3 Syntax und Grammatik von Christian Cartus, Egon Schmid und Hartmut Holzgraefe
3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13
PHP in HTML einbinden 32 Trennung von Anweisungen 33 Kommentare 33 Variablentypen 34 Variablen-Initialisierung 34 Initialisierung von Arrays 35 Objekt-Initialisierung 35 Gültigkeitsbereiche von Variablen 36 Variable Variablen 38 Automatische Typenkonvertierung 38 Erzwungene Typenkonvertierung 39 Stringkonvertierung 40 Bestimmung der Variablentypen 40
32
PHP in HTML einbinden
Die PHP-Syntax lehnt sich sehr stark an die Programmiersprache C an. Einige Konzepte von Java und Perl haben die Syntaxgestaltung ebenfalls beeinflußt. Im folgenden Kapitel beschreiben wir Syntax und Grammatik der Sprache. Wenn Sie bis jetzt noch nie in einer Hochsprache programmiert haben, empfehlen wir Ihnen, sich ein Buch zum Thema Programmierung zuzulegen, noch besser wäre es, wenn Sie einen Bekannten haben, der programmieren kann und sich mit Ihnen zusammen einarbeiten will (PHP als soziale Komponente!).
3.1
PHP in HTML einbinden PHP wird im Gegensatz zu den normalen CGI-Programmen nicht als eigenständiges Programm ausgeführt, das HTML selbst produzieren muss. Der fundamentale Unterschied liegt darin, dass nicht HTML in die Programmiersprache eingebettet wird, sondern PHP in HTML eingebunden wird. Typischerweise heißen die Dateien dann nicht mehr .html oder .htm, sondern .php, .php3 oder .phtml. An dieser Dateiendung kann der Webserver erkennen, dass es sich um eine in PHP geschriebene Datei handelt, und ruft den PHP-Präprozessor auf, bevor die Datei an den Benutzer geschickt wird. Es gibt vier Möglichkeiten, wie Sie PHP-Code in HTML einbinden können: Sie verwenden das Tag . Dies ist die XML-konforme Version. Wenn Sie PHP in XML-Dokumente einbinden, sollten Sie diese Langform auf jeden Fall verwenden: ...
Dies ist normaler HTML-Code
hier geht es weiter mit HTML ...
Folgende (aus PHP/FI stammende historische) Kurzform ist defaultmäßig in PHP möglich: ...
Dies ist normaler HTML-Code
hier geht es weiter mit HTML ...
Da der Code damit nicht mehr XML-konform ist, sollte die Kurzform nur im Ausnahmefall verwendet werden. Bitte beachten Sie, dass PHP bei Ihrem Provider die Kurzform möglicherweise nicht interpretieren kann, da sie sich in der Konfigurationsdatei php3.ini (vgl. Anhang B) abschalten lässt. Zwar lässt sie sich unter PHP 3 dank der Funktion short_tags() wieder anschalten, allerdings ist diese inkompatibel mit PHP 4/ Zend.
Kapitel 3 • Syntax und Grammatik
33
Die Skript-konforme Version sieht so aus: ...
Dies ist normaler HTML-Code <script language="php"> echo "Hier wird PHP-Code ausgeführt";
hier geht es weiter mit HTML ...
Seit der PHP-Version 3.04 kann PHP auch die ASP-Tags interpretieren: ...
Dies ist normaler HTML-Code
hier geht es weiter mit HTML ...
3.2
Trennung von Anweisungen Die PHP-Anweisungen werden so wie in C oder in Perl mit einem Strichpunkt abgeschlossen. Das schließende Tag (z. B. ?>) beinhaltet auch das Ende der Anweisung. Die beiden folgenden Beispiele sind deshalb identisch: ... ...
3.3
Kommentare PHP bietet insgesamt drei verschiedene Möglichkeiten, Kommentare in den Quellcode einzufügen. Ein Kommentar kann wie in C, C++ oder JAVA mit der Zeichenfolge /* begonnen und mit */ in derselben oder einer späteren Zeile abgeschlossen werden. Ein mit wie in C++ oder JAVA mit // oder wie in PERL mit # begonnener Kommentar dagegen endet automatisch mit dem Zeilenende. ... ...
Ein ?>-Tag innerhalb eines Kommentars beendet trotz allem einen PHP-Codeblock.
3.4
Variablentypen PHP unterstützt die folgenden Variablen-Typen: •
Boolean kann nur die Werte true und false aufnehmen
•
Integer kann ganzzahlige Werte aufnehmen
•
Double kann Fließkommawerte aufnehmen
•
String kann eine Sequenz von ASCII-Zeichen, also Text, aufnehem
•
Array nimmt ein- und multidimensionale, indizierte oder assoziative Arrays
auf •
Object nimmt eine Instanz einer Klasse mit Eigenschaften und Methoden auf
Im Gegensatz zu C oder Java kennt PHP nur die sogenannten typenlosen Variablen. Der Typ einer Variablen wird normalerweise nicht vom Entwickler konkret bestimmt, sondern ergibt sich vielmehr aus dem Kontext. PHP wandelt automatisch zwischen den Typen hin und her, je nachdem wie es von den Ausdrücken benötigt wird. Dies ähnelt sehr der Variablenverwendung in Perl. Wenn Sie jedoch einen ganz bestimmten Typ benötigen, so können Sie mit der Funktion settype() eine explizite Typenkonvertierung durchführen. Beachten Sie jedoch, dass sich eine Variable in bestimmten Situationen unterschiedlich verhalten kann. Dies hängt vom Typ ab, welche die Variable zu dieser Zeit hat. Mehr Informationen hierzu sind in dem Abschnitt Typenkonvertierung zu finden.
3.5
Variablen-Initialisierung Variablen können Sie überall und zu jeder Zeit initialisieren. Sie müssen sie nicht zu Beginn des Skripts deklarieren. Um eine Variable zu initialisieren, wird ihr einfach ein Wert zugewiesen. Dabei wird der richtige Variablentyp gewählt, ohne dass Sie ihn angeben müssen. $a = 5; //legt einen Integer an $b = "Hallo Welt"; //legt einen String an $c = 5.2 //legt eine Fließkommazahl an
Kapitel 3 • Syntax und Grammatik
3.6
35
Initialisierung von Arrays Ein Array kann mit zwei verschiedenen Methoden initialisiert werden: durch das sequentielle Zuordnen von Werten und durch die Funktion array(). PHP unterstützt zwei Arten von Arrays: indizierte und assoziative Arrays. Um sequentiell Werte in ein indiziertes Array einzufügen, weist man dem Wert der Arrayvariablen einen leeren Index zu. Der Wert wird dann als letztes Element in das Array angehängt. Die folgenden drei Beispiele sind identisch: $namen[] = "Thomas"; $namen[] = "Daniel"; $namen[0] = "Thomas"; $namen[1] = "Daniel"; $namen=array("Thomas","Daniel");
Um Werte in einem assoziativen Array einzufügen, weist man dem Wert der Arrayvariablen einen Schlüssel zu. Die folgenden beiden Beispiele sind identisch: $namen["name1"] = "Thomas"; $namen["name2"] = "Daniel"; $namen=array("name1"=>"Thomas","name2"=>"Daniel");
Das letzte Beispiel ist etwas komplexer und zeigt die Erzeugung eines gemischten (assoziativen und indizierten) zweidimensionalen Arrays: $array2dim = array( "frucht" => array("a"=>"apfel","b"=>"birne","c"=>"rosine"), "zahlen" => array(1, 2, 3, 4, 5, 6) "werte" => array("eins", 5 => "zwei", "drei") );
3.7
Objekt-Initialisierung PHP bietet eine einfache Implementierung von Klassen. Um eine Instanz einer Klasse zu initialisieren, muss der new-Konstruktor verwendet werden. Dieser weist einer Variablen die Instanz zu: class foo { function do_foo() { echo "Das ist foo."; } } $bar = new foo; $bar -> do_foo ();
36
Gültigkeitsbereiche von Variablen
Näher Informationen über die Verwendung von Klassen und Instanzen finden Sie im Kapitel Klassen.
3.8
Gültigkeitsbereiche von Variablen Der Gültigkeitsbereich einer Variablen ist auf die Umgebung, in der sie definiert wurde, beschränkt. Zum großen Teil haben die Variablen in PHP nur eine beschränkte Gültigkeit. In benutzerdefinierten Funktionen ist die Variable nur innerhalb der Funktion gültig. Sie ist außerhalb der Funktion nicht bekannt und verliert auch nach dem Abarbeiten der Funktion ihre Gültigkeit. $a = 1; /* globaler Gültigkeitsbereich, ist aber nicht in test() bekannt */ function Test () { echo $a; /* referenziert eine lokale Variable */ } test ();
Dieses Skript wird keine Ausgabe erzeugen, weil sich die echo-Funktion auf die lokale Variable $a bezieht. Da diese Variable in der Funktion jedoch nicht initialisiert wurde, ist $a leer. Dies weicht von der Programmiersprache C ab. In C sind globale Variablen automatisch in Funktionen verfügbar, außer sie werden mit einer lokalen Variable gleichen Namens überschrieben. In PHP können globale Variablen auch innerhalb einer Funktion angesprochen werden: $a = 1; $b = 2; Function Summe () { global $a, $b; $b = $a + $b; } Summe (); echo $b;
Das Skript wird 3 ausgeben. Durch die Anweisung global werden global initialisierte Variablen in der Funktion sichtbar und können ausgelesen oder verändert werden. Eine weitere Möglichkeit, auf Variablen aus dem globalen Gültigkeitsbereich zuzugreifen, ist die Verwendung des in PHP definierten $GLOBALS-Arrays. Dieses Array besitzt eine Sonderstellung. Es ist sowohl im globalen Bereich als auch in Funktionen gültig. Das vorhergehende Beispiel kann nun auch so geschrieben werden: $a = 1; $b = 2; Function Summe () { $GLOBALS["b"] = $GLOBALS["a"] + $GLOBALS["b"]; }
Kapitel 3 • Syntax und Grammatik
37
Summe (); echo $b;
Das $GLOBALS-Array ist ein assoziatives Array. Dabei ist der Schlüssel der Variablenname und der Inhalt des Arrayelements der Wert. Ein weiteres wichtiges Merkmal, mit dem Sie einen Gültigkeitsbereich definieren können, sind die statischen Variablen. Eine statische Variable ist nur innerhalb einer benutzerdefinierten Funktion gültig und wird auch nicht ungültig, wenn die Funktion abgearbeitet wurde. Das Verhalten können Sie anhand des folgenden Beispiels sehen: function test () { $a = 0; echo $a; $a++; } test(); test();
Diese Funktion ist nicht besonders sinnvoll, da jedesmal, wenn sie aufgerufen wird, die Variable $a wieder auf 0 gesetzt wird. Die echo-Funktion wird jedesmal 0 ausgeben. Danach wird zwar $a um eins erhöht, aber da danach der Gültigkeitsbereich verlassen wird, verschwindet auch die Variable $a. Damit die Variable ihre Gültigkeit behält, muss man sie als statische Variable definieren: function test () { static $a = 0; echo $a; $a++; } test(); test();
Wenn nun die Funktion mehrmals aufgerufen wird, so wird der aktuelle Wert der Variablen ausgegeben und anschließend um eins erhöht. Der statischen Variablen können Sie einen Anfangswert zuordnen, der beim ersten Aufruf der Funktion initialisiert wird. Statische Variablen können Sie ganz gut für rekursive Funktionen einsetzen. (Eine rekursive Funktion ist eine Funktion, die sich selbst aufruft.) Achten Sie jedoch darauf, dass die Funktion auch ein Abbruchkriterium besitzt, denn sonst ruft sich die Funktion immer wieder selbst auf. Die folgende einfache Funktion zählt rekursiv bis 10: function test () { static $count = 0; $count++; echo $count; if ($count < 10) { test ();
38
Variable Variablen
} } test();
3.9
Variable Variablen Manchmal kann es überaus nützlich sein, variable Variablennamen einzusetzen: Ein Variablenname kann vergeben und dann dynamisch benutzt werden. Normale Variablen werden mit einem Operator wie dem folgenden verwendet: $a = "hallo";
Eine variable Variable benutzt den Wert einer Variablen als deren Namen. Im obigen Beispiel kann folglich "hallo" als Name einer Variablen benutzt werden. Dazu müssen Sie zwei Dollarzeichen ($$) voranstellen: $$a = "Welt";
Damit sind nun zwei Variablen definiert: $a enthält "hallo", und die Variable $hallo, der Inhalt der Variablen $a, enthält den Wert "Welt". Die Ausgabe der Variablen zeigt das folgende Beispiel: echo "$a ${$a}";
Das obige Beispiel und das folgende sind identisch: echo "$a $hallo";
Beide Beispiele geben "hallo Welt" aus. Um variable Variablen in Arrays benutzen zu können, müssen Sie auf das Eindeutigkeitsproblem achten. Wenn Sie zum Beispiel $$a[1] schreiben, so kann der Parser nicht selbständig feststellen, ob Sie nun $a[1] als Variable oder $$a mit dem Arrayindex 1 meinen. Dies können Sie umgehen, indem Sie den zusammengehörenden Teil mit einer geschweiften Klammer ({}) definieren. In diesem Fall gibt es dann zwei Möglichkeiten: ${$a[1]} und ${$a}[1].
3.10
Automatische Typenkonvertierung Wie bereits erwähnt, unterstützt PHP nur typenlose Variablen. Es werden keine ausdrücklichen Typdefinitionen für die Variablendeklaration verwendet. Der Typ einer Variablen wird durch den Kontext, in dem sie verwendet wird, bestimmt. Aus diesem Grund wird je nach Kontext eine automatische Typenkonvertierung durchgeführt, sofern dies notwendig erscheint. Ein Beispiel für die automatische Typenkonvertierung ist der Additionsoperator (+). Falls eine der Variablen eine Fließkommazahl ist, werden alle anderen Variablen, die bei dieser Additionsope-
Kapitel 3 • Syntax und Grammatik
39
ration beteiligt sind, als Fließkommazahlen konvertiert. Das Ergebnis ist natürlich auch eine Fließkommazahl. Das folgende Beispiel verdeutlicht die automatische Typenkonvertierung: $foo = "0"; // $foo ist eine Zeichenkette (ASCII 48) $foo++; // $foo ist die Zeichenkette "1" (ASCII 49) $foo += 1; // $foo ist jetzt eine Ganzzahl (2) $foo = $foo + 1.3; // $foo ist jetzt eine Fließkommazahl (3.3) $foo = 5 + "10 Rosen"; // $foo ist jetzt eine Ganzzahl (15) $foo = 5 + "10 Lilien"; // $foo bleibt eine Ganzzahl (15)
3.11
Erzwungene Typenkonvertierung Sie können allerdings auch eine Typenkonvertierung erzwingen. Dabei wird der Name des gewünschten Variablentyps einfach in runden Klammern vor die Variable geschrieben: $foo = 10; // $foo ist eine Ganzzahl $bar = (double)$foo; // $bar ist eine Fließkommazahl $foo = (string)$foo; // $foo ist jetzt ein String
Mit folgenden Variablentypen können Sie eine Typenkonvertierung erzwingen. Nicht jeder Typ lässt sich einwandfrei in einen anderen Typ konvertieren: (bool) oder (boolean) konvertiert in einen Wahrheitswert. Dies entspricht dem
Verhalten der empty()-Funktion. (int) oder (integer) konvertiert in eine ganze Zahl. Dies ist nur bei double und string sinnvoll. (real) oder (double) konvertiert in eine Fließkommazahl. Dies ist nur bei integer und string sinnvoll. (string) konvertiert in eine Zeichenkette. Dies ist nur bei double und integer
sinnvoll. (array) konvertiert in ein Array. Ein Objekt wird problemlos konvertiert, bei integer, double und string wird ein Array mit einem Arrayelement angelegt. (object) konvertiert in ein Objekt. Ein Array wird problemlos konvertiert, bei integer, double und string wird ein Objekt mit einer Eigenschaft angelegt.
Sie können auch alternativ die settype()-Funktion zur Typenkonvertierung einsetzen: $foo = 10; // $foo ist eine Ganzzahl settype($foo,"double"); // $foo ist jetzt eine Fließkommazahl int settype(mixed var, string type);
40
Stringkonvertierung
konvertiert die Variable var in den Typ type. Für type sind folgende Werte gültig: string, double, integer, array und object. Es wird 1 zurückgegeben, wenn die Konvertierung erfolgreich war, ansonsten 0.
3.12
Stringkonvertierung Bei der Konvertierung eines Strings in eine Zahl wird der String nach gewissen Regeln überprüft und der entsprechende Typ ausgewählt, in den er dann konvertiert wird. Der String wird in eine Fließkommazahl gewandelt, wenn die Zeichen ».«, »e« oder »E« enthalten sind. Sind diese Zeichen nicht enthalten, wird der String in eine ganze Zahl konvertiert. Der Wert wird durch den Anfang der Strings bestimmt. Wenn der String mit einem gültigen numerischen Wert beginnt, dann wird dieser Wert konvertiert und alle angehängten Zeichen ignoriert. Beginnt der String mit keinem numerischen Wert, dann wird auf den Wert 0 konvertiert. Zu den gültigen numerischen Werten zählen auch Vorzeichen, wenn sie einer oder mehreren Zahlen vorangestellt sind. Die Zeichenkette kann auch einen Dezimalpunkt und einen Exponenten enthalten. Ein Exponent wird dabei durch die Zeichen »e« oder »E« gekennzeichnet, gefolgt von einer oder mehreren Zahlen. Hier ein paar Beispiele, die diese Regeln verdeutlichen: $foo $foo $foo $foo $foo $foo
3.13
= = = = = =
1 1 1 1 1 1
+ + + + + +
"10.5"; // $foo ist eine Fließkommazahl (11.5) "-1.3e3"; // $foo ist eine Fließkommazahl (-1299) "bob-1.3e3"; // $foo ist eine ganze Zahl (1) "bob3"; // $foo ist eine ganze Zahl (1) "10 CDs"; // $foo ist eine ganze Zahl (11) "10 Blumen"; // $foo ist eine ganze Zahl (11); // obwohl die Zeichenkette ein 'e' enthält.
Bestimmung der Variablentypen Mit PHP können Sie den aktuellen Typ einer Variablen jederzeit ermitteln. Gerade durch die automatische Typenkonvertierung ist nicht zu jeder Zeit ersichtlich, welcher Typ gerade die Variable besitzt. Hierfür stellt PHP die folgenden Funktionen zur Verfügung: string gettype(mixed var);
gibt den Typ der Variable als String zurück: integer, double, string, array, object und unknown type. int is_boolean(mixed var);
gibt 1 zurück, wenn die Variable ein Wahrheitswert ist, ansonsten 0. int is_integer(mixed var);
gibt 1 zurück, wenn die Variable eine ganze Zahl ist, ansonsten 0.
Kapitel 3 • Syntax und Grammatik
41
int is_double(mixed var);
gibt 1 zurück, wenn die Variable eine Fließkommazahl ist, ansonsten 0. int is_string(mixed var);
gibt 1 zurück, wenn die Variable ein String ist, ansonsten 0. int is_array(mixed var);
gibt 1 zurück, wenn die Variable ein Array ist, ansonsten 0. int is_object(mixed var);
gibt 1 zurück, wenn die Variable ein Objekt oder eine Instanz ist, ansonsten 0.
Kapitel 4 Sprachbeschreibung von Christian Cartus, Egon Schmid, Hartmut Holzgraefe
4.1 4.2 4.3 4.4 4.5
Konstanten 44 Operatoren 45 Anweisungen 48 Benutzerdefinierte Funktionen Klassen 59
56
44
Konstanten
Die Skriptsprache von PHP besteht aus einer Reihe von Anweisungen und Operatoren. Eine Anweisung kann aus einer Zuweisung, einem Funktionsaufruf, einer Schleife, einer bedingten Verzweigung oder wiederum aus Anweisungen bestehen. Außerdem sind Anweisungen, die nichts machen (leere Anweisung) erlaubt. Jede Anweisung wird mit einem Semikolon abgeschlossen, um das Ende der Anweisung zu signalisieren. Anweisungen können durch Klammern zu Gruppen zusammengefaßt werden. Diese Gruppe von Anweisungen werden dann als einzelne Anweisung interpretiert. Die Sprachbeschreibung geht ausführlich auf die einzelnen Anweisungen ein und erläutert anhand von Beispielen die Verwendung dieser Anweisungen.
4.1
Konstanten In PHP können Sie Konstanten definieren. Konstanten unterscheiden sich von Variablen, indem sie nur einmal initialisiert werden können. Danach können sie nur noch ausgelesen werden. PHP liefert von Haus aus zwei reservierte Konstanten mit: __FILE__ und __LINE__. Sie enthalten den Dateinamen des Skripts und die aktuelle Zeile, in der sich der Parser im Skript befindet. Dies können Sie zum Beispiel für eine Fehlermeldungsfunktion verwenden:
Sie können allerdings auch eigene Konstanten definieren. Sie werden mit den Funktionen define() und undefine() definiert bzw. aufgehoben. Beachten Sie, dass die Konstanten ohne vorangestelltes $-Zeichen ausgelesen werden müssen. Das folgende Beispiel zeigt die Verwendung von Konstanten:
Kapitel 4 • Sprachbeschreibung
4.2
Operatoren
4.2.1
Zuweisungsoperatoren
45
Der grundlegende Zuweisungsoperator ist das Gleichheitszeichen. Dies bedeutet, dass man den rechten Ausdruck dem linken Ausdruck zuweist. $a = 5; // weise 5 der Variablen $a zu, $a enthält nun den Wert 5 $b = $a; // weise $b den Inhalt von $a zu, $b enthält nun den Wert 5
Durch Klammerung können Sie einige trickreiche Kombinationen verwenden: $a = ($b = 4) + 5; // $a wird nun mit 9 gleichgesetzt und // $b hat den Wert 4.
Zusätzlich zu den grundlegenden Zuweisungsoperatoren existieren auch sogenannte kombinierte Operatoren. Zu ihnen gehören die arithmetischen und Zeichenkettenoperatoren. $a += $b
addiert zu $a den Inhalt von $b $a -= $b
subtrahiert von $a den Inhalt von $b $a *= $b
multipliziert $a mit $b $a /= $b
dividiert $a durch $b $a %= $b
führt mit $a einen Modulus mit $b durch $a .= $b
hängt den String $b an $a an. $a $a $b $b
= 3; += 5; // $a wird zu 8, als ob man geschrieben hätte: $a = $a + 5; = "Hallo "; .= "Hier!"; // $b wird zu "Hallo Hier!", genauso wie $b = $b . "Hier!"; // funktionieren würde.
46
4.2.2
Operatoren
Arithmetische Operatoren PHP unterstützt alle gängigen arithmetischen Operatoren wie +, -, /, * und % (Modulus bzw. Rest): $a + $b
Addition: Summe von $a und $b. $a - $b
Subtraktion: der Rest, wenn man $b abzieht von $a. $a * $b
Multiplikation: das Produkt von $a und $b. $a / $b
Division: $a geteilt durch $b. $a % $b
Modulus: der Rest, der übrigbleibt, wenn man $a durch $b teilt. Die arithmetischen Operationen geben eine ganze Zahl zurück, wenn beide Operatoren ganze Zahlen sind. Das gleiche ist der Fall, wenn ein String zu einer ganzen Zahl umgewandelt wurde. Ist einer der Operatoren eine Fließkommazahl, dann wird eine Fließkommazahldivision durchgeführt. Strings können nur dann arithmetische Operationen durchführen, wenn sie in eine Zahl konvertiert werden können. Es kann eine abkürzende Schreibweise für die Erhöhung oder Erniedrigung einer Zahl um den Wert eins verwendet werden: $b = $a++
weist $b den Inhalt von $a zu und erhöht anschließend $a um eins. $b = $a--
weist $b den Inhalt von $a zu und erniedrigt anschließend $a um eins. $b = ++$a
erhöht $a ums eins und weist dann $b den neuen Inhalt von $a zu. $b = --$a
erniedrigt $a ums eins und weist dann $b den neuen Inhalt von $a zu.
4.2.3
Zeichenkettenoperatoren Es gibt zur Zeit nur die Verknüpfung von Zeichenketten: $a = "Hallo "; $b = $a . "Welt!"; // Dann ist $b = "Hallo Welt!"
Sie können keinen +-Operator für das Verknüpfen von Zeichenketten verwenden.
Kapitel 4 • Sprachbeschreibung
4.2.4
47
Bitoperatoren Mit Bitoperatoren können Sie bestimmte Bits einer ganzen Zahl gemäß der booleschen Algebra manipulieren. $a & $b
und: Bits, welche in beiden Variablen ($a und $b) gesetzt sind. $a | $b
oder: Bits, welche entweder in $a oder $b gesetzt sind. $a ^ $b
exklusiv oder: Bits, welche entweder nur in $a oder nur in $b gesetzt sind. ~ $a
nicht: Bits, welche in $a gesetzt sind, werden nicht gesetzt und umgekehrt. $a = 255; $b = $a & 128; // $b enthält nun 128 $b = $b | 1; // $b enthält nun 129
4.2.5
Logische Operatoren Logische Operatoren werden hauptsächlich bei Anweisungen, in denen Abfragen durchgeführt werden können (IF, FOR, WHILE usw.) eingesetzt. Im Gegensatz zu den Bitoperatoren kann das Ergebnis der Operation nur true oder false enthalten: $a and $b ; $a && $b
und: wahr, wenn $a und $b wahr sind. $a or $b ; $a || $b
oder: wahr, wenn $a oder $b oder beide wahr sind. $a xor $b
ausschließendes oder: wahr, wenn entweder $a oder $b wahr sind, aber nicht beide. ! $a
nicht: wahr, wenn $a nicht wahr ist. if (1 == $a || 2 == $a ) { echo "wahr"; } else { echo "falsch"; }
48
4.2.6
Anweisungen
Vergleichsoperatoren Vergleichsoperatoren werden dazu benutzt, um Werte miteinander zu vergleichen. Das Ergebnis des Vergleichs ist true oder oder false. Sie werden hauptsächlich bei Anweisungen, in denen Abfragen durchgeführt werden können (IF, FOR, WHILE usw.), eingesetzt: $a == $b
gleich: wahr, wenn $a gleich $b ist. $a === $b
vollkommen gleich: wahr, wenn $a gleich $b und vom gleichen Variablentyp ist. $a != $b
ungleich: wahr, wenn $a nicht gleich $b ist. $a !== $b
nicht vollkommen gleich: wahr, wenn $a nicht gleich $b oder von einem anderen Variablentyp ist. $a < $b
kleiner: wahr, wenn $a kleiner als $b ist. $a > $b
größer: wahr, wenn $a größer als $b ist. $a = $b
größer-gleich: wahr, wenn $a größer oder gleich $b ist.
4.3
Anweisungen
4.3.1
if Die IF-Anweisung ist eine der wichtigsten Anweisungen einer Sprache. Sie erlaubt das bedingte Ausführen von Anweisungen und Ausdrücken: if (operator) anweisung;
Wie dem obigen Abschnitt über Ausdrücke beschrieben, wird der Wahrheitswert des Operators ermittelt. Ist der Operator wahr, wird die nachfolgende Anweisung ausgeführt. Ist der Operator jedoch falsch, wird die Anweisung ignoriert. Das folgende Beispiel wird "A ist größer als B" ausgeben, wenn $a größer als $b ist:
Kapitel 4 • Sprachbeschreibung
49
if ($a > $b) print "A ist größer als B"; IF-Anweisungen können innerhalb von anderen IF-Anweisungen beliebig
geschachtelt werden. Um eine Anweisungsgruppe zu bilden, können Sie dabei die geschweiften Klammern ({}) verwenden: if ($a > $b) { if ($c $b && $c $b ist, ansonsten "A ist NICHT größer als B": if ($a > $b) { echo "A ist größer als B"; } else { echo "A ist NICHT größer als B"; }
Es gibt eine weitere Möglichkeit, eine ELSE-Anweisung zu realisieren. Sie ist jedoch nur für einen Spezialfall geeignet: $c = ( $a > $b ) ? $b : $a;
Diese Kurzschreibweise entspricht folgendem IF-ELSE-Konstrukt: If ($a > $b): $c = $b; else: $c = $a; endif;
50
4.3.3
Anweisungen
ELSEIF ELSEIF ist eine Kombination aus ELSE und IF. ELSEIF wird wie ELSE erst dann ausgeführt, wenn der Operator der IF-Anweisung falsch ist. ELSEIF erlaubt jedoch, einen weiteren Operator wie bei IF auszuführen. Ist dieser Operator wahr, so werden die nachfolgenden Anweisungen ausgeführt. Das folgende Beispiel zeigt die Anwendung von ELSEIF: if ($a > $b) { echo "A ist größer als B"; } elseif ($a == $b) { echo "A ist gleich groß wie B"; } else { echo "A ist kleiner als B"; }
Sie können ohne Probleme mehrere ELSEIFs hintereinander ausführen. Das erste ELSEIF, dessen Operator wahr ist, wird ausgeführt und die restlichen Anweisungen ignoriert. if ($a > $b) { echo "A ist größer als B"; } elseif ($a == $b) { echo "A ist gleich groß wie B"; } elseif ($a == $c) { echo "A ist gleich groß wie C"; } elseif ($b == $c) { echo "B ist gleich groß wie C"; } else { echo "A ist kleiner als B"; }
4.3.4
Alternative Syntax für IF-Anweisungen: IF(): ... ENDIF; PHP stellt einen alternativen Weg zur Verfügung, mit der Sie IF-Anweisungen gruppieren können. Dies ist aus Gründen der Übersichtlichkeit sinnvoll, wenn sie Ihre HTML-Blöcke innerhalb von IF-Anweisungen plazieren. Anstatt geschweifte Klammern zu verwenden, können Sie auch folgende Syntax einsetzen: A = 5
Die alternative Syntax kann auch auf ELSE- und ELSEIF-Anweisungen angewendet werden:
Kapitel 4 • Sprachbeschreibung
51
if ($a==5): echo "a equals 5"; echo "..."; elseif ($a==6): echo "a equals 6"; echo "!!!"; else: echo "a is neither 5 nor 6"; endif;
4.3.5
WHILE WHILE-Schleifen sind die einfachsten Schleifen, die PHP kennt. Die grundlegende Struktur einer WHILE-Schleife sieht so aus: WHILE (operator) { anweisungen; }
Die Bedeutung einer WHILE-Anweisung ist einfach. Sie gibt an, wie oft Anweisungen wiederholt ausgeführt werden sollen, solange der WHILE-Operator wahr ist. Der Operator wird zu Beginn eines jeden Schleifendurchlaufs überprüft. Solange der WHILE-Operator wahr ergibt, wird die Schleife komplett durchlaufen. Wenn der WHILE-Operator falsch ergibt, wird die Schleife verlassen. So wie bei der IFAnweisung, kann man mehrere Anweisungen in einer WHILE-Schleife mit geschweiften Klammern zusammenfassen. Sie können aber auch die alternative Schreibweise verwenden: WHILE (expr): statements; ... ENDWHILE;
Die beiden folgenden Beispiele sind identisch und geben die Zahlen von 1 bis 10 aus: /* Beispiel 1 */ $i = 1; while ($i 10) { break; } echo $i; $i++; } /* Beispiel 4 */ for ($i=1; $i
60
Klassen
In diesem Beispiel wird eine Klassendefinition mit dem Namen Warenkorb definiert. Die Klasse besteht aus dem assoziativem Array $items, das die Produkte im Warenkorb enthält, und zwei Funktionen, um Produkte in den Warenkorb zu legen oder zu entfernen. PHP unterstützt keine Schutzmechanismen wie private oder protected. Nun können Objekte (die auch Instanzen genannt werden) von dieser Klasse erzeugt werden. Dies wird mit dem Operator new gemacht: $warenkorb = new Warenkorb; $warenkorb -> add_item ("10", 1);
Dieses Beispiel erzeugt ein Objekt $warenkorb der Klasse Warenkorb. Die Funktion add_item() des Objekts wird aufgerufen, und ein Produkt mit der Artikelnummer »10« in den Warenkorb gelegt. Sie können Klassen ableiten. Die abgeleitete Klasse besitzt alle Variablen und Funktionen der Basisklasse und wird durch die Variablen und Funktionen der abgeleiteten Klasse erweitert. Dies geschieht mit dem extends-Schlüsselwort. class Noch_ein_Warenkorb extends Warenkorb { var $besitzer; function besitzer_eintragen ($name) { $this -> besitzer = $name; } }
Hier wird eine Klasse mit dem Namen Noch_ein_Warenkorb definiert, welche sämtliche Variablen und Funktionen der Klasse Warenkorb erbt. Zusätzlich wird die Variable $besitzer und die Funktion besitzer_eintragen() zur Verfügung gestellt. Man kann diesen Warenkorb dann wie oben beschrieben anwenden, aber zusätzlich einen Besitzer eintragen oder dessen Namen auslesen. Die Funktionen der Basisklasse können normal angesprochen werden: $ncart = new Noch_ein_Warenkorb; // $ncart -> besitzer_eintragen ("kris"); // print $ncart -> besitzer; // // $ncart -> add_item ("10", 1); // //
Erzeuge einen weiteren Warenkorb Gib dem Warenkorb einen Namen Gib den Namen des Besitzers des Warenkorbs aus Benutze die Funktionen des normalen Warenkorbs
Wenn Sie sich die obigen Klassendefinitionen anschauen, so werden Sie sehr oft die Variable $this finden. Die Variable $this spielt wie in anderen objektorientierten Sprachen eine wichtige Rolle. Um auf die Variablen und Funktionen innerhalb des Objekts zugreifen zu können, muss die Variable $this verwendet werden. $this verweist deshalb immer auf das eigene Objekt. Mit $this-> können Sie Variablen und Funktionen innerhalb des gerade benutzten Objekts anspre-
Kapitel 4 • Sprachbeschreibung
61
chen. Dies wird spätestens dann klar, wenn Sie mehrere Objekte derselben Klassendefinition erzeugen. Beachten Sie, dass Sie kein $-Zeichen einsetzen dürfen, wenn Sie eine Variable mit $this ansprechen möchten: $this->$besitzer; /* FALSCH!! */ $this->besitzer; /* RICHTIG. */
Sie können jeder Klasse einen Konstruktor hinzufügen. Ein Konstruktor ist eine Funktion in einer Klasse, die automatisch aufgerufen wird, wenn ein neues Objekt dieser Klasse erzeugt wird. Eine Funktion wird zum Konstruktor, wenn sie denselben Namen wie die Klasse besitzt: class Auto_Warenkorb extends Warenkorb { function Auto_Warenkorb() { $this -> add_item ("10", 1); } }
Die direkte Initialisierung von Membervariablen ist nur in PHP 3 uneingeschränkt möglich, in PHP 4 dürfen einer Variable in der var-Deklaration nur noch Konstanten zugewiesen werden. Die Initialisierung von Membervariablen innerhalb eines Konstruktors ist unter anderem deshalb eindeutig vorzuziehen. Es wird eine Klasse Auto_Warenkorb definiert, die von der Klasse Warenkorb abgeleitet ist und einen Konstruktor enthält. Der Konstruktor legt bei der Erzeugung des Objekts sofort ein Produkt in den Warenkorb. Konstruktoren können auch Argumente enthalten: Destruktoren sind auch in PHP 4 noch nicht implementiert. class Konstruktor_Warenkorb extends Warenkorb { function Konstruktor_Warenkorb ($item = "10", $num =1) { $this -> add_item ($item, $num); } } // Lege etwas in den Warenkorb $Normaler_Warenkorb = new Konstruktor_Warenkorb; // Und nun aber $Mein_Warenkorb = new Konstruktor_Warenkorb ("20", 17);
PHP 4 unterstützt zusätzlich den direkten Aufruf von Memberfunktionen einer Klasse mit Hilfe der Syntax klassenname::klassenfunktion();. Hiermit werden sowohl statische Methoden (die auch ohne Instanziierung eines Objektes der Klasse verwendet werden können) als auch insbesondere der Zugriff auf Methoden der Elternklasse ermöglicht. Das erste Beispiel zeigt dies anhand eines Konstruktors der abgeleiteten Klasse, der den Konstruktor der Elternklasse aufruft. Bei Instanziierung der Klasse test2 werden somit der Konstruktor von test2 sowie der Elternklasse test1 aufgerufen.
62
Klassen
Das zweite Beispiel zeigt, wie eine Funktion der Elternklasse überschrieben sowie von der abgeleiteten Klasse aufgerufen wird. Bei Aufruf der zur Klasse kind gehörenden Funktion test() wird zunächst diese ausgeführt, welche hier wiederum eine Funktion gleichen Namens aus der Elternklasse aufruft.
Bei Übergabe des Wertes 0 als Parameter wird als Ergebnis die Zahl 2 ausgegeben. Ebenfalls seit PHP 4 sind die Funktionen get_class(), get_parent_class(), is_subclass_of() sowie method_exists() verfügbar. Mit Aufruf der Funktion get_class($obj) erhält man den Namen der Klasse der in $obj angegebenen Objekt-Instanz, get_parent_class($obj) findet die Klasse, von der $obj abgeleitet wurde, während is_subclass_of($obj,$classname) prüft, ob $obj direkt oder indirekt von $classname abstammt. method_ exists($obj,$methode) überprüft, ob die in $methode angegebene Klassenfunktion zur Klasse $obj gehört. Diese Funktionen bieten damit Informationen über Klassen und Methoden zur Laufzeit des PHP-Skripts. So könnte z. B. eine Klassenfunktion in Abhängigkeit seiner Elternklasse eine jeweils andere Klassenfunktion aufrufen.
Kapitel 5 Parameterübergaben in PHP von Christian Cartus und Egon Schmid
5.1 5.2 5.3
Definition der Methoden GET und POST Mit GET Parameter übergeben 67 Formularverarbeitung mit POST 72
66
66
Definition der Methoden GET und POST
Einerseits können direkt über PHP Parameter in URLs mit der GET-Methode übergeben werden, andererseits können Sie mit den Methoden GET und POST auch den Inhalt von Formularen auswerten.
5.1
Definition der Methoden GET und POST Die GET- sowie die POST-Methode sind Bestandteile des Hypertext Transfer Protocols (HTTP), der eigentlichen Sprache des Web. Eine Methode ist ein HTTP-Befehl, der die erste Zeile einer Client-Anforderung einleitet. Es gibt zwei Methoden, die die Art der Bearbeitung eines Formulars definieren. Beide werden von PHP unterstützt. PHP ist hervorragend geeignet, um Formulare zu bearbeiten, und wird daher sehr gerne für diese Zwecke eingesetzt. PHP unterstützt dabei alle gängigen Formulareingabefelder. Die Namen der Formularfelder stehen der Folgeseite als entsprechende PHPVariablen zur Verfügung. Es ist in PHP gleichgültig, welche Formularelemente Sie einsetzen, denn bei der GET- oder POST-Methode werden nur die Daten der Übergabe analysiert. Solange diese Daten den vorgegebenen Gesetzmäßigkeiten entsprechen (siehe RFC 2068), können sie durch PHP in Variablen umgesetzt werden. Formulare dienen dazu, Interaktivität mit dem Besucher herbeizuführen. Sie können mit Formularen Eingaben des Users annehmen und verarbeiten. Zur Verarbeitung gibt es zwei Methoden:
5.1.1
GET-Methode Die GET-Methode wird von den Clients zur Auffindung und Darstellung von Dokumenten verwendet. Bei einer GET-Anforderung konstruiert der Client einen Ergebnis-URL, bestehend aus dem URL der aktuellen Seite mit dem Formular, gefolgt von einem Fragezeichen und den Werten der Eingabefelder und -objekte des Formulars. Diese Werte werden an ein ausführbares Skript oder Programm auf dem Server gesendet, das im ACTION-Attribut des Formulars festgelegt wurde. Das Skript oder Programm verwendet diese Informationen für beliebige weitere Aktionen wie Suchen und Aktualisieren von Datenbankinhalten. Als Ergebnis dieser Auffindung wird eine Seite an den Client zurückgesendet, die vom Server dynamisch erzeugt wurde.
5.1.2
POST-Methode Über die POST-Methode können in einer Client-Anforderung Daten an den Server gesendet werden. Diese Daten werden an ein Datenverarbeitungsprogramm gesendet, das auf den Server zugreift.
Kapitel 5 • Parameterübergaben in PHP
67
Die POST-Methode wird für viele Anwendungen verwendet. Im Gegensatz zur GET-Methode befinden sich die gesendeten Daten bei dieser Methode im BodyAbschnitt. Hat der Server diese Anforderung und die Header verarbeitet, werden die Daten des Body-Abschnitts an das Programm weitergegeben. Wie bei der GET-Methode wird eine Seite an den Client zurückgesendet, die vom Server dynamisch erzeugt wird und das Ergebnis der Anforderung beinhaltet.
5.2
Mit GET Parameter übergeben Die Methode GET eignet sich hervorragend zur Parameterübergabe in PHP. Dies erlaubt eine einfache Weitergabe von Informationen an nachfolgende Seiten eines Webservers. Der Austausch von Informationen über mehrere Webseiten hinweg ist bei der Entwicklung dynamischer Websites ein außerordentlich wichtiger Bestandteil. Im Gegensatz zur normalen CGI/Perl- oder ASP-Programmierung müssen die Übergabewerte in PHP nicht erst umständlich entschlüsselt und in Variablen abgelegt werden. Sie stehen als PHP-Variablen sofort zur Verfügung.
5.2.1
Parameterübergabe mit GET Bei der GET-Methode werden die Daten mit dem URL transportiert. Sie werden beim Surfen bestimmt schon folgende oder ähnliche URLs gesehen haben: http://www.firmaxy.de/cgi-bin/hallo?stunde=11&minute=47&begruessung=Christian
Der Aufbau eines solchen URL ist relativ einfach. Nach dem eigentlichen URL werden, beginnend mit einem »?«, die einzelnen Parameter angehängt. Der Aufbau eines Parameters besteht aus dem Variablennamen und dessen Wert. Die einzelnen Parameter werden mit "&" getrennt. Sie kennen diese Form der Parameterübergabe wahrscheinlich nur von Formularen mit anschließendem CGISkript. Bei PHP jedoch ist dies eine sehr angenehme Art und Weise, auch statische, also nicht durch Formulare erzeugte Informationen zu übertragen. Sie benötigen dafür kein Formular, sondern Sie setzen den URL mittels PHP zusammen. Das folgende Beispiel zeigt einen solchen typischen URL: Link
Wird nun dieser URL ausgeführt und die Folgeseite aufgerufen, bevor das PHPSkript gestartet wird, werden die Parameter ausgelesen und als Variablen angelegt. Sie können auf der Folgeseite diese Variablen direkt nutzen: $stunde enthält 11. $minute enthält 47. $begruessung enthält »Christian«.
68
Mit GET Parameter übergeben
Ein Beispiel für die Folgeseite: <TITLE> Hallo ,
Es könnte jetzt : Uhr sein!
Abbildung 5.1: Das Ergebnis der Übergabe im Browser
Die Variablen können sofort für die Ausgabe verwendet werden. Versuchen Sie einmal folgendes:
|
106
Einen E-Mail-Verteiler entwickeln
Abbildung 8.6: E-Mail-Adresse löschen
Die E-Mail-Liste wird nach dem bekannten Schema ausgelesen. Dabei wird eine Checkbox mit der E-Mail aufgebaut. Der Wert der Checkbox enthält ein Arrayelement-ähnliches Konstrukt mit der E-Mail als assoziativem Index. PHP macht auf der Folgeseite ein Arrayelement daraus. Dieses assoziative Array wird später beim Löschen sehr hilfreich sein. Wählt der Benutzer die entsprechenden E-Mails aus und schickt das Formular weg, so wird folgendes Skript ausgeführt: <TITLE> E-Mailfile nicht vorhanden oder defekt
gelöscht.
E-Mails gelöscht!
zurück
Es wird nun eine temporäre Datei zum Schreiben geöffnet. Diese Datei wird alle E-Mails aufnehmen, die noch in der Liste bleiben sollen. Nun wird aus der aktuellen Liste jede einzelne E-Mail ausgelesen. Diese E-Mail wird dann über das vom Formular übergebene $maildel[]-Array geprüft. Ist ein Eintrag vorhanden, so hat der Benutzer die entsprechende Checkbox angeklickt. Die E-Mail wird dann nicht in die temporäre Datei geschrieben. Alle anderen E-Mails werden in die temporäre Datei geschrieben. Ist das Ende der Datei erreicht, so werden beide Dateien geschlossen und die aktuelle Datei der Liste gelöscht. Anschließend wird die temporäre Datei zur aktuellen E-Mail-Liste umbenannt.
108
Einen E-Mail-Verteiler entwickeln
Abbildung 8.7: Bestätigung
Kapitel 9 Dateien und Benutzerrechte von Christian Cartus und Egon Schmid
9.1 9.2
Unix-Rechtesystem 110 Sicherheitsrisiken 112
110
Unix-Rechtesystem
In PHP können Sie auf sehr einfache Art und Weise Dateien im System erzeugen und bearbeiten. Hauptsächlich werden Sie damit bei der Verwendung von Dateifunktionen oder der Upload-Funktionalität in Berührung kommen. Unter Win 95 gibt es die Benutzerrechte nicht im klassischen Sinn, sodass diese vernachlässigt werden können (bzw. müssen). Für die Rechtevergabe unter Windows NT konsultieren Sie bitte die Dokumentation oder Microsofts Support. Im Folgenden bekommen Sie eine kleine Einführung in die Benutzerverwaltung und Rechtevergabe unter Unix. Wir empfehlen Ihnen zusätzlich, sich ein Buch zum Thema Unix zuzulegen, wenn Sie mit dem Thema noch nicht vertraut sind, z.B.: Brockmann, Lutz: »Jetzt lerne ich Unix«, Markt+Technik 1999, ISBN 3-827225520-1. Ein recht bekanntes und beliebtes, speziell auf Linux zugeschnittenes Buch ist: Kofler, Michael: »Linux – Installation, Konfiguration, Anwendung«, Addison Wesley, 5. Aufl., 2000. ISBN 3-8273-1658-8.
9.1
Unix-Rechtesystem Jede Datei besitzt einen Benutzer und eine Gruppenzugehörigkeit. Gruppen sind eine Zusammenfassung von mehreren Benutzern, die einen logischen Zusammenhang haben (z.B.: staff für Mitarbeiter). Das Rechtesystem von Unix unterscheidet hier zwischen drei Rechtestufen: user
der Benutzer selbst group
die Gruppe, in der der User zugehörig ist other
alle anderen Benutzer und Gruppen Es gibt im Groben drei verschiedene Rechte, die gesetzt werden können: Lesen, Schreiben und Ausführen, und zwar getrennt für den User, die Gruppe und other (also andere, d.h. jeden). Um eine Datei für jeden lesbar, schreibbar und ausführbar zu machen, müssen also die Rechte folgendermaßen gesetzt werden: rwxrwxrwx (r = readable, w = writable, x = executable). Es gibt alternativ die oktale Schreibweise, bei der die Rechte durch Zahlen definiert sind. In diesem Fall steht 4 für readable, 2 für writable und 1 für executable. Soll mehr als ein Recht vergeben werden, werden die Zahlen addiert. Schreib-
Kapitel 9 • Dateien und Benutzerrechte
111
und Leserecht werden also mit der Zahl 6 ausgedrückt, 7 bedeutet volles Zugriffsrecht auf die Datei. Unser obiges Beispiel mit vollem Zugriffsrecht für jeden lautet also in der oktalen Schreibweise: 777. Dieses volle Zugriffsrecht hat es in sich: Jeder beliebige Benutzer des Systems darf so eine Datei auslesen, verändern und ausführen. Anders gesagt: Sie öffnen mit solchen Dateien Sicherheitslöcher im System. Aus diesem Grund sollten Sie niemals einer Datei höhere Rechte zuordnen, als im Moment gerade notwendig. Paranoia ist in diesem Zusammenhang keine negative Eigenschaft eines Systemverwalters. Eine Datei, die vom Besitzer (User) voll verwendet werden darf, aber anderen Usern derselben Gruppe und Fremden nur Lese- und Schreibrecht gewährt, hat die Rechte 755 oder rwxrw-rw-. Eine Datei, die nur gelesen werden soll, wäre mit den Rechten 444 oder r--r--r-- gut versorgt. Ich denke, das Prinzip ist klar. Um Dateien andere Rechte zu geben, benutzt man den Befehl chmod, um Dateien anderen Gruppen zuzuweisen, verwendet man chgroup. Sie können keine höheren Rechte vergeben, als Sie selber als User im System haben, und Sie können Dateien nur Gruppen zuweisen, in denen Sie entsprechend privilegiert sind. In der Praxis bedeutet dies, dass Sie nicht in der Lage sind, auf virtuellen Domains alle administrativen Eingriffe vorzunehmen, da Sie selber (vermutlich) keinen root-Account besitzen. Webserver laufen i.a. als Nutzer nobody o.ä. und haben aus Gründen der Sicherheit selber nur eingeschränkte Rechte auf dem System. Wenn Sie selber einen Server stehen haben und einrichten, dann beachten Sie bitte dringend die Sicherheitsaspekte. Einen öffentlichen Server mit zu hohen Rechten zu versehen, entspricht einem virtuellen Suizid. Nähere Informationen erhalten Sie in den Man-Pages unter Linux/Unix und in der Dokumentation ihrer Distribution. Hinweis Bei der Apache-Modulinstallation übernimmt PHP den Benutzer und die Gruppe von Apache. PHP übernimmt User und Gruppenrechte von Apache. Genau dieser Umstand kann nun beim Erzeugen oder Bearbeiten von Dateien zu Rechtekonflikten führen. Alle Verzeichnisse werden ebenfalls (wie die Dateien) mit dem Rechtesystem verwaltet. Möchten Sie eine Datei erzeugen oder löschen, muss das Verzeichnis mindestens das Schreibrecht besitzen. Ist dies nicht der Fall, so schlägt dieser Versuch fehl. Dies kann genau dann vorkommen, wenn Ihr Verzeichnis im Webbereich einem anderen Benutzer oder einer anderen Gruppe als PHP zugehört und das Verzeichnis kein Schreibrecht für group oder other besitzt.
112
Sicherheitsrisiken
Dasselbe gilt für die Erzeugung oder das Löschen von Verzeichnissen. Beim Schreiben oder Lesen einer Datei sollten Sie auf die entsprechenden Schreib- und Leserechte der Datei achten. Es gibt mehrere Möglichkeiten, dieses Problem zu beheben: 1. Wenn Sie der Benutzer der Datei oder des Verzeichnisses sind und die Gruppe falsch ist, reicht ein einfacher Unix-Befehl, um dies dauerhaft zu beheben: chgrp . 2. Wenn Sie nicht Besitzer der Datei oder des Verzeichnisses sind, so können Sie nur noch Ihren Administrator bitten, Ihnen die Besitzer- und Gruppenrechte zu geben. Die Problematik ist, dass Sie einerseits ausreichende Rechte für Verzeichnisse und/oder Dateien zuweisen müssen, um überhaupt damit arbeiten zu können, andererseits aber diese Rechte zu Sicherheitsproblemen führen können.
9.2
Sicherheitsrisiken Wenn Sie im Web-Onlinebereich mit Dateien arbeiten, so besteht immer die Gefahr, dass Webbenutzer sich unbefugten Zugang zu diesen Daten verschaffen können oder diese gar manipulieren. Auch das oben genannte Rechteproblem birgt Risiken. Wenn Sie z.B. wegen der verschiedenen Benutzer- und Gruppenverteilungen other-Rechte verwenden müssen, so birgt dies das Risiko, dass auch Webbenutzer auf diese Daten zugreifen können. Vor allem, wenn Ihre Dateien im WebOnlinebereich liegen, sind sie sehr einfach über den URL auszulesen. Es gibt verschiedene Lösungsansätze: Speichern Sie Dateien immer außerhalb des Web-Onlinebereichs. Damit verhindern Sie effektiv den Zugriff über den Webserver. Diese Methode funktioniert nur, wenn Sie selber Serveradmin sind und frei walten und schalten können.
Gerade bei Providern ist es meist nicht möglich, außerhalb des Online-Webbereichs Dateien abzulegen (weil Sie nur auf Ihren Bereich Zugriff haben, und dieser komplett über das Netz erreichbar ist). Um trotzdem einen unbefugten Zugriff zu vermeiden, können Sie einen Trick anwenden, der bei wenig frequentierten Seiten gut funktioniert.
Kapitel 9 • Dateien und Benutzerrechte
113
Der Trick besteht also einfach darin, die Benutzerrechte nur für den Augenblick der Bearbeitung zu erhöhen und danach wieder herabzusetzen. Im obigen Beispiel also auf Lesen und Schreiben für jeden (666), danach auf keinerlei Zugriff (auch nicht lesend) für irgendjemanden (000). Welche Benutzerrechte Sie im konkreten Fall brauchen, kann von diesem Beispiel erheblich abweichen.
Kapitel 10 MySQL und PHP von Wolfgang Drews (MySQL) und Christian Wenz (ODBC)
10.1 10.2 10.3 10.4 10.5 10.6
Grundlagen 116 Arbeiten mit MySQL für Fortgeschrittene 132 Beispiel einer Datenbankanwendung 148 MySQL Datentypen 158 PHPs MySQL-Funktionen 162 ODBC 196
116
Grundlagen
In diesem Kapitel werden in der nötigen Kürze das Datenbanksystem MySQL und sein Zusammenspiel mit PHP beschrieben. Ein vollständiger Einblick in die Materie kann und soll nicht Ziel dieses Kapitels sein. Vielmehr soll dem Anfänger ein einfacher Einstieg ermöglicht und dem Fortgeschrittenen einige interessante Möglichkeiten von MySQL aufgezeigt werden. Begonnen wird mit einem theoretischen Einstieg in das Datenbanksystem MySQL (Abschnitt 10.1). Wer mehr zur Theorie von Datenbanken erfahren will, der sei auf die einschlägige Literatur verwiesen. Besonders hervorzuheben in puncto MySQL ist (zum Zeitpunkt des Erscheinens dieses Buches) das Buch »MySQL« von Paul DuBois (Markt + Technik, 2000). Anschließend werden die Grundlagen von MySQL dargestellt. Sie werden lernen, Datenbanken zu erstellen und mit ihnen zu arbeiten. Dabei verfolgt dieser Abschnitt einen etwas ungewöhnlichen Ansatz. Im Gegensatz zur gängigen Literatur werden Sie sowohl mit dem MySQL-Monitor (einem Standardprogramm von MySQL) arbeiten als auch begleitend dazu SQL-Abfragen mittels PHP ausführen. Im Abschnitt 10.2 des Kapitels wird ausführlicher auf die MySQL-Materie eingegangen. Sie werden lernen, »intelligente« Anfragen an eine Datenbank zu richten und auf diese Weise Einblick in die verschiedenen Möglichkeiten von MySQL bekommen. Im Abschnitt 10.3 werden Sie anhand einer Datenbankanwendung das zuvor Erlernte mit PHP umsetzen. Die letzten zwei Abschnitte sind der Referenz gewidmet. Hier erhalten Sie die Typenreferenz von MySQL (Abschnitt 10.4) und PHPs MySQL-Funktionen auf einen Blick (Abschnitt 10.5).
10.1
Grundlagen Seit der ersten Auflage dieses Buches hat sich auf dem Sektor Datenbanken und PHP viel getan. PHP unterstützt von Haus aus eine große Anzahl von Datenbanksystemen. Dennoch hat sich MySQL zu der Datenbank für PHP-Anwendungen entwickelt. Ca. 70% aller PHP-Programmierer arbeiten derzeit mit MySQL.
10.1.1 Was ist eine Datenbank? Auf theoretische Grundlagen der Datenbanken wie »relationale Modelle« oder »Datennormalisierung« kann an dieser Stelle nicht eingegangen werden. Die Theorie von Datenbanksystemen sollten Sie in einem dafür vorgesehenen Lehrbuch nachschlagen. Sie sollten eine ungefähre Vorstellung davon haben, was eine Datenbank ist und wie sie aufgebaut ist. Im Grunde ist eine Datenbank, einfach gesagt, nichts anderes als ein Container, der in sogenannten Tabellen strukturierte Daten in sich
Kapitel 10 • MySQL und PHP
117
beherbergt. Tabellen bestehen aus Spalten und Zeilen. Tabellen können nun wiederum untereinander verschiedene Beziehungen (Relationen) haben. Dadurch wird aus einer Datenbank eine relationale Datenbank.
10.1.2 Was ist MySQL? MySQL ist ein sogenanntes RDBMS, ein »Relational Database Management System«, vereinfacht ausgedrückt ein System, das oben beschriebene Funktionalität zur Verfügung stellt. An dieser Stelle soll der Frage nachgegangen werden, warum MySQL sich so schnell zu dem etabliertesten Datenbanksystem für PHPProgrammierer entwickelt hat. In diesem Zusammenhang sind mehrere Punkte anzuführen: MySQL ist: •
schnell
•
einfach zu benutzen
•
kompatibel mit vielen Betriebssystemen wie UNIX und Windows
•
auf den meisten Webservern im Einsatz bzw. lauffähig
•
Open Source Software; seit der Version 3.23.19 steht das MySQL-RDBMS unter GPL
•
sehr gut dokumentiert und z.B. durch diverse Mailinglisten gut unterstützt
•
in Kombination mit PHP ein perfektes Paar, da die Entwickler von MySQL und PHP 4 sehr eng zusammenarbeiten.
Besonders der gute Support hat dazu beigetragen, dass MySQL in Verbindung mit PHP derart populär geworden ist.
10.1.3 Ein kurzer Einstieg in (My)SQL Im Folgenden werden die grundsätzlichsten SQL-Anweisungen erläutert. In diesem Zusammenhang soll eine einfache Datenbank mit Tabellen erstellt werden. Darüber hinaus werden einige einfache Abfragen (Queries) über die Datensätze ausgeführt werden. Sie werden lernen, sowohl mit dem MySQL-Monitor zu hantieren als auch parallel dazu die passenden PHP-Skripten zu erstellen. Fortgeschrittene können diesen Teil getrost überspringen. Vorüberlegungen Jeder Datenbank geht eine mehr oder weniger intensive Planungsphase voraus. Die richtige Planung von Datenbanken, d.h. ihre Modellierung, ist unverzichtbar. Sie sollten sich unbedingt daran gewöhnen, »sauber« vorzugehen und diesen Schritt nicht zu vernachlässigen.
118
Grundlagen
Zu Beginn der Datenbankmodellierung sollten Sie sich u.a. fragen, welche Daten erfasst werden sollen und wie diese zu strukturieren sind. In dem vorliegendem Beispiel wurde ein einfaches »Community-Beispiel« gewählt, d.h. auf der Webseite soll eine Gemeinschaft aufgebaut werden, in die der Benutzer sich eintragen (registrieren) kann, um Mitglied in der Community zu werden. Überlegen Sie sich, welche Daten Sie von dem Benutzer brauchen. In unserem Fall wären das Name, Vorname, Geburtstag, E-Mail- und Postadresse, Passwort, Anzahl der Besuche und Datum des letzten Besuches. Der Einfachheit halber werden wir uns zunächst auf drei Datenfelder beschränken: Name Vorname E-Mail
Nun haben Sie für das einführende Beispiel genug Informationen, um zu beginnen. Der MySQL-Monitor Die folgenden Anweisungen werden wir auch mit dem MySQL-Programm MySQL-Monitor durchführen. Um es aufzurufen, tippen Sie in der UNIX-Shell % mysql -h Hostname -u Username -p Passwort
bzw. wechseln unter Windows in das Verzeichnis c:\mysql\bin\ und geben dort c:\mysql\bin>mysql -h Hostname -u Username -p Passwort
ein. (Ich gehe hier davon aus, dass Sie MySQL standardmäßig auf Windows in c:\mysql installiert haben) Wenn Sie MySQL auf Ihrem eigenen Rechner installiert haben (für Anfänger ist diese Variante zu empfehlen), dann stellen die Benutzer-Optionen -h Hostname -u Username (Benutzername) -p Passwort
kein weiter aufregendes Problem für Sie da. Geben Sie als Hostnamen einfach Ihren lokalen Server an (meistens: 127.0.0.1 oder localhost), als Username root und als Passwort ihr gewähltes Passwort bzw. lassen Sie diese Option einfach weg, wenn Sie kein Passwort gewählt haben. Die Host- und Userangabe ist ebenfalls nicht zwingend. Auf die Administration von MySQL kann hier leider nicht eingegangen werden, da das den gesteckten Rahmen sprengen würde.
Kapitel 10 • MySQL und PHP
119
Damit rufen Sie den MySQL-Monitor auf, und es sollte eine ähnliche Ausgabe wie hier erscheinen: C:\mysql\bin>mysql Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1 to server version: 3.23.21-beta-debug Type 'help' for help. mysql>
Beim MySQL-Monitor handelt es sich um ein einfaches Kommandozeilen-Programm, mit dem Sie – zugegeben auf etwas unbequeme Weise – Ihre MySQLDatenbanken administrieren können.
10.1.4 Verbindung mit der Datenbank aufnehmen Das folgende Beispiel zeigt, wie Sie mittels PHP Verbindung zu MySQL aufnehmen können.
Dieses Beispiel erfüllt nur den Zweck der Verbindungsaufnahme. Wenn alles glatt ging, sollte in Ihrem Browser die »Glückwunschmeldung« sowie die Verbindungskennung sehen. Die Verbindungskennung benötigen Sie, um bei »späteren« Anfragen jeweils den Bezug zur Verbindung herstellen zu können. Die Verbindung zu MySQL wird in unserem Beispiel mit der Funktion mysql_pconnect() hergestellt. Um Verbindung zum MySQL-Server aufzunehmen, gibt es eine weitere Funktion. Im Folgenden sollen beide Funktionen erläutert werden: mysql_connect() int mysql_connect([string Hostname[:port][:/path/to/socket]] [, string Benutzername] [, string Passwort])
Die Funktion öffnet eine Verbindung zum MySQL-Server. Im Erfolgsfall erhalten Sie eine Verbindungskennung, im Fehlerfall false bzw. 0 zurück. Alle Argumente, die Sie mit der Funktion übergeben, sind optional, d.h. Sie können Sie weglassen und werden in den meisten Fällen trotzdem eine Verbindung erhalten (als Hostname wird dann einfach localhost [127.0.0.1], als Benutzername der Name des Benutzer des Serverprozesses und als Passwort ein leeres Passwort angenommen).
120
Grundlagen
Fehlermeldungen können Sie mit vorangestelltem »@« unterdrücken. Die Verbindung wird mit Ende des PHP-Skripts oder mit der Funktion mysql_close() geschlossen. mysql_pconnect() int mysql_pconnect([string Hostname[:port][:/path/to/socket]] [, string Benutzername] [, string Passwort])
Die Funktion verhält sich ähnlich wie mysql_connect(). Die einzigen Unterschiede bestehen darin, dass vor dem Verbindungsaufbau eine möglicherweise schon geöffnete Verbindung (mit gleichen Benutzerdaten) gesucht wird und eine damit geöffnete Verbindung nicht am Ende des PHP-Skripts oder durch die Funktion mysql_close() beendet wird. Daher wird eine solche Verbindung persistent genannt. Ein persistenter Verbindungsaufbau bleibt ohne Wirkung, wenn Sie PHP als CGIVersion laufen haben. Das ist bei den meisten Windows-Umgebungen der Fall. Da Windows meistens nur als Entwicklungsumgebung genutzt wird, der eigentliche Produktionsserver jedoch auf einer UNIX-Umgebung läuft (und hier meistens PHP als Modul in den Apache einkompiliert ist) sollten Sie – soweit möglich – die Funktion trotzdem benutzten. Auf dem Produktionsserver wird sich dies in der Datenbankperformance positiv auswirken und auf Windows werden Sie deswegen keine Fehlermeldung erhalten. Erhalten Sie beim Ausführen des Beispielskripts eine Fehlermeldung, sollten Sie versuchen, diesen Fehler zuerst zu beseitigen, bevor Sie weitermachen. Überprüfen Sie dabei folgende Punkte: •
Haben Sie den MySQL-Daemon gestartet?
•
Haben Sie zur Verbindungsaufnahme die richtigen Verbindungsdaten (Hostname, Username und Passwort) angegeben ?
•
Stimmt der Port, auf dem Sie MySQL ansprechen ? Standardmäßig ist dies der Port 3306. Wurde er geändert, müssen Sie ihn auch im Skript ändern. Geben Sie hierzu einfach nach dem Hostnamen einen Doppelpunkt und dann den richtigen Port an.
10.1.5 Erstellen einer Datenbank Erstellen einer Datenbank mit Hilfe des MySQL-Monitors Legen Sie als Erstes die oben besprochene Datenbank »Community« mit der CREATE DATABASE-Anweisung an: mysql> create database community; Query OK, 1 row affected (0.05 sec) mysql>
Kapitel 10 • MySQL und PHP
121
Achten Sie darauf, Anweisungen mit einem Semikolon abzuschließen. Die Anweisung CREATE DATABASE Datenbankname dient der Erzeugung einer Datenbank, der Parameter Datenbankname gibt der Datenbank ihren Namen. Um mit der soeben erstellten Datenbank Community arbeiten zu können, müssen Sie diese mittels der USE-Anweisung zu Ihrer aktuellen Datenbank machen: mysql> use community; Database changed mysql>
Jetzt können Sie mit der Datenbank Community arbeiten. Legen Sie mit den oben aufgelisteten Daten eine Tabelle an. mysql> create table members ( -> vorname varchar(30) not null, -> name varchar (30) not null, -> email varchar (30) not null, -> memid int unsigned not null auto_increment primary key); Query OK, 0 rows affected (0.11 sec) mysql>
Erläuterung der obigen Anweisung: Die Anweisung CREATE TABLE Tabellenname erzeugt eine Tabelle mit dem Namen members. In Klammern stehen die einzelnen Deklarationen, welche Spalten in der Tabelle vorhanden sein, und von welchem Typ sie sein sollen. Das vorliegende Beispiel enthält beispielsweise den Spaltennamen vorname, der vom Typ VARCHAR sein soll. Für eine Übersicht über die von MySQL zur Verfügung gestellten Typen sei auf den Abschnitt 10.4 dieses Kapitels verwiesen. Die hier verwendeten Typen werden im Folgenden kurz erläutert: •
INT/VARCHAR: Typ, von dem der Wert sein soll. INT steht für einen ganzzahligen Wert, VARCHAR für eine Zeichenkette mit variabler Länge. Der in Klammern ste-
hende Wert gibt die maximale Länge der Zeichen (Wertebereich), die eingegeben werden können, an. Nachfolgend werden die im Beispiel verwendeten Attribute erläutert: •
UNSIGNED: erlaubt keine negativen Werte.
•
NOT NULL (/ NULL): Dieses Attribut zeigt MySQL an, ob der Wert NULL erlaubt ist oder nicht. Wenn Sie NOT NULL bei der Tabellendefinition angeben, wird MySQL eine Anweisung nicht ausführen, wenn für diese Spalten kein Wert angegeben wurde. Daher sollten Sie nur solche Spalten mit NOT NULL kennzeichnen, von denen Sie glauben, dass sie unbedingt einen Wert enthalten müssen.
122
Grundlagen
Möchten Sie trotzdem NOT NULL verwenden, sollten Sie einen DEFAULT-Wert angeben. Dieser wird immer dann eingefügt, wenn kein expliziter Wert angegeben wurde. •
AUTO_INCREMENT: Diese Option bewirkt, das der Wert memid bei jedem Eintrag automatisch um 1 erhöht wird. So werden Inkonsistenzen verhindert, d.h. jeder Datensatz wird eindeutig identifizierbar.
•
PRIMARY KEY: Dies ist der Schlüssel, anhand dessen ein Datensatz eindeutig identifiziert werden kann. Für den Primary Key kommt grundsätzlich jede Spalte in Frage. Sie sollten jedoch darauf achten, eine sinnvolle (eindeutige) Spalte auszuwählen. Pro Tabelle können Sie nur einen Primary Key erstellen.
Wenn Sie alles wie oben eingegeben haben, werden Sie unter Umständen merken, dass der MySQL-Monitor relativ unkomfortabel ist. Haben Sie die Eingabetaste gedrückt, können Sie nicht mehr in die zuvor eingegebene Zeile zurückspringen, um Fehler zu korrigieren. Sollten Sie sich in einer abgeschlossenen Zeile vertippt haben, müssen Sie alles noch einmal eingeben. Abhilfe schaffen hier sogenannte DUMPs. Hierbei können Sie alle o.g. Anweisungen mit einem Texteditor eingeben, diese Datei als »community.dump« abspeichern und abschließend die gesamte Datei dem MySQL-Monitor in einem Schritt übergeben. Beenden Sie den MySQLMonitor hierzu mit dem Befehl exit bzw. quit, und geben Sie folgendes am Prompt ein: C:\mysql\bin>mysql community < community.dump
bzw. unter UNIX: %mysql community < community.dump
Sie können nun das Ergebnis Ihrer Arbeit mit der DESCRIBE-Anweisung ansehen: mysql> describe members; +---------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +---------+------------------+------+-----+---------+----------------+ | vorname | varchar(30) | | | | | | name | varchar(30) | | | | | | email | varchar(30) | | | | | | memid | int(10) unsigned | | PRI | 0 | auto_increment | +---------+------------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec) mysql>
Kapitel 10 • MySQL und PHP
123
Weitere Anweisungen, die Sie ausprobieren sollten, um sich mit der Syntax vertraut zu machen, sind SHOW TABLES und SHOW DATABASES. Das Löschen einer kompletten Datenbank ist genauso einfach wie ihre Erstellung. Hierzu benutzen Sie die DROP-Anweisung: mysql> drop database community; Query OK, 3 rows affected (1.21 sec) mysql>
Die Anweisung DROP findet u.a. auch auf Tabellen Anwendung. Die Syntax ist identisch. Erstellen einer Datenbank mit Hilfe von PHP Alles, was Sie oben mit Hilfe des MySQL-Monitors ausgeführt haben, können Sie selbstverständlich auch mit PHP ausführen. PHP bringt etliche MySQL-Funktionen (Abschnitt 10.1.5) mit sich, sodass mit PHP die Administration von MySQL fast zum Kinderspiel wird. Zuerst legen Sie wiederum die Datenbank community an. (Achtung: Vergessen Sie nicht, die zuvor mit dem MySQL-Monitor erzeugte Datenbank wieder zu löschen!) Sie werden in diesem Teil neben der bereits bekannten Funktion mysql_(p)connect() die Funktion mysql_create_db() kennen lernen:
Dieses Beispiel erzeugt wie bereits dargelegt eine Verbindung zum MySQL-Server und anschließend mit der Funktion mysql_create_db() eine neue Datenbank. mysql_create_db() int mysql_create_db(string Datenbankname [, int Verbindungskennung]);
124
Grundlagen
Die Funktion erzeugt eine neue Datenbank. Als Parameter werden ihr der Name der Datenbank und optional die Verbindungskennung übergeben. Im Fehlerfall lässt sich den Fehler mit der Funktion mysql_error() ausgeben. mysql_error() string mysql_error([int Verbindungskennung]);
Die Funktion liefert den Fehlertext einer zuvor fehlerhaft ausgeführten MySQLAnweisung zurück. Verwandt mit dieser Funktion ist die Funktion mysql_errno(). mysql_errno() int mysql_errno([int Verbindungskennung]);
Die Funktion liefert die Fehlernummer einer zuvor fehlerhaft ausgeführten MySQL-Anweisung zurück. Erstellen Sie nun auf ganz ähnliche Weise die Tabelle members in der Datenbank:
Wie das obige Beispiel zeigt, ist die Umsetzung der SQL-Anweisung ähnlich wie die zuvor in den MySQL-Monitor eingegebene. Sie unterscheidet sich darin, dass die Argumente der SQL-Anweisungen in Variablen ($sql_create, $host, $user, Funktionen $database) gespeichert werden. Darüber hinaus werden die mysql_select_db() und mysql_query() verwendet.
Kapitel 10 • MySQL und PHP
125
mysql_select_db() int mysql_select_db(string Datenbankname [, int Verbindungskennung])
Die Funktion macht die bezeichnete Datenbank zur aktuellen Datenbank. Dabei benutzt sie die übergebene Verbindungskennung oder eine gerade aktive. Im Erfolgsfall gibt sie true, bei einem Fehler false zurück. Somit erfüllt sie denselben Zweck wie die schon bekannte SQL-Anweisung USE. Sie könnten statt dessen auch diese Anweisung benutzen, würden aber den Programmcode unnötig verkomplizieren. mysql_query() int mysql_query(string SQL-Anweisung [, int Verbindungskennung]);
Die Funktion sendet eine Anfrage an die bestehende Datenbank-Verbindung. Sie liefert im Erfolgsfall true und je nach Anweisung weiterverarbeitbare Ergebniskennungen zurück. Wenn ein Fehler auftritt, gibt sie false zurück. Diese Funktion wird immer dann benutzt, wenn dem MySQL-Server eine SQLAnweisung übergeben werden soll. Sie können die Datenbank mit der Ihnen schon bekannten DROP-Anweisung löschen:
Das Beispiel sollte selbsterklärend sein. Wenn Sie es jetzt ausführen, müssen Sie für den weiteren Teil jedoch die Datenbank wieder anlegen. Um Näheres zu der Funktion mysql_drop_db() zu erfahren, schauen Sie bitte in der MySQL-Funktionsreferenz im Abschnitt 10.5 dieses Kapitels nach.
126
Grundlagen
10.1.6 Arbeiten mit der Datenbank Nachdem Sie die Rahmenbedingungen für die Datenbank geschaffen haben, fehlen lediglich die Daten selbst und Möglichkeiten, diese Datensätze zu bearbeiten. Dazu werden Sie sich der SQL-Anweisungen SELECT, INSERT, UPDATE und DELETE bedienen. SELECT: INSERT: UPDATE: DELETE:
SQL-Anweisung SQL-Anweisung SQL-Anweisung SQL-Anweisung
zur zur zur zum
Ausgabe von Daten Eingabe von Daten Aktualisierung von Daten Löschen von Daten
INSERT mit Hilfe des MySQL-Monitors Damit Sie mit Datensätzen arbeiten können, müssen Sie diese zunächst eingeben. Dies erfolgt über die INSERT-Anweisung. Bei dieser Anweisung gibt es verschiedene Syntax-Möglichkeiten. An dieser Stelle werden jedoch lediglich die gängigsten – auf das hier Notwendige reduziert – aufgezeigt: INSERT INTO Tabelle VALUES (Wert 1, Wert2, ...)
Die in Klammern stehende Liste von Werten muss jeweils einer korrespondierenden Spalte der Tabelle entsprechen. Wert 1 wird folglich in die erste Spalte der Tabelle, Wert 2 in die zweite Spalte usw. eingefügt. Dabei müssen exakt so viele Werte angegeben werden, wie Spalten in der Tabelle vorhanden sind. In unserem Beispiel demnach: mysql> insert into members values mysql>('Max','Mustermann','[email protected]',1); Query OK, 1 row affected (0.17 sec) mysql>
Wenn jedoch lediglich in ausgewählte Spalten Daten einfügt werden sollen, wird folgende Syntax benutzt: INSERT INTO Tabelle (Spaltenname 1, Spaltenname 2, ...) VALUES (Wert 1, Wert2, ...)
Die Spalten, die mit Werten gefüllt werden sollen, werden in Klammern hinter dem Tabellennamen angegeben. Die hinter dem Schlüsselwort VALUES in Klammern stehenden Werte müssen mit diesen korrespondieren: mysql> insert into members (vorname,name) values ('Max','Mustermann'); Query OK, 1 row affected (0.00 sec) mysql>
Kapitel 10 • MySQL und PHP
127
INSERT mit Hilfe von PHP Testen Sie hier Ihren Lernerfolg, und schreiben Sie ein Skript, mit dem Sie die Datensätze eingeben können, bevor Sie sich das folgende Beispiel, das auf bekannte Funktionen zurückgreift und nur der Vollständigkeit abgebildet ist, anschauen: Steinmann Uwe <street>Feithstr. Hagen
Da diese Beispieldatei keinerlei Fehler enthält, kehrt der Aufruf von xml_parse mit dem Wert True zurück.
276
SAX
Mit der Funktion int xml_parser_create void
wird zunächst ein Parser erzeugt. Die zu parsende Datei wird danach mit fopen geöffnet und der Inhalt in Stücken zu 4.096 Byte an den Parser übergeben. Dies geschieht so lange, bis die Datei vollständig gelesen ist. Das Parsen übernimmt die Funktion int xml_parse int parser string data int [isFinal]
Falls dabei Fehler auftreten sollten, wird der Vorgang sofort abgebrochen und eine Fehlermeldung sowie die Zeile in dem XML-Dokument, an dem der erste Fehler aufgetreten ist, ausgegeben. In der Regel will man ein XML-Dokument jedoch nicht nur überprüfen, sondern die Information darin auswerten. Dazu müssen die Ereignisse, die der Parser generiert, in eigenen Funktionen ausgewertet werden. Das Beispiel wird also durch zwei Funktionen erweitert, die beim Start und beim Ende eines Elements aufgerufen werden.
In diesem Beispiel führen beim Parsen auftretende Start- und End-Tags zum Auslösen von Ereignissen, die wiederum zum Aufruf der Funktionen startElement und endElement führen. Gesetzt werden diese Funktionen durch die folgende PHP-Funktion: int xml_set_element_handler int parser string startElementHandler string endElementHandler
Die Funktion startElementHandler wird bei jedem öffnenden Tag mit dessen Name und Attributen sowie einer Referenz auf den Parser aufgerufen. Der Funktion endElementHandler, aufgerufen beim Schließen eines Tags, werden lediglich der Parser und der Name des Tags übergeben. Es ist nun Aufgabe der Anwendung, auf diese Ereignisse zu reagieren. In dem obigen Beispiel werden die Tags lediglich ausgegeben und dabei gemäß ihrer Verschachtelungstiefe eingerückt. Was auch diesem Beispiel noch fehlt, ist die Verarbeitung der eigentlichen Inhalte, also der Adressinformation. In XML wird dieser Teil CDATA (Character Data) genannt, der mit einem eigenen Ereignis eingeleitet wird. Dem Parser wird die bearbeitende Funktion mit int xml_set_character_data_handler int parser string handler
bekannt gemacht. Das Beispiel um diese Funktion und den Handler erweitert, sieht dann so aus:
Wenn Sie das Beispiel ausprobieren, werden Sie feststellen, dass selbst die Elemente, von denen man nicht annimmt, dass sie Charakter Data enthalten (z. B. address), das entsprechende Ereignis auslösen. Dies liegt an den Zeilenumbrüchen und den einrückenden Leerzeichen, die ebenfalls als Character Data interpretiert werden. Eine weitere Änderung an dem Beispiel soll noch durchgeführt werden. Das Element address bekommt ein Attribut mit dem Namen type, das den Wert hidden annehmen kann. Ist dieser Wert gesetzt, so soll die Adresse nicht ausgegeben werden. So werden die Tag-Attribute zusätzlich angewendet:
Neben den bisher beschrieben Funktionen verfügt das XML-Modul über weitere: int xml_set_processing_instruction_handler int parser string handler
280
DOM
Setzt die Funktion, die so genannte Processing Instructions abarbeitet. . int xml_set_default_handler int parser string handler
Setzt die Funktion, die aufgerufen wird, wenn sonst kein Handler verfügbar ist. Als Parameter werden dem Handler der Parser und die Daten als Zeichenkette übergeben. Alle weiteren Funktionen entnehmen Sie bitte der Funktionsreferenz.
15.2
DOM Das DOM-Modul ist noch recht neu und daher noch nicht vollständig fertig. Zur Zeit bestehen zwei Möglichkeiten, die DOM-Schnittstelle zu nutzen. Die eine Möglichkeit besteht aus nur einer Funktion. class xmltree string str
Die Funktion generiert aus einem XML-Dokument einen Baum aus PHP-Klassen, auf die dann beliebig zugegriffen werden kann. Wenn Sie diesen Baum mit var_dump ausgeben, wird die Struktur schnell deutlich. Sie können den Baum beliebig verändern; es besteht allerdings zur Zeit keine Möglichkeit, daraus wieder ein XML-Dokument zu machen, es sei denn Sie realisieren dies selbst in PHP. Die Objekte des Baums sind Instanzen der folgenden Klassen: •
DomDocument
•
DomNode
Die zweite Möglichkeit besteht darin, den Baum intern aufzubauen und durch Funktionen darauf zuzugreifen. Dazu ist es zunächst, ähnlich wie bei der SAX-Schnittstelle, notwendig, ein bestehendes Dokument mit der Funktion class xmldoc string xmldoc
zu parsen oder mit der Funktion class new_xmldoc void
einen neuen Baum zu beginnen. Die Rückgabe ist in beiden Fällen eine Klasse vom Typ DomDocument.
Kapitel 15 • PHP und XML
281
Die beiden Bäume erstellt mit xmltree oder xmldoc werden nicht synchronisiert. Änderungen an einem Baum haben daher keine Wirkung in dem anderen Baum. Sie sollten sich als für eine der beiden Möglichkeiten entscheiden.
15.2.1 Beschreibung der Klassen DomDocument Die Klasse DomDocument verfügt über die folgenden Funktionen: class root void
Liefert eine Instanz der Klasse DomNode mit der Wurzel des Dokuments. array children void
Liefert alle Kinder des Dokuments. Jedes Kind ist eine Instanz der Klasse DomNode. Unter diesen Kindern ist auch die Wurzel, die einzeln mit root erfragt werden kann. string dump_mem void
Liefert das XML-Dokument. class dtd void
Liefert die DTD des Dokuments als Instanz der Klasse DomDTD, die jedoch zur Zeit nicht weiter verwendbar ist. class add_root string name
Fügt die Wurzel zu einem Dokument hinzu. Diese Funktion ist dann sinnvoll, wenn mit new_xmldoc ein neues Dokument erzeugt wurde. Zudem sind noch die Variablen version und standalone verfügbar. DomNode Die Klasse DomNode verfügt über die folgenden Funktionen: class lastchild void
Liefert das letzte aller Kinder. class children void
282
DOM
Liefert alle Kinder des Knotens. class parent void
Liefert die Mutter/den Vater des Knotens. class new_child string name string content
Fügt ein neues Kind zur Liste der Kinder hinzu. string getattr string name
Liefert den Wert eines Attributs. bool setattr string name string content
Setzt ein Attribut auf einen neuen Wert. Existiert ein noch kein Attribut mit diesem Namen, dann wird es hinzugefügt. array attributes void
Liefert alle Attribute in einem assoziativen Array, in dem der Name des Attributs als Schlüssel verwendet wird. Beispiele Das folgende Beispiel erzeugt ein einfaches XML-Dokument unter Verwendung von HTML-Tags.
Kapitel 15 • PHP und XML
Das Lesen eines XML-Dokuments ist etwas aufwändiger. ]> <entry>a1<entry morerows='1'>b1<entry>c1 <entry>a2<entry>c2 <entry>a3<entry>b3<entry>c3 "; function output_node($node, $level=0) { switch($node->type) { case XML_ELEMENT_NODE: for($i=0; $iname; $attributes = $node->attributes(); if(is_array($attributes)) { foreach($attributes as $attribute) echo " ".$attribute->name."=".$node->getattr($attribute->name); } echo ">\n"; $children = $node->children(); for($i=0; $i < count($children); $i++) output_node($children[$i], $level+1); for($i=0; $iname.">\n"; break; case XML_TEXT_NODE: for($i=0; $icontent; break; case XML_ENTITY_REF_NODE: echo $node->content; break; case XML_COMMENT_NODE: for($i=0; $i