Sie sind auf Seite 1von 448

Johann-Christian

Hanke
H
a
n
k
e
8674
Johann-Christian Hanke
6. Au age
Auf der CD:
PHP 5, MySQL 5, Apache-Webserver,
PSPad, Notepad++, Aptana Studio,
XAMPP, Videos zur Installation
und Einrichtung, Programmiercode
aus dem Buch
Der Bestseller aktualisiert in der
6. Auage!
Alles redet von PHP und MySQL! Und unzhlige
Webseiten-Programmierer setzen die Program-
miersprache PHP und die Webdatenbank MySQL
mit viel Erfolg und Spa ein. Du mchtest auch in
diese Liga aufsteigen und tolle Webseiten mit PHP
und MySQL erstellen?
Dann ist dieses Buch von Johann-Christian Hanke
genau richtig fr dich! Du lernst zum Beispiel, wie
du die Besucher auf deiner Webseite zhlst und
ein Gstebuch einrichtest, in dem deine Freunde
Nachrichten verffentlichen knnen. Selbst eigene
Umfragen, Formulare fr Feedback und ein kleines
Weblog kannst du bald selbst erstellen. Falls du
einmal nicht weiterweit, springt dir Hund Buf
zur Seite und gibt dir gerne hilfreiche Tipps. Und
das ist lngst nicht alles, was das Buch zu bieten
hat!
Die CD ist randvoll mit Tools, die du fr deine
Webseiten-Programmierung brauchst. Die Videos
zur Installation und Einrichtung helfen dir, damit du
sofort mit dem Programmieren loslegen kannst.
Auf der CD ndest du alles, was du zum Program-
mieren brauchst:
PHP 5, MySQL 5, den Apache-Webserver, die Edito-
ren PSPad, Notepad++ und Aptana Studio, phpMy-
Admin, XAMPP, SELFHTML, Videoworkshops, Lsun-
gen zu den Aufgaben und den Programmiercode
aus dem Buch
ISBN 978-3-8266-8649-8
Ebenfalls in dieser Reihe
erschienen:
ber den Autor:
Johann-Christian Hanke
ist ein erfolgreicher Fach-
buchautor und gibt Kurse
an einer Volkshochschule
in Berlin.
System-
voraussetzungen:
Alle Windows-Versionen
sowie Mac OS X und
Linux
Ab 11 Jahre, aber auch
fr Erwachsene, die eine
wirklich einfache Einfh-
rung suchen.
23,3 mm
Probekapitel und Infos
erhltst du unter:
info@it-fachportal.de
www.it-fachportal.de
(D) 19,95
Regalsystematik:
Programmierung
ISBN 978-3-8266-8674-0
8674.indd 1 07.01.2010 10:48:51






PHP und MySQL fr Kids


Johann-Christian Hanke
PHP und MySQL
fr Kids


Bibliografische Information Der Deutschen Bibliothek
Die Deutsche Bibliothek verzeichnet diese Publikation in
der Deutschen Nationalbibliografie; detaillierte bibliografische
Daten sind im Internet ber <http://dnb.ddb.de> abrufbar.



Bei der Herstellung des Werkes haben wir uns zukunftsbewusst fr
umweltvertrgliche und wiederverwertbare Materialien entschieden.
Der Inhalt ist auf elementar chlorfreiem Papier gedruckt.


ISBN: 978-3-8266-8674-0
6., aktualisierte und erweiterte Auflage 2010



E-Mail: kundenbetreuung@hjr-verlag.de

Telefon: +49 89/2183-7928
Telefax: +49 89/2383-7620


2010 bhv, eine Marke der Verlagsgruppe Hthig Jehle Rehm GmbH
Heidelberg, Mnchen, Landsberg, Frechen, Hamburg.
Printed in Germany

Lektorat: Katja Vlpel
Korrektorat: Petra Heubach-Erdmann
Satz und Layout: Johann-Christian Hanke, Berlin

Dieses Werk, einschlielich aller seiner Teile, ist urheberrechtlich geschtzt.
Jede Verwertung auerhalb der engen Grenzen des Urheberrechtsgesetzes ist
ohne Zustimmung des Verlages unzulssig und strafbar. Dies gilt insbesondere
fr Vervielfltigungen, bersetzungen, Mikroverfilmungen und die
Einspeicherung und Verarbeitung in elektronischen Systemen.


fr Tabea, Florian und Linus




7


Inhaltsverzeichnis

Vorwort 15
Was bedeutet eigentlich Programmieren? 15
Wozu sind Datenbanken da? 16
Was kannst du mit PHP und MySQL alles machen? 17
Was ist ein Webserver und wozu brauchst du den? 18
Wie arbeitest du mit diesem Buch? 18
Was brauchst du fr dieses Buch? 19
Wie gut kommst du mit dem Computer klar? 20
Was ist neu in Auflage 6? 22
Wo gibts Hilfe, wenn es mal klemmt? 24
1 Deine coole Homepage mit HTML 25
Richte dir einen Projektordner ein! 26
HTML auf Knopfdruck mit PSPad 28
So wirds perfekt: berschriften, Abstze und mehr 35
Hier bin ich: Ein Bild einfgen 40
Meine Hobbys kurz aufgelistet 43
Coole Links zu coolen Pltzen 45
Meine drei Lieblingsfcher in einer Tabelle 47
Schickes Layout mit Style Sheets 49
Schn bunt hier: Farben zuweisen 53
So legst du die exakte Breite fest 57
Eine Umfrage! Wie findest du meine Page? 59
Tipps und Tricks zu PSPad 61
Schlussbemerkung 64
Zusammenfassung 64
Ein paar Fragen 65
und ein paar Aufgaben 65
8
Inhaltsverzeichnis

2 Installiere deinen eigenen Webserver! 67
Warum eigentlich ein Webserver? 68
Wie teuer ist die Homepage mit PHP/MySQL? 71
How! Im Reich des Apachen 75
Ganz einfach: Webserver selbst installiert! 75
Nur noch etwas Handarbeit und fertig! 81
Testen: phpinfo() auf localhost 83
Schlussbemerkung 86
Zusammenfassung 87
Ein paar Fragen 87
und eine Aufgabe 88
3 Hallo echo Hallo Welt 89
Daten ausgeben mit echo 90
Variablen: Mein rechter, rechter Platz ist leer 94
Ausgabe verschnern mit HTML-Tags 96
Wie Pech und Schwefel: Strings verketten 97
Kleine Zeilenumbruchkunde 101
Maskenball: Das Escape-Zeichen \ 103
Keinen Durchblick? Kommentare setzen! 105
Fehlermeldung? Cool bleiben! 106
Schlussbemerkung 108
Ein paar Fragen 109
und ein paar Aufgaben 109
4 Spa mit Datum und Uhrzeit 111
Immer up to date 112
Wer hat an der Uhr gedreht? 115
Pause muss sein: Die if-else-Entscheidungsstruktur 116
Der Tag vergeht: Zwischentne mit elseif 123
Feldvariablen: Wochentage aufschreiben 125
Arrays die Zweite: Es geht auch krzer! 128
9
Inhaltsverzeichnis

Assoziativ: Monatsnamen als Array 129
und wieder die Kurzform 131
Den Monat ausgeben 132
Schlussbemerkung 133
Zusammenfassung 133
Ein paar Fragen 134
und ein paar Aufgaben 135
5 Seiten mit Passwort schtzen 137
Formular fr das Passwort 138
Senden mit Methode: post oder get? 139
Ausgabe des Passworts 141
Testen mit if-else 143
Schnheitsfehler? Variablentest mit isset()! 144
Mehr Mglichkeiten mit switch 147
Inhalt mit include einbinden 151
Mehr Sicherheit: Endungs- und Ordnertricks 152
Schlussbemerkung 154
Zusammenfassung 155
Ein paar Fragen 156
und ein paar Aufgaben 156
6 Etwas Mathe: Taschen(geld)rechner 157
Nicht ohne Grund: Grundrechenarten 158
Rechenpraxis: Zwei mal Drei macht Vier 159
Einnahmen minus Ausgaben: Taschengeldrechner 160
$_SERVER['PHP_SELF']: Daten an sich selbst
schicken 164
Wie viel bleibt brig? Prozentrechnung! 165
Traurige Sulen: Ergebnis als Diagramm 169
Plus, Minus, Mal, Geteilt? Select! 170
So liest du ein SELECT-Feld aus 172
10
Inhaltsverzeichnis

Rechner de luxe: Wir schreiben eine Funktion 174
Der Rechner im Einsatz 177
Schlussbemerkung 180
Zusammenfassung 180
Ein paar Fragen 181
und ein paar Aufgaben 181
7 Schleifen: Die Gratulationsmaschine 183
Die while-Schleife 184
Prfung zu Fu: do while 189
Der Bestseller: for 190
Und die Geburtstagskerzen? 192
Have a break: Abbruchbedingung einfgen 194
Und noch eine Schleife: foreach 195
Schlussbemerkung 199
Zusammenfassung 199
Ein paar Fragen 199
und ein paar Aufgaben 200
8 Frs Feedback: Formmailer selbst gestrickt 201
Die Funktion mail() 202
E-Mail mit Datums- und Zeitstempel 204
Das Feedback-Formular 205
Professionell mailen: Fehler unterdrcken 207
Formular um ein Name-Feld erweitern 210
Backslashes entfernen mit stripslashes() 211
Prfen! Sind alle Felder ausgefllt? 212
Inhalt in die Formularfelder schreiben 216
Erweiterter Fehlertest: Mindestlnge und
E-Mail-Check 221
Krnender Abschluss: Universal-Formmailer 227
Schlussbemerkung 231
11
Inhaltsverzeichnis

Zusammenfassung 232
Ein paar Fragen 232
und ein paar Aufgaben 233
9 Surfer wiedererkennen mit Cookies 235
Was sind Cookies? 236
Grundeinstellungen im Browser 239
Krmelmonsters Keksfabrik: Cookies backen 241
Der Keks bekommt ein MHD 243
Herumkrmeln: Cookies verspeisen 244
Aufgegessen: Cookies lschen 245
Schlussbemerkung 246
Zusammenfassung 246
Ein paar Fragen 246
und ein paar Aufgaben 246
10 Besucherzhler selbst gebaut 247
Zwei Dateien: So funktioniert das Beispiel 248
Hitmaschine: Ein Textcounter 248
Datei zum Lesen ffnen 249
Der geheimnisvolle Dateizeiger 250
Daten in eine Textdatei schreiben 252
Rechtevergabe mit chmod 253
Counter de luxe mit Cookies 256
So funktioniert das Skript 257
Schlussbemerkung 258
Zusammenfassung 258
Ein paar Fragen 258
und ein paar Aufgaben 259
11 Eine Umfrage mit grafischer Auswertung 261
So sieht das Beispiel aus 262
Durch Komma separierte Textdatei 263
12
Inhaltsverzeichnis

Text am Trennzeichen zerlegen 266
Die unsichtbare Tabelle fr das Diagramm 267
und wieder etwas Mathe: Dreisatz 268
Die Umfrageseite: So funktioniert das Skript 270
Schummeln verboten: Mehrfachvotes unterdrcken 273
und wieder entsteht ein Array 274
Schlussbemerkung 277
Zusammenfassung 277
Ein paar Fragen 277
und ein paar Aufgaben 278
12 Das eigene Gstebuch 279
(Zu) simpel gestrickt: Version 1 280
Hacking-Versuche unterbinden 283
Die Funktionen nl2br() und readfile() 283
Schon besser: Gstebuch Version 2 284
So vermeidest du Doppeleintrge 286
Gstebuch sicherer machen 290
Schlussbemerkung 291
Zusammenfassung 292
Ein paar Fragen 292
und ein paar Aufgaben 292
13 Ein Adressbuch fr dein Team 295
Planung ist die halbe Miete 296
Geniales Tool: phpMyAdmin 298
Etwas SQL zum Anlegen der Datenbanktabelle 300
Die Datentypen im berblick 304
Trage ein paar Adressen ein! 307
Alle Teammitglieder da? Schaue nach! 312
Daten als HTML-Tabelle ausgeben 317
Mit PHP: Eingabeformular selbst gestrickt 327
13
Inhaltsverzeichnis

Schlussbemerkung 332
Zusammenfassung 332
Ein paar Fragen 333
und ein paar Aufgaben 334
14 Gstebuch de luxe als Datenbanktabelle 335
Datenbanktabelle planen 336
Daten erst einmal ausgeben 338
Das Eingabeformular entsteht 343
Mit Sicherheit: Reloadsperre und Magic Quotes 348
Nicht alle Datenstze auf einmal 354
Links fr die seitenweise Ausgabe 357
Schlussbemerkung 361
Zusammenfassung 361
Ein paar Fragen 362
und ein paar Aufgaben 362
15 Weblog fr Kids: Das Mini-CMS 365
Pflichtenheft: Zuerst planst du das Projekt 366
Schickes Design: Die Ausgabe aller Daten 368
Datenbankabfrage: Der MySQL-Teil im berblick 372
News von Gestern? ltere Eintrge anzeigen! 375
Passwortschutz mit Cookie 377
So bindest du die Beitrge ein 379
HTML in PHP mit heredoc 380
Mehr gefllig? Hier klicken! 383
Die Funktionen strlen() und substring() 385
Schlussbemerkung 389
Zusammenfassung 389
Ein paar Fragen 390
und ein paar Aufgaben 390
14
Inhaltsverzeichnis

16 Aktivitten verwalten: Wer kommt mit
ins Kino? 391
Das Adressbuch bekommt Gesellschaft 392
Ist das noch normal? Daten aufteilen! 395
Nicht vergessen: Das Eingabeformular 399
Bitte besttige: Name und Nutzer-ID 403
Wer kommt mit? Aus zwei mach drei! 406
SQL fr Profis: Von Joins und Funktionen 411
Schlussbemerkung 416
Zusammenfassung 417
Ein paar Fragen 417
und ein paar Aufgaben 417
17 Automatisch Geburtstagsgre versenden 419
MySQL und dein Dienstleister 420
ALTER TABLE: Neue Spalte mit ADD COLUMN 420
Vorberlegung: Pseudo-Cronjob einrichten 421
So klappts: Das Geburtstags-Skript 422
Schlussbemerkung 426
Zusammenfassung 427
Ein paar Fragen 427
und ein paar Aufgaben 428
Anhang A: Fr Eltern und Lehrer 429
Anhang B: Hochladen der Seiten mit FTP 431
Anhang C 437
Empfehlenswerte PHP-Editoren 437
PHP und MySQL lernen 438
Stichwortverzeichnis 439
15


Vorwort
PHP was ist das? Lass mich dazu eine kleine Geschichte erzhlen!
Es war einmal ein Typ, der hie Rasmus. Und Rasmus hatte eine eigene
Homepage. Zugegeben, das ist heute nichts Besonderes. Doch damals
(1994) besaen die meisten Homepages den Charme einer verhauenen
Mathearbeit. Es fehlte der Pfiff. Das rgerte unseren Helden. Kurzerhand
schrieb Rasmus ein paar Befehle, um seine Homepage aufzupeppen. Eine
neue Programmiersprache war geboren! Er nannte sie Personal Homepage-
Tools, kurz PHP.
Und weil PHP so einfach war, fanden sich bald ein paar andere Computer-
experten, die immer mehr Pepp zu PHP hinzufgten. Gemeinsam entwi-
ckelten und entwickeln sie PHP zur einer richtig coolen Homepage-
Aufpepp-Sprache: Egal ob Besucherzhler oder Gstebuch alles das
konnte nun mit relativ wenig Aufwand gebastelt werden.
Wenn du dieses Buch liest, gibt es schon die PHP-Version 5.4 oder sogar
schon 6 da ist in der Zwischenzeit also allerhand passiert. Auch auf
deiner Homepage wird mit PHP bald allerhand passieren. Versprochen!
Doch wozu brauchst du dieses Datenbankprogramm namens MySQL? Und
was ist das genau? Das erzhle ich dir gleich! Doch vorher sprechen wir
ber die Sache, um die sich im Buch (fast) alles dreht ber das Pro-
grammieren.
Was bedeutet eigentlich
Programmieren?
Programmieren ist wenn man dem Computer sagt, wo der Hase lang
luft. Du gibst dem Computer Befehle, die er automatisch ausfhren muss.
Angenommen, Lars Labertasche bestellt auf deiner Homepage drei Eimer
deiner selbst gebrauten Spezial-Kaugummis mit Sprechblasen-Garantie.
Dann soll der Homepage-Computer diese Bestellung an dich per E-Mail
weiterleiten. Und zwar so schnell wie mglich. Damit der Computer das
auch so macht wie du willst, schreibst du ihm alles vorher genau auf. Du
gibst dem Rechner die entsprechenden Befehle und Anweisungen.
16
Vorwort

Vorwort
Und da liegt der Hase im Pfeffer: Computer verstehen kein Deutsch! Du
musst wohl oder bel die Sprache der Computer lernen. Diese heit in un-
serem Fall eben PHP.
Wenn Lars hinterher doch 5 Eimer Lakritzschnecken oder 3 Sack Gem-
sezwiebeln geliefert bekommt, hast du wohl einen Programmfehler ge-
macht. Aber das steht auf einem anderen Blatt. Programmfehler gehren
zur Programmierer-Karriere dazu wie der Geigerfleck am Kinn eines
Violinspielers.
Wozu sind Datenbanken da?
Angenommen, dein kleines Geschft auf der Homepage startet richtig
durch: Lars ist inzwischen Stammkunde geworden. Neben Lars bestellen
noch Lukas, Laura, Tim, Michelle und Jan regelmig deine selbst gekoch-
ten Kaugummis. Tglich kommen unzhlige Bestellungen.
Um weniger Stress zu haben, mchtest du nicht mehr jede einzelne Bestel-
lung vom Computer geschickt bekommen. Du befiehlst dem Computer,
alle Bestellungen in eine Liste zu schreiben. Solch eine Liste ist aufgebaut
wie eine Tabelle: Alles steht fein suberlich untereinander.
Diese eine Tabellen-Liste wird nun als Datenbanktabelle bezeichnet. Das
ist sehr bersichtlich, weil jede Bestellung in einer eigenen Zeile steht.
Halt, da wre noch eine Kleinigkeit: Wenn du Datenbanktabellen einset-
zen willst, brauchst du wieder ein spezielles Programm, das Datenbank-
programm. Und hier nehmen wir MySQL. Warum? Weil MySQL viel kann,
nichts kostet und sich wunderbar mit PHP vertrgt.
Merke dir: Eine Datenbanktabelle ist eine Art Liste in Tabellenform. Sie hilft
dir, deine Daten effektiver zu speichern. Du kannst sie, musst sie aber nicht
einsetzen. Eine oder mehrere zusammengehrige Datenbanktabellen wer-
den auch als Datenbank bezeichnet.
Am Beispiel eines Gstebuches zeige ich dir spter, wie man es ohne und
mit Datenbankuntersttzung machen kann. Apropos machen
17
Was kannst du mit PHP und MySQL alles machen?

Was kannst du mit PHP und
MySQL alles machen?
Fast alles! Wie wre es mit einem Zhler? Dem eben erwhnten Gste-
buch? Der Umfrage? Du mchtest die aktuelle Uhrzeit auf der Homepage
anzeigen? Das Datum? Du willst dem Surfer mitteilen, dass er schon einmal
auf deiner Homepage war. Kein Problem! berprfe, ob das Formular (z. B.
fr die Kaugummi-Bestellung!) richtig ausgefllt wurde. Zeige Lars Laber-
tasche alle Bestelldaten noch einmal an. Schreibe ein Programm, welches
deinen fleiigen Bestellern bei jeder Bestellung eine Dankes-E-Mail schickt.
Das Grte: Vieles davon geht sogar schon allein mit PHP. Doch ein Daten-
bankprogramm wie MySQL ist dann ungeschlagen, wenn viele Informatio-
nen verknpft werden mssen. Klingt kompliziert? Nehmen wir an, du er-
weiterst das Angebot deines kleinen Internet-Ladens. Nun gibt es neben
den Kautschis auch Lakritzschnecken mit eingebautem Drehwurm,
Pfefferminzbonbons mit Anisgeschmack und andere selbst gemachte
Leckereien. Wie stellst du deine Kstlichkeiten ins Netz? Du trgst alle Da-
ten fein suberlich untereinander in eine weitere Datenbanktabelle ein.
Es gibt also eine extra Liste fr deine Sigkeiten und eine weitere Liste fr
die Bestellungen. Das macht es fr den Computer einfacher, die Daten zu
verwalten, weil alles wunderbar geordnet ist.
Doch damit nicht genug. Weise den Computer an, Bestellung und Adress-
daten in getrennten Tabellen zu fhren. Das ist ungeheuer praktisch, denn
nun muss Lars seine Daten nicht bei jeder Bestellung neu eingeben. Er be-
kommt einfach eine Nummer und wird jedes Mal anhand dieser Nummer
vom Computer wiedererkannt.
Lange Rede, kurzer Sinn: Im Endeffekt hast du ein richtiges kleines Sys-
tem von miteinander verknpften Datenbanktabellen. Fr jeden Zweck
gibt es die passende Tabelle: Eine fr die Produkte, eine fr die Kunden
und eine fr die Bestellungen. Alle Tabellen gehren zusammen: Das ist
ungeheuer praktisch und effektiv. Damit hast du eine tolle Datenbank
geschaffen!
Wenn du dieses Prinzip verstanden hast, kannst du praktisch alles mit PHP
und MySQL machen. Und dieses tolle Prinzip schauen wir uns in den letz-
ten Kapiteln des Buches und auch im Fortsetzungsband PHP und MySQL
Praxisbuch fr Kids etwas nher an.
18
Vorwort

Vorwort
Was ist ein Webserver und wozu
brauchst du den?
Was zum Teufel ist denn nun der Webserver? Es ist dein Homepage-
Computer. Also der Rechner, auf dem deine Homepage liegt. Moment
mal, denkst du hier vielleicht. Meine Homepage liegt doch z. B. auf mei-
nem Rechner daheim. Dort habe ich sie erstellt und dort kann ich sie mir
jederzeit ansehen.
Das stimmt schon, an deinem Rechner kannst du deine Homepage sehen.
Und du kannst sie deinen Kumpels zeigen. Doch damit alle etwas von dei-
nen Seiten haben, musst du diese erst auf den Homepage-Computer im
Web hochladen. Also auf den sogenannten Webserver.
Das Wort Server kommt vom Englischen to serve. Das bedeutet soviel wie
dienen. Der Webserver ist der Diener im Web. Hier liegen die Websei-
ten, die Homepages. Der Webserver dient so allen Besuchern. Denn die
Besucher knnen die Seiten nun vom Webserver abrufen und mit ihrem
Browser betrachten.
Der Webserver sorgt brigens auch dafr, dass PHP und MySQL richtig gut
funktionieren. Er fhrt also die von dir aufgeschriebenen Programmbefehle
aus. Erst dann zeigt er dem Besucher die gewnschte Seite.
Der bekannteste und beste Webserver heit brigens Apache. Ja richtig,
Apache wie der gleichnamige Indianerstamm. Bei solch einem tollen Na-
men muss die Sache ziemlich cool sein. Das ist sie auch! Die Arbeit mit
PHP, MySQL und dem Apachen macht irrsinnigen Spa. How!
Wie arbeitest du mit diesem
Buch?
Lahmes Lesen ist out, Selbermachen ist in: Dieses Buch enthlt nicht nur
sturen Text und de Programmanweisungen, sondern vor allem Beispiele,
Tipps und Tricks. Mitmachen ist also Pflicht. Es lohnt sich!
Doch wenn du mal keine Lust zum Abschreiben hast (oder dich immer wie-
der verschreibst), ist das auch nicht schlimm! Ich habe dir alle Beispiele auf
die CD gepackt. Ansonsten zeige ich dir schnell noch, welche Symbole be-
sonders wichtig sind.
19
Was brauchst du fr dieses Buch?

Arbeitsschritte
>
Wenn du dieses Zeichen siehst, heit das: Achtung, Action! Es gibt
etwas zu tun. Schreibe eine Programmzeile, whle einen Befehl oder
fhre einen Indianer-Freudentanz auf, weil dein Programm endlich
funktioniert.
Stolperfallen und Rettungsringe
Dieses Symbol findest du dagegen immer dann, wenn es problematisch
wird. Hund Buffi hilft dir, Stolperfallen von vornherein zu umgehen. Lies
also besonders grndlich, wenn du auf dieses Zeichen stt. Vielleicht ist
das ja gerade der Rettungsring, den du in diesem Moment brauchst?
Aber auch Tipps und Tricks bauen wir in solche Ksten ein.
Besonders wichtige Stellen im Buch
Immer wenn solch ein Ausrufezeichen am Textrand erscheint, wird es
besonders wichtig. Du solltest den entsprechenden Kasten vielleicht
zweimal lesen.
Fragen und Aufgaben
Wiederholung ist die Mutter der Porzellankiste (oder so hnlich). Deshalb
gibt es am Ende jedes Kapitels ein paar Fragen und ein paar Aufgaben. Wie
heit es so schn: bung macht den Meister. Die Antworten und die L-
sungen zu den Aufgaben findest du auf der beiliegenden CD.
Was brauchst du fr dieses Buch?
Nun, einen Platz im Bcherregal. Spa beiseite, natrlich einen Computer!
Es muss nicht einmal der allerneuste Rechner sein. Hauptsache Windows
und ein Internet-Browser sind vorhanden. Wir geben uns dabei ganz be-
scheiden, es mssen nicht die neusten Versionen sein. Du kannst sogar
noch Windows 98 verwenden. Oder natrlich Windows 2000, Me bzw. das
aktuelle Windows XP. Vom Prinzip her ist das Vorgehen bei allen Versionen
gleich. Sollte es hier Unterschiede geben, mache ich dich rechtzeitig darauf
aufmerksam.) Bei den Browsern ist Firefox sicher die beste Wahl, aber auch
der Internet Explorer, Opera, Safari oder Google Chrome sind geeignet.
20
Vorwort

Vorwort
Alles andere findest du auf der CD!
Mehr brauchst du nicht! Tatsache, um den Rest musst du dich nicht km-
mern. Auf CD liefern wir dir alles andere mit, damit du sofort loslegen
kannst. Hier findest du unter anderem:
0 PSPad eine sehr gute Windows-Freeware zum Erstellen von Homepa-
ges mit PHP, ein Programm vom Ja Fiala.
0 Aptana Studio, die auf Java basierende Alternative fr Nutzer von Linux
und Mac OS. (Aber auch fr Windows-Nutzer!)
0 PHP selbst (zum Programmieren der dynamischen Webseiten) und
MySQL (das Datenbankprogramm, um mit Datenbanktabellen Ordnung
zu schaffen)
0 phpMyAdmin (eine Art grafische Oberflche fr MySQL, damit du Da-
tenbanken und Tabellen bequem einrichten kannst)
0 Apache-Webserver (damit du alles auf dem eigenen Computer auspro-
bieren kannst und so tust, als ob du einen eigenen Webserver httest.
How!)
0 XAMPP: Ein Super-Programm, welches dir alle bisher genannten Sachen
fast vollautomatisch auf deinem Rechner einrichtet
0 FileZilla, ein Programm zum Hochladen deiner Homepage auf den Web-
server
0 SELFHTML, eine schon fast zu profimige Einfhrung in HTML, die
Sprache zum Erstellen von Homepages
0 NotePad++, ein flinker Windows-Editor zum schnellen Bearbeiten von
PHP-Dateien.
Wie gut kommst du mit dem
Computer klar?
Du solltest dich schon ein wenig mit dem Computer auskennen. Du kommst
mit Maus und Tastatur klar? Prima! Dann kann kaum etwas schief gehen.
Wenn du zustzlich noch weit, was Ordner sind und wie man diese anlegt,
gehrst du schon in die Profi-Liga. (Und wenn nicht, ist das halb so wild,
ich zeige es dir.) Im Notfall fragst du einfach deine Freunde, Geschwister
oder Eltern. Vielleicht kennen die sich ja aus. Oder sie spendieren dir ein
anderes Buch aus der Reihe fr Kids? Zum Beispiel PCs fr Kids (zu
Windows Vista) von Hans-Georg Schumann.
21
Wie gut kommst du mit dem Computer klar?

Was ist neu in Auflage 4 und 5?
Fnf Auflagen in fnfeinhalb Jahren das htte sich der Autor dieses Bu-
ches nicht trumen lassen. Die erste Auflage erschien 2003, die fnfte
2008. Vielen Dank fr das groe Vertrauen! Wir freuen uns riesig ber die-
sen Erfolg. Grund genug, den gesamten Inhalt kritisch zu berprfen und
behutsam zu modernisieren.
Soviel vorweg: Schon in der vierten Auflage von 2007 gab es umfangreiche
Neuerungen, Ergnzungen und Erweiterungen! Hier ging es vor allem um
das Thema Sicherheit. Die fnfte Auflage haben wir nochmals durchgese-
hen und an vielen Stellen verbessert.
Wichtig: Das Thema Sicherheit
Besonders das Thema Sicherheit spielt inzwischen eine immer wichtiger
werdende Rolle. Die Spamattacken werden immer heftiger, die Hacker im-
mer dreister. Selbst groe Programme wie das Content-Management-
System Joomla oder Foren wie phpBB werden bzw. wurden Opfer von Ha-
ckerattacken. Aus diesem Grund haben wir schon fr Auflage 4 alle Skripte
auf Sicherheit hin berprft und in manchen Fllen etwas erweitert. Au-
erdem geben wir dir an vielen Stellen wertvolle Tipps und Tricks, wie du
deine Skripte von vorn herein gegen Angriffe von auen schtzen kannst.
Sicherheit ist ein Prozess, kein Zustand. Was heute noch als sicher gilt,
kann morgen mglicherweise schon erfolgreich gehackt werden. Auch ist
der Aufwand fr absolut sichere Skripte so hoch, dass du alleine fr ein
wirklich sicheres Gstebuch mehrere hundert Zeilen Code schreiben
msstest. Wir versuchen, den Mittelweg zu finden zwischen einfacher
Verstndlichkeit und Durchschaubarkeit auf der einen Seite und Sicher-
heit der Skripte auf der anderen Seite. Man kann es noch immer und
immer ein Stckchen aufwendiger treiben. Aber an irgendeiner Stelle
muss dann auch Schluss sein.
Videoworkshops
In Auflage 4 haben wir erstmals Videoworkshops eingefgt. In diesen Vi-
deos fhren wir dir beispielsweise die Installation von PHP und MySQL
mit dem Tool XAMPP vor, damit du sofort mit dem Programmieren lose-
legen kannst. Du findest alle Videos im Ordner videos. Rufe die Datei
index.html auf. Die Videos liegen im Flashformat vor. Mehr Informati-
onen findest du in der Datei liesmich.txt.
22
Vorwort

Vorwort
Was ist neu in Auflage 6?
Wenn du dich bisher gewundert hast, kann ich dich beruhigen: Du hast das
richtige Buch erwischt. Vor dir liegt tatschlich schon die sechste Auflage
von 2010. Und das kam so: Kurz vor Weihnachten 2009 erreichte mich der
Hilferuf aus dem Verlag: Wir haben nur noch ganz wenige Exemplare auf
Lager. Der Titel ist schneller ausverkauft als gedacht. Wir wrden das Buch
am liebsten sofort in einer neuen Auflage drucken!
Sofort war ein echtes Problem. Denn fr eine weitere Auflage hatte ich mir
ganz heftige Aktualisierungen vorgenommen. Ich wollte die Inhalte im
Buch grundlegend modernisieren und meine Anleitungen fr die Zukunft fit
machen. Das bedeutet:
0 Alle HTML- bzw. PHP-Dateien mssten im immer weiter verbreiteten
Universalzeichensatz Unicode (UTF-8) gespeichert werden. Denn viel-
leicht mchtest du auch einmal fremdsprachige Seiten mit allen mgli-
chen Sonderzeichen erstellen und pflegen? Mit UTF-8 kannst du selbst
Chinesisch rckwrts darstellen, deutsche Umlaute und Sonderzeichen
sowieso. Und da inzwischen auch MySQL die Daten im Format UTF-8 si-
chert, wre das auch aus diesem Grund sehr wichtig.
0 Dafr msste ich einen neuen, Unicode-fhigen PHP-Editor finden,
denn der gute alte Weaverslave von Thomas Weinert (der Editor der ers-
ten fnf Auflagen) wre mit dem Thema UTF-8 leider berfordert. Scha-
de, Thomas, dass du noch keine Zeit zum Aktualisieren hattest! Schn,
dass ich mit PSPad von Jan Fiala einen guten Ersatz gefunden habe.
0 Auerdem msste ich beim Thema Datenbankzugriff auf die moderne-
ren PHP 5-Funktionen zurckgreifen. Schon aus Sicherheitsgrnden!
PHP 5 ist inzwischen der Mindeststandard, praktisch alle Anbieter ha-
ben von PHP 4 auf PHP 5 umgestellt! Und veraltete Techniken gehren
nun mal nicht in ein PHP- und MySQL-Lehrbuch. Eine Menge Arbeit
im Interesse der Sicherheit!
0 Die Installation des sogenannten lokalen Webservers (wir verwenden im
Buch XAMPP) hat sich gendert. Auch hier msste ich eine komplett
neue Anleitung schreiben.
0 Auch die Informationen zu den Dienstleistern msste ich aktualisieren,
denn innerhalb eines Jahres kann viel geschehen.
0 Weiterhin wre es schn, wenn ich mehr Tipps fr Mac- und Linux-
Nutzer einbauen knnte, denn vor allem der Apple Macintosh gewinnt
immer mehr Freunde. (Auch wenn es nur bei Tipps bleiben wird fr
ausfhrliche Anleitungen fehlt leider der Platz.)
23
Was ist neu in Auflage 6?

Nun, was soll ich dir schreiben: Ich habe es geschafft! Die vollstndig aktu-
alisierte 6. Auflage liegt vor dir. Weihnachtsbaum, Kerzenschein und Be-
scherung sind ausgefallen Silvesterparty und Katerfrhstck auch! Dafr
habe ich Tag und Nacht geschrieben, recherchiert, Code getippt und Code
geprft. Bis kurz vor dem Drucktermin. Denn das bin ich dir schuldig eine
gut verstndliche PHP-Anleitung auf der Hhe der Zeit.
Und wenn das Buch so gut ankommt wie die Vorauflagen, hat sich die M-
he auf jeden Fall gelohnt! Danke fr dein Vertrauen!
Danke auch an die vielen, vielen Leser, die mir Tipps, Korrektur- und Ver-
besserungsvorschlge geschickt haben. Ganz besonderer Dank geht an
Sandra, Jonas und vor allem an Falk Joensson (http://jcoud.de). Gerade
du, Falk, hast mir mit deinen umfangreichen Korrektur- und Verbesse-
rungsvorschlgen sehr geholfen. Nobody is perfect und ich schon gar
nicht. Wie gut, dass es solche aufmerksamen Leser gibt wie dich!
Das Betriebssystem spielt keine Rolle!
Wundere dich nicht, wenn im Buch mal der eine oder andere Browser auf-
taucht. Der Grund ist ganz einfach: Ich habe die Anleitungen auf verschie-
denen Rechnern getestet. Ich zeige dir sowohl Abbildungen vom Internet
Explorer 8 unter Windows 7 als auch Bildschirmfotos des alten Internet
Explorer 6 aus Windows XP. Auch Firefox ist natrlich vertreten.
Warum diese Vielfalt? Du sollst sehen, dass das Ergebnis nicht vom Be-
triebssystem oder Browser abhngt. HTML, PHP und MySQL sind plattform-
unabhngig, sie laufen berall! Selbst auf dem Macbook Pro mit Snow
Leopard oder dem altersschwachen Schulrechner mit Windows 2000 oder
Linux. Im Web beim Dienstleister sowieso und der arbeitet in der Regel
unter Linux! Hauptsache, du hast das richtige Webserver-Programm und
den passenden Code-Editor.
Apropos Code-Editor: Da die meisten Leser mit Windows arbeiten,
kommt der im Buch vorgestellte Code-Editor PSPad aus der Windows-
Welt. Er ist schlank und schnell und luft daher auch auf lteren Rech-
nern. Du kannst den Anleitungen jedoch auch an Macs oder Linux-
Rechnern folgen. Verwende lediglich ein anderes Entwicklungswerkzeug,
einen anderen Editor. Programmcode und Ergebnis bleiben gleich. Fr
Mac- und Linux-Nutzer empfehle ich Aptana Studio. Du findest dieses
Tool auf der CD im Ordner programme/aptana. Aptana Studio ist sehr
leistungsfhig, bentigt dafr aber einen schnellen Rechner.
24
Vorwort

Vorwort
Wo gibts Hilfe, wenn es mal
klemmt?
Melde dich einfach! Fr dieses Buch hat der Autor eine eigene Serviceseite
im Web eingerichtet. Surfe zu www.phpkid.de! Hier findest du ein Forum,
wo du mit anderen Lesern diskutieren und dir Hilfe holen kannst. Weiterhin
listen wir brandheie Tipps und Tricks zu Dienstleistern auf und informieren
dich zu nderungen nach dem Druck. Auerdem kannst du Fragen stellen,
die wir dir dann hoffentlich schnell beantworten. Und du findest evtl. Feh-
lerberichtigungen, denn auch Autoren sind nur Menschen.
Du hast Lust bekommen auf mehr? Dann legen wir dir die Fortsetzung
dieses Titels namens PHP und MySQL Praxisbuch fr Kids (2. Auflage)
sehr ans Herz. Dabei stehen auf dem Programm: ein komplettes Forum
mit Userverwaltung, das Schreiben eines RSS-Feedreaders, ein komfor-
tables Fotoalbum und sogar das Planen und Programmieren eines Con-
tent-Management-Systems. Ganz nebenbei schnupperst du sogar noch
ein wenig Objektorientierungsluft und lernst, wie man richtig guten Co-
de schreibt. Gleicher Autor, gleicher Verlag, gleicher Preis.
Voil - jetzt geht es aber los mit PHP und MySQL! Doch zuvor lernst du
noch etwas HTML und CSS. Gleich auf den nchsten Seiten. Einverstanden?
25



1
Deine coole Homepage
mit HTML
Auf los gehts los! Wenn du mit PHP programmieren willst, musst du HTML
knnen. HTML ist schlielich die Sprache, mit der eine Homepage geschrie-
ben wird. Ohne HTML macht PHP keinen Sinn. Du kannst noch kein HTML?
Nicht schlimm! In diesem Kapitel lernst du das Wichtigste zum Thema.
Glaube mir, es ist kinderleicht. Na ja, fast
Du kannst schon HTML? Umso besser! Mache trotzdem mit, denn in diesem
Kapitel zeige ich dir ein super Programm: einen sogenannten HTML- und
PHP-Editor. Und ich verrate dir, wie du dein Projekt am besten organisierst.
In diesem Kapitel lernst du,
$ wie man eine HTML-Seite erstellt
$ wie man berschriften und Abstze notiert
$ wie man Grafiken in die Seite einfgt und mit Farben arbeitet
$ wie man Querverweise setzt, die Hyperlinks
$ wie man Tabellen erstellt
$ wie man der Seite mit Style Sheets ein schickes Layout verpasst
Doch bevor es losgeht, besprechen wir gleich zu Beginn ein paar Dinge, die
verdammt wichtig sind.
26
Deine coole Homepage mit HTML

Kapitel
1 Richte dir einen Projektordner ein!
Ordnung ist das halbe Leben, geht dir dieser Spruch auch so auf die Nerven
wie mir? Dabei kann ein wenig Ordnung im Nachhinein viel Zeit sparen!
Und schon sind wir beim Thema Ordner. Richte dir zuerst einen Projektord-
ner fr deine Experimente ein. Diesen nennen wir phpkid und legen ihn
direkt unter der FESTPLATTE C: ab!
Projektordner phpkid einrichten
Wie geht das? Ganz einfach!
>
Starte zuerst den Windows Explorer. Die coolste Methode: Du hltst
die Taste [Win] auf deiner Tastatur gedrckt. Das ist in der Regel die
zweite oder dritte Taste von links in der unteren Reihe. Du erkennst
sie am Windows-Logo. Jetzt tippst du mutig und unverzagt ein [E]
wie echt einfach oder wie Explorer. Zack schon startet das
Ordner-Verwaltungs-Programm namens Windows Explorer.
>
Was nun, sprach das Huhn? Achte darauf, dass dein Laufwerk C: (die
Festplatte) markiert ist. Klicke also auf der linken Seite auf das Sym-
bol fr deine FESTPLATTE. Es befindet sich unterhalb des Symbols
COMPUTER (Windows 7 bzw. Vista) bzw. ARBEITSPLATZ (Windows XP).
>
Und nun richtest du deinen Ordner ein. In Windows 7 klickst du ein-
fach auf die Schaltflche NEUER ORDNER:

In Windows Vista gibt es diese praktische Schaltflche leider noch nicht.
Dort klickst du auf den Meneintrag ORGANISIEREN und whlst den Me-
npunkt NEUER ORDNER. In Windows XP und Windows 2000 ist der Weg
noch etwas lnger. Du klickst im Men DATEI auf den Befehl NEU. Ein
weiteres Men klappt zur Seite. Whle hier den Befehl ORDNER.
27
Richte dir einen Projektordner ein!

>
Jetzt erscheint ein Platzhalter-Ordner mit der Bezeichnung Neuer
Ordner. Dieser Platzhaltername ist markiert. Du kannst ihn also direkt
berschreiben. Klicke noch nirgends, sondern tippe einfach los. Tippe
den Namen des neuen Ordners, im Beispiel phpkid.
>
Geschafft? Dann drcke einfach [Enter]! Fertig ist der neue Ordner.
Suche doch einmal deinen neuen Ordner. Du findest ihn im linken Bereich
des Windows-Explorers. Er wird alphabetisch zwischen den anderen Ord-
nern einsortiert. Sollte dein Ordner nicht gleich zu sehen sein, ist das nicht
schlimm. Der Windows Explorer ist manchmal ein langsamer Geselle, er
vergisst das Aktualisieren der Ansicht. Hilf etwas nach, drcke auf die
Funktionstaste [F5] auf deiner Tastatur.
Hoppla, du hast dich beim Ordnernamen verschrieben? Oder der Ordner
wurde an der falschen Stelle eingerichtet? Kein Problem! Wenn du einen
Ordner umbenennen willst, klickst du ihn kurz an. Drcke nun die Funk-
tionstaste [F2]. Schon ffnet sich der Ordnername und du kannst ihn
korrigieren. Besttige die Umbenennungsaktion wieder mit [Enter]. Na-
trlich lsst sich so ein Ordner auch lschen. Markiere ihn und drcke
die Taste [Entf] auf deiner Tastatur. Schon ist der Ordner weg!
Einen weiteren Unterordner einrichten
Weil das so gut geklappt hat, machen wir es gleich noch einmal. Erstelle
diesmal einen Unterordner namens html. Dieser Ordner soll direkt unter-
halb von phpkid entstehen. Diesen neuen Ordner nutzen wir fr unsere
ersten Gehversuche mit HTML.
>
Markiere den Ordner phpkid im Windows Explorer. Klicke ihn also im
linken Bereich an.
>
Whle nun wieder NEUER ORDNER (ORGANISIEREN|NEUER ORDNER bzw.
DATEI|NEU|ORDNER) und richte den Unterordner html ein.
Gewhne dir bei der Namensgebung fr Ordner und Dateien generelle
Kleinschreibung an. Die Ordner sollen also phpkid und html und nicht
Phpkid und Html heien. Das ist deshalb so wichtig, weil der Webserver
(Homepage-Computer) spter ganz pingelig zwischen Gro- und Klein-
schreibung unterscheiden wird. Und wenn du hier etwas vermischst, wird
die Homepage im Web nicht oder nicht richtig angezeigt. Bei genereller
Kleinschreibung kann hier jedoch nichts anbrennen. Okay?
28
Deine coole Homepage mit HTML

Kapitel
1
Bitte blende die Dateiendungen ein!
rgert dich auch, dass du unter Windows die Dateiendungen normalerwei-
se nicht siehst? Jede Datei hat ja eine typische drei- bis vierstellige Endung,
die nach einem Punkt an den eigentlichen Dateinamen angehngt wird.
Mit .doc kennzeichnet man Word-Dateien, .txt steht fr Textdateien,
.html fr HTML-Dateien und .php fr PHP-Dateien.
Normalerweise siehst du diese Endungen nicht. Das ist sehr rgerlich, denn
wir brauchen sie! Fr unseren Kurs musst du die Dateiendungen unbedingt
eingeschaltet haben!
>
Rufe den Windows Explorer auf. Wie ging das noch? Halte dafr bei-
spielsweise die [Win]-Taste auf deiner Tastatur gedrckt und tippe
kurz ein [E]. Whle nun im Men ORGANISIEREN den Befehl ORDNER
UND SUCHOPTIONEN. (Windows XP: EXTRAS|ORDNEROPTIONEN.)
>
Geschafft? Das Dialogfenster Ordneroptionen erscheint. Gehe ins
Register ANSICHT, es ist das zweite Register.
>
Suche nach einer Option, die je nach Windows-Version folgenderma-
en heit: Erweiterungen bzw. Dateinamenerweiterungen bei bekann-
ten Dateitypen ausblenden. Sie ist abgehakt. Nimm das Hkchen weg!
>
Besttige deine Einstellungen durch Klick auf OK. Nun siehst du bei
allen Dateinamen auch die typische Endung und weit genau, um
welchen Dateityp es sich handelt.

Nimm das entsprechende Hkchen weg, klicke es einfach an!
HTML auf Knopfdruck mit
PSPad
Vorhang auf, die Show beginnt. Nele, Tim und Buffi, Jan (Programmautor)
und ich (Buchautor) prsentieren: PSPad, den freien Code-Editor fr Win-
dows! Es handelt sich praktisch um ein Programm zum Schreiben deiner
Homepage. Neben HTML beherrscht PSPad aber auch PHP und andere Pro-
grammiersprachen. Geschrieben hat das tolle Programm Jan Fiala, die
Homepage von PSPad findest du unter www.pspad.com.
29
HTML auf Knopfdruck mit PSPad

So wird PSPad installiert
PSPad liegt auf der CD fr dich bereit! Die Installation ist kinderleicht und
erfolgt Schritt fr Schritt per Setup Wizard (Installationsassistent).
>
Starte den Windows Explorer, z. B. durch Gedrckthalten von [Win]
(die Taste mit dem Windows-Logo) und kurzem Tippen von [E].
Schaue in den linken Bereich des Windows Explorers. Gehe zum
Laufwerk fr die CD und hangele dich durch bis zum Unterordner
programme/pspad.
>
Hier siehst du die Datei pspad454inst_en.exe. Doppelklicke auf
diese Datei. Je nach Windows-Version erscheinen erst warnende Dia-
logfenster, die du besttigen musst. Klicke z. B. auf AUSFHREN bzw. JA.
>
Geschafft? Das Fenster Welcome to the PSPad Editor Setup Wizard ist
erschienen? Prima! Folge den Schritten der Installation.

>
Klicke auf NEXT, um zum nchsten Bildschirm zu gelangen. Klicke vor
I accept the agreement. Nun klickst du erneut auf die Schaltflche
NEXT und hangelst dich Schritt fr Schritt durch die gesamte Installa-
tion!

>
Klicke also immer wieder auf NEXT. Die Voreinstellungen gehen in
Ordnung, die kannst du stets bernehmen.
>
NEXT verschwindet, die Schaltflche INSTALL erscheint? Dann hast du
eine weitere Etappe auf deinem Weg erreicht. Klicke auf INSTALL
jetzt endlich wird das Programm auf deiner Festplatte eingerichtet!
>
Klicke zum Schluss auf FINISH. Das Programm startet ganz automa-
tisch und zwar auf Deutsch!
Wenn du das entsprechende Hkchen im letzten Schritt belassen hast, legt
PSPad automatisch eine Verknpfung auf dem Desktop an. Auerdem er-
scheint es als Programmeintrag in der sogenannten Schnellstartleiste
rechts neben der START-Schaltflche! Das ist wirklich genial!
30
Deine coole Homepage mit HTML

Kapitel
1
Eine HTML-Datei erstellen
PSPad ist gestartet? Jetzt erstellst du im Handumdrehen deine erste HTML-
Seite. Doch vorher sollten wir uns noch fr die richtige HTML-Variante
entscheiden. Ich schlage das klassische HTML 4 vor.
Hast du schon etwas Ahnung von HTML? Fragst du dich auch, welches
die richtige HTML-Schreibweise sei? Die klassische oder die Neufor-
mulierung namens XHTML mit strengeren Regeln? Fakt ist, dass die Ent-
wicklung von XHTML als eigenstndige Sprache gerade erst eingestellt
wurde. An HTML 5 dagegen wird fleiig gewerkelt der Klassiker lebt
also weiter. Zwar wird es auch von HTML 5 wieder eine strengere
XHTML-Variante geben. Aber eben nur als alternative Syntax. Wir blei-
ben daher im Buch bei der Schreibweise der bewhrten, klassischen Ver-
sion 4.01 und zwar ohne X vor dem HTML.
Und so erzeugst du in PSPad eine Musterseite im klassischen HTML 4.01:
>
Whle im Men DATEI den Befehl NEU. Das Dialogfenster Neu er-
scheint. Klicke auf die Registerzunge Neue Datei aus Vorlage erstellen.
>
Scrolle zum Zweig HTML und klicke auf den Eintrag HTML 4.01 Transi-
tional. Klicke danach auf BEARBEITEN, nicht auf OK. (OK wrde eine
neue HTML-Seite in den Editor einfgen, die auf diesem Grundgerst
beruht. Doch das Grundgerst ist noch nicht ganz perfekt!)

Klicke auf die Schaltflche Bearbeiten, noch nicht auf OK.
>
Du hast auf BEARBEITEN geklickt? Super! Jetzt erscheint das eben er-
whnte Grundgerst. Und zwar direkt als Vorlage! Du kannst und
musst diese Grundgerst-Vorlage wunschgem ndern.
31
HTML auf Knopfdruck mit PSPad

Die HTML-Vorlage von PSPad anpassen
So sieht es aus das HTML-Grundgerst. Fr meinen Geschmack gibt es
noch einige Schnheitsfehler. Und bevor wir die einzelnen Zeilen genauer
betrachten, merzen wir diese Schnheitsfehler einfach aus.
Die von mir gezeigten Zeilennummern sind bei dir in PSPad nicht sicht-
bar? Whle ANSICHT/ZEILENNUMMERIERUNG.
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
2 <html lang="cs">
3 <head>
4 <meta http-equiv="content-type" content="text/html;
charset=windows-1250">
5 <meta name="generator" content="PSPad editor,
www.pspad.com">
6 <title>Untitled</title>
7 </head>
8 <body>
9
10 </body>
11 </html>

Soviel vorweg: HTML besteht aus Text, der durch sogenannte Tags gesteu-
ert wird. Jedes Tag steht in spitzen Klammern. Es gibt in der Regel ein Tag
zum Einschalten und eins zum Abschalten. Das Abschalt-Tag bekommt
zustzlich einen Slash (/) vorangestellt.
Die Taste mit den spitzen Klammern findest du links unten auf der Tasta-
tur. Drcke [<] fr die ffnende spitze Klammer. Fr die schlieende
Klammer > musst du zustzlich die []-Taste gedrckt halten.
Die Dinge, die mich stren, habe ich unterstrichen. Es sind zum Glck nicht
viele. In Zeile 2 nderst du das cs in de. (Es sei denn, du mchtest deine
Webseiten auf Tschechisch erstellen. Unser Programmautor Jan stammt aus
Tschechien, das ist der Grund fr cs.)
Die Passage windows-1250 am Ende von Zeile 4 ersetzt du durch utf-8.
UTF-8 ist der Universalzeichensatz, der die Zeichen aller wichtigen Spra-
chen enthlt. Damit decken wir einen viel weiteren Bereich an Sprachen ab
als mit dem Windows-Zeichensatz. Schlielich ist Windows nicht der Nabel
der Welt!
32
Deine coole Homepage mit HTML

Kapitel
1
Zeile 5 <meta name="generator" content="PSPad editor usw.
kann entfallen. Niemand muss wissen, dass wir die Seite mit PSPad gene-
riert (erzeugt) haben! Schlielich schreibst du sie per Hand.
Zeile 6 <title>Untitled</title> ist so wichtig, diese Zeile mchte ich
gerne direkt unterhalb von <head> platzieren. Das ist erlaubt! Dann
rutscht die Zeile mit dem Zeichensatz einfach eine Etage tiefer.
Auerdem ersetze ich den Platzhaltertext Untitled durch Hier Titel eintra-
gen. Damit du nie vergisst, den wichtigen Seitentitel einzutragen!
Das perfekte HTML-Grundgerst
Und so sieht das perfekte HTML-Grundgerst fr unseren Kurs aus:
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
2 <html lang="de">
3 <head>
4 <title>Hier Titel eintragen</title>
5 <meta http-equiv="content-type" content="text/html;
charset=utf-8">
6 </head>
7 <body>
8
9 </body>
10 </html>

Die Umbruchpfeile signalisieren, dass die Zeile noch weitergeht. Beachte das Leerzeichen!
Du findest dieses Grundgerst auch auf der Buch-CD. Schaue in den Ordner
beispiele\kapitel01 und ffne die Datei html-grundgeruest.txt.
Schreibe nicht nur utf-8, sondern stelle in PSPad unbedingt auch das
Format UTF-8 ein: Whle dafr im Men FORMAT den Befehl UTF-8. Nur
dann werden deine Umlaute und Sonderzeichen richtig dargestellt!
In einigen Kapiteln jedoch mssen wir eine Ausnahme machen. Dort
schreiben wir statt utf-8 einfach iso-8859-1. Wir whlen auerdem
FORMAT|ANSI. Das beugt Problemen mit Umlauten beim Versenden von
E-Mails vor. Ich mache dich rechtzeitig darauf aufmerksam!
Und nun brauchst du diese aktualisierte Vorlage nur noch zu speichern.
Whle DATEI|SPEICHERN. Vorlagen legt PSPad automatisch im Ordner
Template ab. Im Beispiel findest du die bearbeitete Datei unter dem Pfad
C:\Programme\PSPad Editor\Template\HTML 4.01 Transitional.html.
33
HTML auf Knopfdruck mit PSPad

Eine HTML-Datei erstellen
Voil jetzt endlich erzeugst du eine HTML-Seite. Whle wieder DATEI|NEU,
Register Neue Datei aus Vorlage erstellen. Navigiere erneut zum Zweig
HTML und diesmal doppelklicke gleich auf HTML 4.01 Transitional. (Mar-
kieren und Klick auf OK geht auch.) Erneut entsteht das oben gezeigte,
ideale Grundgerst einer HTML-Datei. Allerdings nicht als Vorlage, sondern
gleich als HTML-Datei. Und die schauen wir uns jetzt etwas genauer an!
Die lange Zeile 1 ist eine Ausnahme, eine reine Formalie. Dahinter steckt
die sogenannte Dokumenttypdeklaration (kurz DTD). Damit zeigen wir, dass
es sich um HTML in der Version 4.01 handelt (bergangsfassung). Zu
lang, das Biest? Von dieser DTD gibt es zum Glck auch eine Kurzform:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
Aus Platzgrnden verwende und zeige ich im Buch ab Kapitel 2 nur noch
die Kurzform. Soviel vorweg: In HTML 5 soll das ganze DTD-Gebilde dras-
tisch verkrzt werden: <!DOCTYPE html>. Zum Glck!
Der eigentliche Beginn steckt im Tag <html>, hier geht es los. Wie die
meisten Tags tritt auch dieses Tag paarweise auf: Auf das Einschalt-Tag
<html> folgt ein Ausschalt-Tag. In Zeile 10 wird das Tag per </html>
wieder abgeschaltet! Im Tag <html> befindet sich das Attribut lang mit
dem Wert de. Damit zeigen wir, dass diese Webseite in Deutsch verfasst ist.
Als nchstes folgt der Kopf, der Head. Dieser steckt zwischen den Tags
<head></head>, also zwischen Zeile 3 und Zeile 6. Wichtig ist der Titel
(<title></title>). Was du zwischen diesen Tags notierst, erscheint
spter in der Titelzeile des Browsers. Also in der blauen Leiste ganz oben.
>
Trage hier doch einmal etwas Sinnvolles ein. Ersetze Hier Titel eintra-
gen einfach durch den Text Homepage von Computerhund Buffi!
Was bedeutet Zeile 5? Mit diesem sogenannten Meta-Tag lege ich den
Zeichensatz fest. Mit charset=utf-8 sorge ich dafr, dass du mit Umlau-
ten wie , , und dem arbeiten kannst. Ein Ausschalt-Tag ist in diesem
Fall ausnahmsweise nicht ntig. Meta-Tags treten nicht paarweise auf.
Frher wurden Umlaute und Sonderzeichen wie das umschrieben.
Statt schrieb man z. B. &auml; und aus wurde &ouml; usw. usf. Das
wurde durch &szlig; ersetzt. Dank utf-8 ersparen wir uns diese
Qual und ermglichen den Einsatz praktisch beliebiger Zeichen. Deine
Homepage ist damit gleich gut gerstet fr alle Sprachen der Welt!
34
Deine coole Homepage mit HTML

Kapitel
1
In Zeile 7 wird der Krper des Dokuments eingeschaltet, der sogenannte
Body. Zeile 9 schaltet den Body wieder ab.
Speichern nicht vergessen!
Vergiss nicht, dein Projekt zu speichern. HTML-Dokumente sind Textdoku-
mente. Sie werden mit der Endung htm bzw. html versehen. Ich schlage
den Namen index.html vor. Warum? Eine Hauptseite wird in aller Regel
index.html genannt!
Und so speicherst du in PSPad:
>
Whle im Men DATEI den SPEICHERN-Befehl (oder tippe die Tasten-
kombination [Strg] + [S], das geht viel fixer!). Das Dialogfenster zum
Speichern erscheint, der Fokus steht auf dem Feld Dateiname.
>
Tippe den Dateinamen ein, im Beispiel index.html. Navigiere zu
dem Ordner, in dem du speichern mchtest. Im Beispiel gehst du zu
C:\phpkid\html im Feld Speichern in muss jetzt html stehen.
>
Klicke auf SPEICHERN, um die neue HTML-Datei zu sichern.

Achte darauf, die Datei im richtigen Ordner abzulegen!
>
Schaue in den linken Bereich, zum Toolfenster mit dem Mini-Explorer.
Diesen Mini-Explorer erreichst du ber das zweite Register. Navigiere
hier zu dem Ordner, in dem du gespeichert hast. Im Beispiel gehst du
zu C:\phpkid\html und klickst den Ordner html an.
>
Im unteren Bereich des Toolfensters findest du die Dateiliste. Hier
sollte die index.html als Symbol zu sehen sein. Hat es geklappt?
Du kannst dieses pfiffige Toolfenster auch ausblenden. Whle AN-
SICHT|TOOLFENSTER oder die Tastenkombination [Strg] + [F2]. Eine erneu-
te Wahl dieses Befehls blendet das Toolfenster wieder ein.
35
So wirds perfekt: berschriften, Abstze und mehr

So wirds perfekt: berschriften,
Abstze und mehr
Und, wie schauts aus? Bewundere deine Seite doch einmal in der Vor-
schau! Dafr bietet dir PSPad folgende zwei Mglichkeiten:
ffnen im internen Browser
Das ffnen im internen Browser ist ganz einfach. Drcke die Funktionstaste
[F10], klicke das Weltkugel-Symbol an oder whle HTML|VORSCHAU IM IN-
TERNEN BROWSER. Schon ffnet sich ein neues Fenster und zeigt deine Seite.

Noch besser jedoch ist die externe Browservorschau. Dabei ffnet sich der
Browser in einem eigenen Fenster und du hast den vollen berblick. Nur
hier wird auch der ungeheuer wichtige Seitentitel dargestellt, also der Text
zwischen den Tags <title></title>.
ffnen im externen Browser
Schaue in den linken unteren Bereich, zum Toolfenster. Whle oben das
zweite Register, das mit dem Ordnersymbol. Achte darauf, dass der Ordner
html unter phpkid markiert ist. Schaue dann etwas
tiefer und zwar dorthin, wo die einzelnen Dateien
des markierten Ordners angezeigt werden.
Klicke mit der rechten Maustaste auf die zu ffnende
Datei, rechtsklicke im Beispiel also auf index.html.
Das Kontextmen erscheint. Whle ganz oben den
Befehl FFNEN. Die HTML-Seite wird im Standardbrowser geffnet, in aller
Regel ist das der Internet Explorer, bei mir jedoch der Firefox.
Du mchtest einen anderen Browser whlen? Dann verwende den Befehl
FFNEN MIT und suche den anderen Browser heraus. Der Browser ist nicht
aufgelistet? Suche ihn aus dem Dateisystem deiner Festplatte heraus.
Das gelingt beispielsweise ber die Schaltflche DURCHSUCHEN bzw.
PROGRAMM AUSWHLEN. Mozilla Firefox liegt in der Regel unter dem Pfad
C:\Programme\Mozilla Firefox.
36
Deine coole Homepage mit HTML

Kapitel
1

Die HTML-Seite in der externen Vorschau. Als Browser habe ich den Firefox gewhlt.
Die Seite ist leer, aber der Seitentitel von Zeile 4 steht schon da. Wo? Na
ganz oben in der Titelzeile des Browsers. Dort steht nun ebenfalls Home-
page von Computerhund Buffi.
Du wunderst dich, warum bis jetzt noch kein Inhalt im Dokument zu se-
hen ist? Du hattest doch noch nichts hineingeschrieben! Der Bereich
zwischen <body></body> ist schlielich noch leer! Nur der Seitentitel
ist schon vorhanden und der wird ja auch angezeigt!
Leben einhauchen: berschriften und Absatz
>
Hauche deinem Dokument Leben ein: Klicke dazu in die bisher noch
leere Zeile. Es ist die Zeile 8. Wir wagen uns nun an den Body. Schaffe
ruhig durch mehrmaligen Druck auf [Enter] ein paar Zeilen Platz.
Auch der Buch-Hund Buffi wollte es sich nicht nehmen lassen, endlich
mit einer eigenen Homepage aufzuwarten. Bitte sehr in diesem Kapitel
darf er endlich aktiv werden.
Orientiere dich an Buffis Beispiel. Schreibe es ab. Ich empfehle dir, die
HTML-Befehle erst einmal exakt so aus dem Beispiel zu bernehmen. (Nur
den Text kannst du so ndern, dass er auf dich zutrifft!)
<h1>Homepage von Buffi</h1>
<p>Guten Tag! Mein Name ist Buffi! Ich bin von Beruf
<b>Computerkinder-Hund</b> mit <i>allumfassender
Allgemeinbildung</i>. Meine Freunde heien Tim und
Nele.</p>
<h2>Hier zeige ich dir ein Bild von mir!</h2>

37
So wirds perfekt: berschriften, Abstze und mehr


So wird der Code in PSPad dargestellt. Du kannst ruhig immer wieder [Enter] drcken, um
den Code ordentlich auszurichten. Auf die Anzeige im Browser hat das keinen Einfluss.
Was haben wir da gemacht? Wir fangen mit einer berschrift an! Mit dem
Tag-Paar <h1></h1> kennzeichnest du die heading 1, die Hauptber-
schrift. Hier schmettert dir Buffi sein Homepage von Buffi entgegen.

Im Text gibt es gleich noch eine weitere berschrift, und zwar Hier zeige
ich dir ein Bild von mir! Es ist eine heading 2, eine Unterberschrift auf
zweiter Stufe. Diese wird stets vom Tag-Paar <h2></h2> eingerahmt.
Insgesamt gibt es brigens sechs berschriftsebenen, du knntest also
auch eine <h3></h3>, <h4></h4> usw. einsetzen.
Doch ein HTML-Dokument besteht nicht nur aus berschriften. Was ist mit
dem Textabsatz mittendrin? Auch hierfr gibt es das passende Tag-Paar.
Textpassagen umwickelst du einfach mit dem Tag-Paar <p></p> ein. Das
p steht dabei fr paragraph, zu Deutsch Absatz.
Die Homepage beginnt
mit einer Hauptber-
schrift.
38
Deine coole Homepage mit HTML

Kapitel
1

Wenn du mchtest, kannst du den Text innerhalb von Tags durch das so-
genannte Stil-Attribut style (Attribut = Eigenschaft) gestalten. Deine
berschriften und Abstze stehen normalerweise bndig am linken Rand,
also linksbndig. Deine Hauptberschrift soll auer der Reihe zentriert
(mittig) ausgerichtet werden? Ergnze im Einschalt-Tag <h1> einfach
das Attribut-Werte-Paar style="text-align: center" und zwar
nach einem Leerzeichen. Hinter diesem Stil-Attribut style verbirgt sich
die Gestaltungssprache CSS. Die Angabe text-align: bezieht sich auf
die Textausrichtung und center steht fr zentriert.
Dann sieht es so aus:
<h1 style="text-align: center">Homepage von Buffi</h1>

Falls du die berschrift dagegen nach rechts setzen mchtest, notierst du
das folgendermaen: <h1 style="text-align: right">.
Probiere es ruhig einmal aus! Es gelingt mit berschriften und Abstzen,
mit sogenannten Blockelementen. Genug probiert? Dann kannst du diesen
Zusatz auch wieder lschen. Ich verzichte im Beispiel auf diesen Zusatz!
Ich empfehle dir dringend, CSS zu lernen, damit du die wichtigsten Attribu-
te und Werte zum Gestalten kennst!
Tags zur Hervorhebung von Zeichen
Sicher gibst du dich nicht mit blankem Text zufrieden. Das wre doch
langweilig! Schau einmal in den Absatz. Auch hier findest du schon weitere
interessante Tags vor.
Mit <b></b> (b wie bold) kannst du Wrter oder Wortgruppen hervorhe-
ben. Sie werden dann fett angezeigt. Das Tag-Paar <i></i> (wie italic,
kursiv) dagegen sorgt fr eine Kursivstellung der entsprechenden Passage.
Die Tag-Paare <b></b> und <i></i> galten bis vor kurzem noch als
veraltet. Als Alternative sollte man zu <strong></strong> und <em>
</em> greifen. Die gute Nachricht: <b></b> und <i></i> werden in
HTML 5 weiterleben, wenn auch mit leicht vernderter Bedeutung. Es
gibt also keinen Grund, auf diese klassischen Tags zu verzichten!
Geht auch: Stelle die
berschrift einfach in
die Mitte!
39
So wirds perfekt: berschriften, Abstze und mehr

Die wichtigsten HTML-Tags im berblick
In dieser Tabelle zeige ich dir die wichtigsten HTML-Tags und ihre Bedeu-
tung im berblick:
Tag-Paar Bedeutung Wie siehts aus?
<h1></h1> Heading 1
berschrift 1
fett, sehr gro
<h2></h2> berschrift 2 fett, gro
<h3></h3> berschrift 3 fett, mittelgro
<h4></h4> berschrift 4 fett, normal
<h5></h5> berschrift 5 fett, klein
<h6></h6> berschrift 6 fett, sehr klein
<b></b> bold fett Text wird fett dargestellt
<strong></strong> strong stark Text wird ebenfalls fett
<i></i> italics kursiv Text wird kursiv dargestellt
<em></em> emphatic
hervorgehoben
Text wird ebenfalls kursiv
<blockquote>
</blockquote>
langes Zitat wird eingerckt dargestellt.
<small></small> small klein Text wird verkleinert dargestellt

Wenn du eine Linie setzen mchtest, verwendest du das Tag <hr>. Dieses
Tag braucht ausnahmsweise kein End-Tag.
Auerdem gibt es den sogenannten break, einen Zeilenumbruch. Wenn du
ein Wort auf eine neue Zeile setzen mchtest, setzt du davor einfach das
Tag <br>. Damit rutscht das Wort auf die neue Zeile, ohne dass gleich ein
neuer Absatz beginnt. Auch <br> bentigt kein End-Tag.
An dieser Stelle gleich ein interessantes Detail: Die Schreibweise <hr>
(fr eine Linie) bzw. <br> (fr den break, Zeilenumbruch) ist die klassi-
sche Schreibweise. Du findest auf vielen Seiten auch die XHTML-Variante
<hr /> bzw. <br /> vor. Dabei bekommt das Tag nach einem Leerzei-
chen einen internen Ausschalt-Slash, so einen Schrgstrich.
Das macht man deshalb, weil in der XHTML-Schreibweise jedes Tag aus-
geschaltet werden muss. Und da ein <hr>- oder <br>-Tag nun mal kein
Ausschalt-Tag kennt, schaltet man es einfach intern ab. In der Praxis fin-
dest du beide Schreibweisen vor. Selbst PHP verwendet Elemente aus
XHTML. (Wir aber bleiben bei der bewhrten klassischen Schreibweise.)
Genug gelabert, jetzt wollen wir unsere Homepage mit einem Bild etwas
aufpolieren!
40
Deine coole Homepage mit HTML

Kapitel
1 Hier bin ich: Ein Bild einfgen
Hast du irgendwo ein Foto von dir auf der Festplatte herumliegen? Viel-
leicht vom Scanner oder der Digicam? Hauptsache es liegt im Format GIF,
JPG oder PNG vor. (Andere Formate sind fr das Internet nicht geeignet.)
Du hast momentan keine derartige Grafik? Dann nimm zum ben ein-
fach ein Bild von mir! Du findest die Datei buffi.png auf der CD im
Ordner beispiele/kapitel01.
Wichtig: Dein Bild sollte nicht zu hoch und breit sein. Es sollte also, wenn
du es im Grafikprogramm aufrufst, nicht die ganze Breite und Hhe des
Bildschirms ausfllen. Die Abbildung von Buffi ist 445 Pixel breit und 310
Pixel hoch. (Pixel sind Bildpunkte, eine Maeinheit auf dem Bildschirm.)
Fgen wir das Bild nun ganz schnell in unsere Homepage ein! Und zwar
unterhalb der schon vorbereiteten berschrift 2.
>
Achte zuerst darauf, dass die Grafik im gleichen Ordner liegt wie dei-
ne HTML-Datei. Das ist zwar nicht unbedingt ntig, macht das Einf-
gen aber einfacher. Kopiere das Bild also in den Ordner html. Die Bei-
spielgrafik fr Buffi heit buffi.png.
>
Sorge in PSPad dafr, dass der Mini-Editor mit der Dateiansicht sicht-
bar ist. Du weit schon, per Toolfenster, zweites Register. Du schaltest
das Toolfenster ber das Men ANSICHT ein bzw. aus.
>
An welcher Stelle mchtest du die Grafik einfgen? Schaffe hier eine
Leerzeile, drcke also auf [Enter]. Und jetzt geht es los: Ziehe die
Grafikdatei aus der Dateiliste direkt in das Dokument. Und zwar an
die gewnschte Stelle:

Klicken und ziehen so einfach fgst du eine Grafik ein.
41
Hier bin ich: Ein Bild einfgen

Hurra, die Grafik ist da! Das entsprechende Tag wurde fix und fertig einge-
fgt, mit allem Drum und Dran. Im Beispiel sieht die lange Zeile so aus:
<img src="buffi.png" alt="buffi.png, 27kB"
title="Buffi" border="0" height="310" width="445">

Das Attribut-Werte-Paar border="0" dient zum Unterdrcken einer even-
tuellen Umrandung.
Hintergrund dieser border-Geschichte: Wenn eine Grafik zum Hyperlink
gemacht wird, bekommt sie dadurch automatisch eine krftige blaue
Umrandung. Das ist nun einmal so bei Hyperlinks auf Grafiken. Um diese
hssliche Umrandung zu unterdrcken, schreiben PSPad und andere Edi-
toren zur Sicherheit das Attribut-Werte-Paar border="0".
Grafik nur innerhalb eines Blocks einfgen
Wir sind noch nicht fertig mit der Grafik und mit den Regeln. Denn es gilt
weiterhin: Eine Grafik sollte stets innerhalb eines Absatzes eingefgt
werden. Oder innerhalb eines anderen sogenannten Block-Elements. (Tipp:
Auch eine berschrift wie <h1></h1> oder <h2></h2> ist ein Block-
Element.) So verlangt das der Standard zu HTML 4. Und wir wollen im Buch
schlielich genau nach Standard vorgehen!
Okay, wenns denn so gewnscht wird, machen wirs einfach. Wir packen
die Grafik zustzlich noch in ein Block-Element. Welches nehmen wir? Den
Absatz! Setze also vor der Grafik das einleitende <p>-Tag. Schalte es hinter
der Grafik mit </p> wieder ab.
<p>
<img src="buffi.png" alt="buffi.png, 27kB" title="Buffi"
border="0" height="310" width="445">
</p>

Erst durch diese Erweiterung haben wir eine standardgerecht eingefgte Grafik!
Was bedeuten die Attribute von <img>?
Schaue dir das eben eingefgte Tag fr die Grafik doch etwas genauer an.
Es handelt sich um das Tag <img>. Zuerst fllt dir vielleicht auf, dass auch
<img> kein Endtag bentigt. Wieder eine Ausnahme. Doch was bedeuten
die Attribute?
42
Deine coole Homepage mit HTML

Kapitel
1
0 Das Attribut src steht fr source, Quelle. Als Wert gibst du den Grafik-
namen in Gnsefchen an. (Sollte sich die Grafik in einem Unterordner
befinden, musst du den Pfad ebenfalls notieren.)
0 Das Attribut alt sorgt nicht etwa dafr, dass die Grafik alt aussieht.
Im Gegenteil! Dieses Attribut erzeugt einen sogenannten Alternativtext.
Der ist wichtig fr Suchmaschinen und fr Leute, die nicht gut sehen
knnen. (Sie lassen sich diesen alternativen Text vom Browser einfach
vorlesen!) Nach dem Gleichheitszeichen tippst du ein beschreibendes
Wort oder eine Wortgruppe. Ersetze also den Platzhaltertext von PSPad
beispielsweise durch eine Wortgruppe wie Computerkinder-Hund Buffi.
0 Das Attribut title stelle ich dir in der nchsten Abbildung vor. Es er-
zeugt nun einen Titel fr das Bild. Den Effekt siehst du, wenn du
den Mauszeiger ber die Abbildung fhrst. Auch hier knnte ruhig mehr
Text stehen aus Platzgrnden lasse ich das im Beispiel jedoch sein.

0 Die Attribute width und height kmmern sich um Breite und Hhe
der Grafik. Die Grafik von Buffi ist im Beispiel 445 Pixel breit und 310
Pixel hoch. Die Reihenfolge, in der man die Attribute angibt, ist dabei
egal. Du kannst sie auch vertauschen.
Es gibt brigens eine modernere Schreibweise fr die drei Attribute
border, height und width. Und zwar mit der Stil- und Formatierspra-
che CSS. Ersetze border="0" height="310" width="445" einfach
durch: style="border: 0; height: 310px; width: 445px;". Du
schreibst also nur noch das style-Attribut und setzt alle weiteren CSS-
Anweisungen in Gnsefchen. Mehr zu CSS folgt weiter hinten!

43
Meine Hobbys kurz aufgelistet

Mit dem style-Attribut von CSS sieht das <img>-Tag dann so aus:
<p>
<img src="buffi.png" alt="buffi.png, 27kB" title="Buffi"
style="border: 0; height: 310px; width: 445px;">
</p>
Meine Hobbys kurz aufgelistet
Noch nicht fertig! Schreibe auf, welchen Hobbys du frnst! Skateboardfah-
ren? Inlineskaten? Lesen? Programmieren? Manga-Zeichnen? Pokemon-
Karten sammeln? WoW spielen? Was auch immer: Fr solche Dinge bieten
sich in idealer Weise die Listen an.
Mit Aufzhlungspunkten: Ungeordnete Liste
Im ersten Vorschlag verwenden wir eine sogenannte unordered list, eine
ungeordnete Liste. Das entsprechende Tag-Paar heit <ul></ul>. Die
einzelnen Listen-Eintrge wiederum werden in <li></li> eingekleidet.
Dieses li steht dabei als Abkrzung fr list item.
Schluss mit dem Englischunterricht, ran an das Beispiel. Ich zeige dir den
gesamten Rest des Dokuments. Die Liste beginnt unter der neu eingefgten
H3 Ich habe folgende Hobbys. Ergnze also noch die berschrift und lege
dann mit deinen Hobbys los!
...
<h2>Hier zeige ich dir ein Bild von mir!</h2>
<p>
<img src="buffi.png" alt="Computerkinder-Hund Buffi"
title="Buffi" border="0" height="310" width="445">
</p>

<h3>Ich habe folgende Hobbys:</h3>
<ul>
<li>Sterne betrachten</li>
<li>Inlineskaten</li>
<li>Harry Potter lesen</li>
<li>Homepages fr Freunde erstellen</li>
</ul>

</body>
</html>
44
Deine coole Homepage mit HTML

Kapitel
1

In einer solchen unordered list bekommt jeder Aufzhlungspunkt einen
kleinen Kreis vorangestellt. Sieht doch irgendwie knuffig aus, nicht wahr?

Eins, zwei, drei: Ordnung schaffen durch
Nummerierung
Du mchtest deine Hobbys lieber durchnummerieren? Auch dieser Wunsch
lsst sich leicht erfllen! Bringe Ordnung ins Chaos: Verwende eine ordered
list.
Ersetze einfach das Tag-Paar <ul></ul> durch <ol></ol>. Wie von Geis-
terhand werden deine Eintrge nun durchnummeriert.
<h3>Ich habe folgende Hobbys:</h3>
<ol>
<li>Sterne betrachten</li>
<li>Inlineskaten</li>
<li>Harry Potter lesen</li>
<li>Homepages fr Freunde erstellen</li>
</ol>

Das Schnste: Du kannst nun nachtrglich so viele Eintrge hinzufgen,
wie du mchtest. Die Nummerierung passt sich immer wieder an!
Skaten, Lesen, Home-
page erstellen? Hier ist
die Liste fr deine
Hobbys!
45
Coole Links zu coolen Pltzen


Coole Links zu coolen Pltzen
Was wre das Web ohne die Hyperlinks? Ein Nichts! Es wrde gar nicht
existieren! Erst durch diese Kreuz- und Querverweise werden deine Seiten
richtig lebendig. Linke zu den schnsten und interessantesten Pltzen im
Web. Wirf deine Anker aus.
Einfache Hyperlinks erstellen
Auf welche Seiten verlinkst du? Buffi whlt seinen Heimatverlag und
netterweise auch die Seiten des Buchautors (Danke, Buffi!). Hier die ent-
sprechenden Adressen, die sogenannten URLs.
0 http://www.it-fachportal.de
0 http://www.phpkid.de
Zum Erstellen von Querverweisen (Links) verwendest du das <a>-Tag. Das a
steht fr Anker. Du wirfst also einen Anker aus. Als Ziel verwendest du die
entsprechende Webadresse. Und dafr brauchst du zustzlich das Attribut
href. Denn erst mit diesem Attribut kannst du die Zieladresse fr <a> an-
geben. Geschafft? Danach notierst du den beschreibenden Text. Hier ein
Beispiel:
<a href="http://www.it-fachportal.de">Mein Heimatverlag</a>

Nicht vergessen: Das Tag wird zum Schluss natrlich durch </a> abge-
schaltet.
Eine Web-Adresse muss bei Hyperlinks stets ausgeschrieben werden. Die
einfache Abkrzung nach dem Motto www.it-fachportal.de oder gar
it-fachportal.de ist hier nicht erlaubt. Im Zweifelsfall wird der Link
nicht funktionieren.
Hobby by Number: Eine
durchnummerierte Liste.
46
Deine coole Homepage mit HTML

Kapitel
1
So sieht der Quelltext fr das gesamte Hyperlink-Beispiel von Hund Buffi
aus:
<p>
<strong>Besuche doch einmal folgende Seiten</strong>:<br>
<a href="http://www.it-fachportal.de">Mein Heimatverlag</a> -
<a href="http://www.phpkid.de">Serviceseite zum Buch</a>
</p>

Auf eine berschrift hat Buffi diesmal verzichtet. Der Abschnitt mit den
Hyperlinks wurde in einen Absatz (<p></p>) eingehllt. Doch was passiert
innerhalb dieses Absatzes?
Zur Abwechslung findest du diesmal das Tag-Paar <strong></strong>
vor. Praktisch als berschrifts-Ersatz. Dadurch wird die entsprechende
Passage fett hervorgehoben und strkerer betont.
Danach hat Hund Buffi einen Zeilenumbruch gesetzt, den schon bespro-
chenen break <br>. Solch ein Umbruch erzeugt eine neue Zeile. Dabei ent-
steht jedoch kein neuer Absatz! (Du erkennst es in der Vorschau: Der Ab-
stand zwischen den Zeilen ist geringer!)
Nun folgen die Hyperlinks nebeneinander, aus optischen Grnden nur durch
einen Bindestrich voneinander getrennt.

Parke doch einmal den Mauszeiger ber einem Hyperlink. Schon erscheint
das Verweis-Ziel in der Statuszeile, also in der unteren Zeile des Browsers.
brigens: Du musst nicht immer auf eine externe Webseite verweisen.
Setze Links vor allem innerhalb deines Web-Projekts. Verweise von ei-
ner Seite auf die andere. Du willst auf der Startseite auf eine Unterseite
namens hobby.html verweisen? Diese liegt im gleichen Ordner wie die
Startseite? Als Linkbeschreibung soll der Text Meine Interessen verwen-
det werden? Dann sieht der interne Links so aus:
<a href="hobby.html">Meine Interessen</a>
Unbesuchte Hyperlinks
sind per Voreinstellung
blau, besuchte frben
sich lila.
47
Meine drei Lieblingsfcher in einer Tabelle

Wie wre es mit ein paar Tipps und Tricks zu Hyperlinks?
>
Du mchtest, dass sich nach Klick auf den Link ein eigenes Fenster
bzw. ein neuer Browsertab ffnet? Dann notiere ganz einfach zustz-
lich das Attribut-Werte-Paar target="_blank" im <a>-Tag:
<a href="http://www.it-fachportal.de" target="_blank">
Mein Heimatverlag</a>

>
Du mchtest, dass beim Darberfahren mit dem Mauszeiger ein in-
formativer Beschreibungstext auf dem Hyperlink erscheint? Dann er-
gnze das schon bekannte Attribut title (Beschreibungstitel). Gib
als Wert ein beschreibendes Wort oder eine Wortgruppe an:
<a href="http://www.bhv.de" title="Software fr Kids">
Lernsoftware und mehr</a>

>
Du mchtest die Farbe der Hyperlinks ndern? Die Unstreichung ab-
schalten? Das alles gelingt mit Style Sheets. Blttere einfach ein
Stck weiter nach hinten, dort verraten wir dir mehr zu diesem The-
ma.
Meine drei Lieblingsfcher in
einer Tabelle
Schreiben wir zur Abwechslung doch mal eine Tabelle. Warum? Weil es
Spa macht! Und weil Tabellen auf HTML-Seiten eine ganz wichtige Rolle
spielen. Und weil du Tabellen kennenlernen solltest. Sind das genug Grn-
de? Dann los!
Grundaufbau der Tabellen
Was musst du zu Tabellen wissen? Nicht viel!
0 Jede Tabelle wird vom Tag-Paar <table></table> eingerahmt. (Table
ist das englische Wort fr Tabelle!)
0 Eine Zeile steht innerhalb von <tr></tr> (table row heit Tabellen-
zeile).
0 Eine einzelne Zelle (das Tabellenkstchen) wird zwischen <td></td>
gequetscht. Mit td ist table data genannt, frei bersetzt Zellinhalt.
48
Deine coole Homepage mit HTML

Kapitel
1
0 Mchtest du eine Zelle besonders hervorheben, whlst du statt
<td></td> einfach <th></th> fr table head. Eine solcherart gestal-
tete Zelle wird fett hervorgehoben. Der Inhalt wird zentriert.
Das Beispiel
Zuerst zeige ich dir das Beispiel. Eine Tabelle besteht aus Zeilen und Spal-
ten. Diese werden durch die Tabellenkstchen (Zellen) gebildet.

Das Beispiel sieht im Quelltext folgendermaen aus:
<table border="1">
<tr>
<th>Lieblingsfach</th><th>Warum?</th>
</tr>
<tr>
<td>Informatik</td><td>Weil ich der Beste bin!</td>
</tr>
<tr>
<td>Physik</td><td>Weil wir lernen, wie ein Motor
funktioniert.</td>
</tr>
<tr>
<td>Zeichnen</td><td>Weil der Lehrer mit uns Manga-Comics
zeichnet.</td>
</tr>
</table>

Die Beispiel-Tabelle
besteht aus vier Zeilen
und zwei Spalten.
49
Schickes Layout mit Style Sheets

Die Erklrung
Durchschaust du die Struktur? Zuerst setzen wir das einleitende Tag
<table> und drcken schon ein paar Mal [Enter]. Damit schaffen wir
etwas Luft. Nicht vergessen: Schalte das <table>-Einschalt-Tag gleich
jetzt am Ende der Tabelle mit </table> wieder ab!
Damit die Tabelle einen Rahmen erhlt, arbeite ich gleichzeitig mit dem
Attribut-Werte-Paar border="1". Das einleitende Tabellen-Tag sieht
also so aus: <table border="1">. (Wenn du den Rahmen vergrern
willst, erhhst du einfach den Wert hinter border. Mit border="5" be-
kommst du beispielsweise einen 5 Pixel dicken Rand.)
Danach definiere ich die erste von vier Zeilen. Ich schreibe <tr>, lasse da-
nach ein paar Zeilen frei und setze das abschlieende </tr>. Wenn du
willst, kannst du alle vier Zeilen schon derart vorbereiten, hier zumindest
zwei Zeilen:
<tr>
...
</tr>
<tr>
...
</tr>

Nun kmmern wir uns um die einzelnen Kstchen der Tabelle. Die erste
Zeile bekommt zweimal <th></th> spendiert. Es soll schlielich der
Tabellenkopf werden. In den brigen Zeilen begngen wir uns mit je zwei-
mal <td></td> fr den normalen Zellinhalt.
Wie gesagt, was dann in der Zelle selber erscheinen soll, wird einfach zwi-
schen <th></th> bzw. <td></td> notiert. So weit, so gut. Aber ich wuss-
te gar nicht, dass Buffi noch zur Schule geht
Schickes Layout mit Style Sheets
Coole Seite? Von wegen! Bis jetzt sieht unser Projekt aus wie eine Kakerla-
ke hinterm Kchenschrank farblos und platt. Dagegen sollten wir etwas
unternehmen, und zwar mit Style Sheets. Lege Schriftart, Schriftgre und
Farben fest! Verpasse den Hyperlinks einen Mouseover-Effekt. Du wirst
staunen, mit wie wenig Aufwand man seine Seiten aufpeppen kann.
50
Deine coole Homepage mit HTML

Kapitel
1 Style Sheets sind eine ganz fabelhafte Geschichte. Du legst einmal fest,
wie deine Homepage auszusehen hat. Das machst du am besten in einer
extra Datei. Dadurch erstellst du eine Art Musterschablone. Dieses Ge-
staltungs-Muster kannst du nun beliebig oft fr weitere HTML-Seiten
verwenden. Das spart viel Arbeit! Wichtig: Style-Sheet-Dateien sind
Textdateien mit der Endung .css.
Verweis auf CSS-Datei setzen
Also, frisch ans Werk. Worauf wartest du noch? Die extra Stil-Datei soll
im Beispiel phpkid.css heien. Sie wird im gleichen Ordner entstehen
wie unsere HTML-Datei. Doch zuerst setzen wir einen Verweis auf diese
Datei. Wir binden sie also in unser HTML-Dokument index.html ein. Und
zwar in den Kopfbereich, in den Head:
>
Suche diese Zeile:
<meta http-equiv="content-type" content="text/html;
charset=utf-8">

>
Klicke hinter diese Zeile und drcke [Enter]. Damit erzeugst du eine
leere Zeile dort notierst du gleich den Verweis zur Stildatei. Das ge-
lingt mit dem Tag <link> und seinen Attributen:
<link rel="stylesheet" type="text/css" href="phpkid.css">

Insgesamt sieht der Anfang der HTML-Datei also so aus:
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
2 <html lang="de">
3 <head>
4 <title>Homepage von Computerhund Buffi</title>
5 <meta http-equiv="content-type" content="text/html;
charset=utf-8">
6 <link rel="stylesheet" type="text/css"
href="phpkid.css">
7 </head>

Lass dich von der Syntax dieser Zeile 6 nicht zu sehr entmutigen. Wichtig
ist das Attribut href. Hinter dem Gleichheitszeichen setzt du den Namen
der CSS-Datei ein, umkleidet von Gnsefchen.
51
Schickes Layout mit Style Sheets

Du speicherst deine HTML-Datei, aktualisierst die Vorschau und es pas-
siert rein gar nichts? Na klar! Wir haben einen Link auf eine Datei er-
stellt, die es noch gar nicht gibt. Da wartet also ein Stck Arbeit auf uns.
CSS-Datei erstellen
Eine CSS-Datei ist nichts weiter als eine Textdatei mit der Endung .css.
Also, erstelle eine neue Textdatei.
>
Whle in PSPad DATEI|NEU. Das Dialogfenster Neu erscheint, du soll-
test dich im Register Neue Datei aus Vorlage erstellen befinden. Wh-
le den Ordner CSS und doppelklicke auf Default.
>
PSPad fgt eine fast leere CSS-Datei ein und schaltet auf die CSS-
Farbhervorhebung um. Der Text /* CSS Document */ beweist, dass
es sich um eine CSS-Datei handelt. Lsche diese Platzhalter-Zeile!
>
Ehe ich Style Sheets jetzt gro und breit erklre, legen wir los! Tippe
zuerst folgende drei Zeilen. (Die geschweiften Klammern erzeugst du
mit gedrckter [AltGr]-Taste. Tippe dazu entweder die [7] bzw. [0].)
body {
font-family: Verdana, Arial, Helvetica, sans-serif;
}

>
Speichere die Datei ab. Whle als Dateinamen phpkid.css. Die Datei
wird im Beispiel im gleichen Ordner abgelegt wie das HTML-
Dokument. Achte darauf!
Die Schreibweise fr CSS-Style-Sheets gleicht der von Programmier-
sprachen wie JavaScript oder PHP. So findest du auch in CSS die be-
rhmten geschweiften Klammern. Diese geschweiften Klammern bilden
einen Block. Sie halten praktisch zusammen, was zusammen gehrt.
Auch in CSS wird (fast) jede Zeile durch ein Semikolon (;) abgeschlossen.
Es ist so, wie du es in PHP noch kennenlernen wirst!
Rufe das HTML-Dokument index.html doch einmal in der Browservor-
schau auf. Aktualisiere die Ansicht, z. B. durch Druck auf die Funktionstaste
[F5]. Wahnsinn! Auch einen Schlag ndert sich die Schriftart im gesamten
Dokument. Und das nur mit diesen simplen drei Zeilen. Wie geht das?
Nun, das gesamte Dokument befindet sich zwischen den Tags <body>
</body>. Mit diesem Tag kannst du praktisch alle Textpassagen erreichen,
52
Deine coole Homepage mit HTML

Kapitel
1
<body></body> ist sozusagen die groe Klammer, die alles zusammen-
hlt. Also body, okay. Doch wo sind die spitzen Klammern? Die werden in
CSS nicht mitgeschrieben! Du notierst also das nackige Tag ohne spitze
Klammern. Wir schreiben einfach body und haben damit den sogenannten
Selektor zu Papier gebracht. Wenn das kein Grund zum Feiern ist
Nun setzen wir nach einem Leerzeichen die ffnende geschweifte Klammer.
Der Block beginnt. Mein Tipp: Drcke schon ruhig zweimal auf [Enter].
Setze gleich die schlieende Klammer. (Denn hinterher vergisst man das
oft, glaube mir!) Zwischen diesen Klammern notierst du nun die Formatier-
anweisungen. Im Beispiel handelt es sich um folgende Zeile:
font-family: Verdana, Arial, Helvetica, sans-serif;

Damit legen wir die font-family fest, die Schriftfamilie hier also Verdana.
Am Ende der Zeile setzt du ein Semikolon.
Wenn der Benutzer auf seinem Rechner kein Verdana hat? Dann wird die
Schriftart verwendet, die als nchstes nach dem Komma folgt. Und wenn
es auch hier heit: Fehlanzeige? Dann probiert der Browser, ob er Helve-
tica findet. Sollte das nicht glcken, whlt der Browser irgendeine sach-
liche Schriftart. Dafr sorgt sans-serif am Schluss der Aufreihung.
Das ganze Gebilde mit Selektor und geschweiften Klammern nennt sich
nun Regel. Und tatschlich haben wir damit eine fabelhafte kleine Regel
erstellt, mit der wir die Schriftart fr das gesamte Dokument steuern.
Einige Attribute und Werte von CSS
Neugierig, welche Anweisungen es noch so gibt? Die folgende Tabelle zeigt
dir einige wichtige Attribute und Werte von CSS. In der linken Spalte fin-
dest du jeweils das Beispiel. Rechts erklre ich dir, was passiert.
Beispiel verantwortlich fr
font-family: Arial, Helvetica; Schriftart Arial bzw. Helvetica
font-size: 12pt; Schriftgre 12 Punkt
font-weight: bold; Zeichenformat fett
font-variant: small-caps;
KAPITLCHEN (DAS SIND KLEINE
GROSSBUCHSTABEN)
font-style: italic; Schriftstil (z. B. kursiv)
line-height: 1.2;
Zeilenabstand (z. B. 1,2-zeilig)
margin: 10px; Rand rundherum 10 Pixel
text-decoration: none; Texteffekt (Unterstreichung) abschalten
border-style: solid; Rahmen rundherum ziehen
53
Schn bunt hier: Farben zuweisen

Mehrere Fliegen mit einer Klappe
Nun kennst du schon einige CSS-Eigenschaften. Wunderbar. Kmmere dich
doch einmal um die Schriftgre! Angenommen, du mchtest in Abstzen
(Selektor p), Tabellen (table) und Listeneintrgen (li) eine Schriftgre
von 10 Punkt einrichten.
Dann schlage doch einmal drei Fliegen mit einer Klappe! Reihe die Selekto-
ren vor der ffnenden geschweiften Klammer auf. Dann gilt die Regel fr
alle drei Tags zugleich!
p, table, li {
font-size : 10pt;
}

Warum haben wir in dieser Regel keine Schriftart definiert? Nun, diese
hatten wir doch schon in der body-Regel festgelegt. Schlielich gilt
body fr das gesamte Dokument, also auch fr p, table und li. In die-
ser Regel mssen wir nur noch die Schriftgre bestimmen. Und zwar
zustzlich.
Schn bunt hier: Farben zuweisen
Natrlich kannst du in CSS nicht nur Texteigenschaften, Rnder und Rah-
men festlegen. Arbeite doch einmal mit Farben! Fr die Schriftfarbe
nimmst du das Attribut color. Die Hintergrundfarbe wird dagegen durch
background-color gesteuert.
Farb-Beispiel verantwortlich fr
color: blue;
Farbe blau
background-color: silver;
Hintergrundfarbe hellgrau

Doch wie viele Farben kannst du verwenden? 16,7 Millionen! Und wie stellt
man sie dar? Das geht zum einen mit dem sogenannten Hexadezimalwert.
Das ist eine kryptische Zeichenfolge. Sie beginnt mit einer Raute, gefolgt
von weiteren 36 Stellen. Diese beschreiben die Zusammensetzung aus den
drei Grundfarben Rot, Grn und Blau. Ein Blau sieht so aus: #0000FF.
Zum anderen kannst du diese RGB-Anteile auch auf andere Weise be-
schreiben. Notiere rgb() und trage innerhalb der Klammern die Anteile der
drei Grundfarben ein. Und zwar auf einer Skala von 0 bis 255 getrennt
mit Komma. Ein Blau sieht dann so aus: rgb(0,0,255).
54
Deine coole Homepage mit HTML

Kapitel
1
Du mchtest mit PSPad die gewnschte Farbe zuweisen? Whle WERKZEU-
GE|FARBAUSWAHL bzw. die FARBAUSWAHL-Schaltflche. Setze den Cursor dort-
in, wo der Farbwert stehen soll. Doppelklicke auf deine Wunschfarbe:

Neben den 16,7 Millionen unterschiedlichen Hexadezimal- bzw. RGB-
Farbwerten gibt es aber auch freundlichere Farbnamen. Zumindest fr die
16 Grundfarben. Wenn du dich also auf diese 16 Grundfarben beschrnken
mchtest, whlst du einen der 16 englischen Farbnamen aus.
Eine Gesamtbersicht ber diese Grundfarben zeige ich dir in der Tabelle.
Dabei ist es egal, ob du dich fr den Farbnamen (linke Spalte), den Hexade-
zimalwert oder den RGB-Farbwert (rechte Spalte) entscheidest:

Farbname dahinter steckt Hexadezimalwert RGB-Farbwert
black
schwarz #000000 rgb(0,0,0)
silver
hellgrau #c0c0c0 rgb(192,192,192)
gray
grau #808080 rgb(128,128,128)
white
wei #ffffff rgb(255,255,255)
maroon
kastanienbraun #800000 rgb(128,0,0)
red
rot #ff0000 rgb(255,0,0)
purple
lila #800080 rgb(128,0,128)
fuchsia
hellila #ff00ff rgb(255,0,255)
green
dunkelgrn #008000 rgb(0,128,0)
lime
hellgrn #00ff00 rgb(0,255,0)
olive
olivgrn #808000 rgb(128,128,0)
yellow
gelb #ffff00 rgb(255,255,0)
navy
dunkelblau #000080 rgb(0,0,128)
blue
blau #0000ff rgb(0,0,255)
teal
blaugrn #008080 rgb(0,128,128)
aqua
himmelblau #00ffff rgb(0,255,255)

PSPad verwendet zum
Einfgen der Farben die
freundliche RGB-Syntax.
55
Schn bunt hier: Farben zuweisen

Buffi, gar nicht faul, hat seine Homepage inzwischen komplett mit Style
Sheets aufgebrstet. So sieht seine neue Layout-Page aus.

Die komplette CSS-Datei im berblick
Mchtest du die gesamte CSS-Datei sehen, die Hund Buffi zur Steuerung
seiner Seite geschrieben hat? Bitte sehr. Damit du durch den Code durch-
steigst, habe ich mit beschreibenden Kommentaren gearbeitet.
Kommentare sind Passagen, die nur fr den Autor der Datei interessant
sind. Sie werden nicht ausgefhrt, bleiben praktisch unsichtbar. In CSS
verwendest du die gleichen Kommentarzeichen, die du spter auch in
PHP setzen wirst. Ein Kommentar wird mit /* eingeleitet und endet mit
*/. So kannst du der ersten Regel (also dem Gebilde in geschweiften
Klammern) z. B. folgende Beschreibung voranstellen:
/* Schriftart im gesamten Dokument */
Auerdem empfehle ich dir, mit Leerzeilen fr mehr bersicht zu sorgen.
Was hier wie die reinste Platzverschwendung aussieht, wird uns spter bei
PHP sehr helfen! Aber nun Manege frei fr den CSS-Code:
Welche eine Verwandlung!
CSS bringt Farbe ins Bild.
56
Deine coole Homepage mit HTML

Kapitel
1
/* Schriftart im gesamten Dokument */
body {
font-family: Verdana, Arial, Helvetica, sans-serif;
}

/* Abstze, DIVs, Tabellen, Listen, Formulare in 10 Punkt */
p, div, table, li, form {
font-size: 10pt;
}

/* Hintergrundfarbe grau mit weier Schrift */
h1 {
background-color: gray;
color: white;
}

/* berschrift 2 und 3 blau frben */
h2, h3 {
color: rgb(0,0,153);
}

/* fette Passagen rot einfrben */
b {
color: red;
}

/* kursive Passagen blau frben */
i {
color: rgb(0,0,153);
}

/* Link-Stile fr Hover-Links */
a:link {
color: rgb(0,0,153);
}

a:visited {
color: gray;
}

a:hover {
text-decoration : none;
57
So legst du die exakte Breite fest

color: red;
}

a:active {
color: black;
}

Lies dir den Quelltext ganz in Ruhe durch. Die ersten beiden Regeln haben
wir schon besprochen. Bei der zweiten Regel habe ich gleich die Tags div
und form mit dazu geschrieben. So werden diese Elemente ebenfalls ges-
taltet. (Zu div und form gleich mehr!)
Schon mit der dritten Regel fr h1 erreichst du einen sehr interessanten
Rahmen-Effekt. Die Schrift wird wei eingefrbt. Doch der Hintergrund
erhlt die Farbe grau! Das sieht doch toll aus, oder?
Wenn du genau hinschaust, stellst du fest, dass Buffi auch die Tags
<b></b> und <i></i> aufpoliert hat. Fette Passagen werden zustzlich
rot, kursive dagegen blau eingefrbt.
Du wunderst dich ber den letzten Abschnitt in der CSS-Datei? Was ver-
birgt sich hinter Link-Stile fr Hover-Links? Das sind Sonderflle, damit
erzeugst du den berhmten Hovereffekt beim Darberfahren mit der
Maus! Mit den vier Sonder-Selektoren a:link, a:visited, a:hover
und a:active kannst du die vier Linkzustnde ansprechen. Einmal den
normalen Link, dann den besuchten Link, danach den Link whrend des
Darberfahrens mit der Maus (Hover-Effekt!) und den aktiven Link (wh-
rend des Klickens). Du solltest die Links brigens stets in dieser Reihen-
folge notieren, damit es keine Anzeigeprobleme gibt.
So legst du die exakte Breite fest
Zufrieden? Noch nicht ganz! Verndere doch einmal die Gre des Brow-
serfensters. Ziehe das Fenster lang. Der ganze Text wandert mit.

Die Breite des Textes
richtet sich nach der
Breite des Browser-
fensters.
58
Deine coole Homepage mit HTML

Kapitel
1
Das ist doch der reinste Wanderzirkus!
Zugegeben, auf manchen Seiten ist dieser Effekt beabsichtigt. Unser Hund
wnscht jedoch eine ganz exakte Breite. Die Breite der Seite soll genau
600 Pixel betragen. Nicht mehr und nicht weniger.
Packe den Inhalt in einen Div-Container
Dafr eignet sich ganz ausgezeichnet ein sogenannter Div-Container. Es
handelt sich um das Tag-Paar <div></div>. In dieses Tag-Prchen darfst
du ganze Textpassagen einwickeln. Div darf berschriften, Abstze, Ta-
bellen und Listen enthalten.
Fge direkt unter dem <body>-Einschalt-Tag zuerst eine leere Zeile ein.
Setze dort hinein:
<div>

Schalte dieses Div kurz ber </body> wieder ab. Nun sieht es so aus:
...
<body>
<div>
<h1>Homepage von Buffi</h1>
... viele, viele Zeilen dazwischen ...
</table>
</div>
</body>
</html>
Breite festlegen ber Inline-CSS
Fehlt noch die Breite (width). Richtig, das knnten wir in der CSS-Datei
festlegen. Zu umstndlich! Es handelt sich schlielich nur um eine einzige
Angabe. Wir lsen das Ganze deshalb kurz und schmerzlos mit Inline-CSS.
Bei Inline-CSS werden die CSS-Anweisungen direkt im Tag notiert. Ich
habe es dir in Zusammenhang mit text-align (Absatzausrichtung),
border (Rahmen), width (Breite) und height (Hhe) schon gezeigt!
Eine Inline-CSS-Passage beginnt mit dem Attribut style="...". Die
CSS-Regeln werden nun innerhalb der Gnsefchen notiert. Inline-CSS
ist dann ideal, wenn man kurze Anweisungen festlegen mchte, die sich
nicht wiederholen sollen.
59
Eine Umfrage! Wie findest du meine Page?

Gehe deshalb in das einschaltende <div>. Ergnze style="width:
600px;". Insgesamt sieht das Tag also so aus:
<div style="width: 600px;">



Eine Umfrage! Wie findest du
meine Page?
Du mchtest wissen, wie deine Seite bei den Besuchern ankommt? Erstelle
eine Umfrage! Dazu nimmst du einfach eine neue Seite, die wir im Beispiel
umfrage.html nennen. Speichere sie ebenfalls unter C:/phpkid/html.
>
Baue die Seite auf dem schon bekannten Grundgerst auf. Fge eben-
falls den schon verwendeten CSS-Link zur Datei phpkid.css ein!

Ein Formular mit Radioknpfen
Und hier zeige ich dir den kompletten Quelltext dieser Umfrage. Denke
zuallererst an den Titel. Passe den Bereich zwischen <title></title> an.
Setze eine berschrift in das Dokument.
Exakte Breite durch die
CSS-Regel width: 600px;
Eine Umfrage mit Radio-
knpfen Der Besucher
whlt eine Option aus.
60
Deine coole Homepage mit HTML

Kapitel
1
Aus Platzgrnden habe ich den HTML-Code im Gegensatz zur index.html
nicht eingerckt. Es ist schlielich keine Pflicht. Und wenn du doch einr-
cken willst: Es gibt in PSPad eine clevere Automatik. Mehr dazu gleich
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html lang="de">
<head>
<title>Umfrage: Wie findest du meine Seite?</title>
<meta http-equiv="content-type" content="text/html;
charset=utf-8">
<link rel="stylesheet" type="text/css" href="phpkid.css">
</head>
<body>
<h2>Wie findest du meine Page?</h2>
<form action="">
<p>
<input type="radio" name="ergebnis" value="1"> echt super<br>
<input type="radio" name="ergebnis" value="2"> ziemlich
gut<br>
<input type="radio" name="ergebnis" value="3"> geht so
</p>
<p><input type="submit" value="Absenden"></p>
</form>
</body>
</html>

Das eigentliche Formular beginnt mit dem <form>-Tag. Du musst hier au-
erdem das Attribut action eintragen. Wir haben es jedoch leer gelassen.
(Vergiss nicht, das Formular mit </form> auch wieder abzuschalten.)
Im Formular selber arbeiten wir mit sogenannten Radiobuttons. Dieser Typ
wurde tatschlich von alten Rhrenradios abgeschaut. Drckt man einen
Knopf rein, springt der andere heraus. Radiobuttons werden auch als Kon-
trollkstchen bezeichnet.
Radiobuttons werden mit <input type="radio"> erzeugt. Gib allen
zusammengehrigen Buttons den gleichen Namen. Dazu dient das Attri-
but name. Im Beispiel heien alle Buttons ergebnis. Der value wieder-
um ist der Wert, den der Button beim Absenden mitschickt. Hier be-
kommt jeder Button einen eigenen Wert, z. B. 1, 2 und 3. Das dient zum
spteren Wiedererkennen. Du als Formularbesitzer bekommst schlie-
lich das Name-Werte-Paar zugeschickt, z. B. ergebnis="1".
61
Tipps und Tricks zu PSPad

Submit! Doch wo bleibt die Action?
Jedes Formular bentigt zum Abschicken einen Submit-Button. Submit
steht fr Versenden, bermitteln. Dieser Button sieht im Beispiel so aus:
<input type="submit" value="Absenden">

Der Wert hinter dem Attribut ist brigens die Beschriftung. Du knntest
hier auch Los! oder Klicken auf eigene Gefahr eintragen. Aber darauf
will ich nicht hinaus.
Klappe die Erste. Und Action! Wenn du auf den Submit-Button klickst, geht
die Action los. Es passiert nichts. Oder fast nichts. Kunststck. Schlie-
lich passiert das, was wir im einleitenden <form>-Tag hinter action no-
tiert haben. Doch da steht bis jetzt ebenfalls nichts.
So ganz stimmt das nicht mit dem nichts. Schaue doch einmal in die
Adress-Leiste des Browsers. Nach dem Klicken wird hinter die Adresse
noch ein Fragezeichen angehangen. Nun steht hier pltzlich z. B.
ergebnis=2 (je nachdem, welche Auswahl du getroffen hast). Das ist
doch sehr interessant! Mehr knnen wir an dieser Stelle jedoch nicht
machen. Zum Auswerten des Formularinhalts kommen wir allein mit
HTML nicht weiter. Hier brauchen wir PHP.

Ein Grund mehr, PHP zu lernen!
Tipps und Tricks zu PSPad
PSPad ist ein toller Editor mit vielen genialen Funktionen. Man muss sie nur
kennen.
HTML-Quellcode automatisch ausrichten
Du mchtest den HTML-Quellcode schn einrcken und formatieren? Da-
mit es ordentlich und bersichtlich aussieht? HTML-Kenner wissen: Zustz-
liche Umbrche und Leerzeichen im Editor werden nicht im Browser darge-
stellt. Fazit: Gliedere und formatiere den Quellcode so, wie du magst. Per
Leerzeichen eingerckt, mit zustzlichen Leerabstzen und und und
Keine Lust, das Gliedern von Hand zu erledigen? PSPad bietet dir gleich
zwei Tools. Die sanfte Variante findest du unter HTML|HTML-CODE NEU
62
Deine coole Homepage mit HTML

Kapitel
1
STRUKTURIEREN. Der Code wird ausgerichtet und automatisch eingerckt. Ab
und an musst du noch ein berschssiges Leerzeichen entfernen, denn in
dieser Beziehung ist das Tool noch nicht perfekt.
Schrfere Geschtze fhrt Tidy auf, tidy up heit saubermachen. Whle
z. B. HTML|TIDY|TIDY CLEAN DOCUMENT WRAP oder TIDY CLEAN DOCUMENT NOWRAP
und staune! Tidy darfst du aber nur bei reinen HTML-Dateien anwenden.
Sobald PHP mit dazukommt, ist dieser Code-Verschnerer tabu!
Tidy schreibt automatisch eine zustzliche Meta-Zeile in das Dokument:
<meta name="generator" content="HTML Tidy for Windows...
Diese Zeile kannst du lschen.
Automatischen Zeilenumbruch einfgen
Du hast den Quellcode automatisch ausgerichtet, aber auf die Umbrche
verzichtet? Die Zeilen sind nun so lang, dass du stndig scrollen musst?
Schalte die automatischen Zeilenumbrche an. Whle ANSICHT|ZEILEN-
UMBRUCH. Der Umbruch erfolgt jetzt rein optisch fr die Anzeige im Editor,
wird jedoch nicht mitgespeichert.
Mehr berblick in der Codeansicht
Der Quellcode wird zu klein angezeigt, du kannst ihn nicht lesen? Oder du
mchtest alles auf einen Blick sehen? Na dann zoome doch einfach so
wie vom Internetbrowser oder aus der Textverarbeitung bekannt. Halte die
Taste [Strg] gedrckt und drehe am Mausrad.
Lesezeichen fr mehr bersicht
Genial finde ich auch die Mglichkeit, mit Lesezeichen zu arbeiten. So
kannst du dir besonders bei langen Codeabschnitten wichtige Zeilen besser
merken. Mit [Alt] + [] setzt du ein (gelbes) Lesezeichen. Mit [Alt] +
[] dagegen kannst du ein einmal gesetztes (gelbes) Lesezeichen wieder
lschen. Mit den Tastentricks [Alt] + [] bzw. [Alt] + [] springst du
zwischen mehreren Lesezeichen hin und her. Weitere (rote) Lesezeichen
gibt es auch. Die setzt du am besten ber das Kontextmen.
Nach dem Schlieen der Datei werden die Lesezeichen automatisch ge-
lscht.
Datei vom Windows-Explorer aus ffnen
Eines der genialsten Features von PSPad? Das ist fr mich eindeutig die
Mglichkeit, Dateien direkt vom Windows-Explorer aus laden zu knnen.
63
Tipps und Tricks zu PSPad

Und zwar ber das Kontextmen. Klicke also mit der rechten Maustaste auf
die zu ffnende Datei, beispielsweise die index.html. Whle den Befehl
PSPAD. Schn ffnet sich die entsprechende Datei. Du kannst dabei bri-
gens auch mehrere Dateien auswhlen, beispielsweise den Inhalt des ge-
samten Ordners. Alle Dateien werden auf einen Schlag in PSPad geladen!
Arbeit mit Verknpfungen
Besonders ntzlich ist auch die Arbeit mit Verknpfungen. So kannst du dir
zu den wichtigsten Ordnern Querverweise direkt in PSPad anlegen. Nach
Klick springt PSPad sofort zum entsprechenden Ordner im Mini-Explorer.
Verknpfungen heien in PSPad Links. Sie gehren ins Register mit dem
Herz. Und so erstellst du einen Link zum Ordner xampp/htdocs.
>
Achte darauf, dass das Toolfenster sichtbar ist (ANSICHT|TOOLFENSTER).
Wechsle ins Favoriten-Register, du erkennst es am Herz.
>
Klicke mit der rechten Maustaste auf das Ordner-Symbol und whle
den Befehl Neuen Link hinzufgen.
>
Das Dialogfenster Neuen Link hinzufgen erscheint. Schaue rechts
neben das Feld Pfad / URL und klicke auf die Schaltflche mit den drei
Punkten. Suche den gewnschten Ordner heraus.

>
Nach Klick auf OK ist der neue Link fertig eine praktische Verknp-
fung zum gewnschten Ordner!
Lege dir so viele Verknpfungen an, wie du brauchst.
Werkzeuge und Suchfunktion
Schau dir doch auch die pfiffigen Werkzeuge von PSPad an. Du findest sie
im gleichnamigen Men. Mir hat es neben der schon getesteten Farbaus-
wahl besonders der Code-Explorer angetan. Dieses Tool zeigt dir die Ele-
mente der aktiven Datei in einer baumartigen Struktur. Ausprobieren! Mein
zweitliebstes Tool heit Text-Diff: Aktuelle Datei vergleichen. So kannst du
zwei verschiedene Versionen eines Dokuments laden. PSPad hebt die Unter-
schiede farblich hervor.
Auch die ausgefeilte Suchfunktion bentige ich recht hufig, du findest sie
im gleichnamigen Men. Mein Favorit heit Suchen/Ersetzen in Dateien.
Damit kannst du beispielsweise ganze Ordner durchsuchen.
64
Deine coole Homepage mit HTML

Kapitel
1 Schlussbemerkung
Uff! Das war eine ganze Menge HTML auf einmal. Gute HTML-Kenntnisse
sind jedoch die Voraussetzung fr die PHP-Programmierung. Immerhin bist
du jetzt schon ein kleiner HTML-Experte.
Beim Thema HTML haben wir uns fr die klassische Version HTML 4 ent-
schieden, wobei ich schon in Richtung HTML 5 vordenke. Wir lassen die
strengere und weniger beliebte XHTML-Syntax auen vor.
Du mchtest tiefer in (X)HTML (und CSS) einsteigen und die modernsten
Versionen und neusten Techniken kennenlernen? Dann empfehle ich dir
die wunderbaren Bcher HTML fr Kids und CSS fr Kids von meinen
Autorenkollegen Robert Agular bzw. David Sigos. Vor allem das letztge-
nannte Buch bietet dir eine hervorragende Einfhrung in schickes Sei-
tenlayout.
Die Beispieldateien findest du brigens auch auf der CD zum Buch. Schaue
in den Unterordner beispiele/kapitel01.
Zusammenfassung
0 Du kannst mit dem PSPad blitzschnell das Grundgerst eines HTML-
Dokuments zaubern. Whle im Men DATEI den Befehl NEU und dop-
pelklicke auf den entsprechenden Eintrag.
0 Du fgst mit den entsprechenden Tags ganz lssig berschriften (z. B.
<h1></h1>) und Abstze ein. Setze den entsprechenden Text einfach
innerhalb der Tags ein.
0 Du weit, wie du mit dem Tag <img src="bildname.gif"> eine
Grafik in deine Homepage einfgst. Ziehe die Grafikdatei einfach aus
der Dateiliste des Toolfensters in dein HTML-Dokument. Passe die Attri-
bute und Werte des Tags dann wunschgem an.
0 Du kannst mit <ul></ul> Aufzhlungen und mit <ol></ol> Listen
mit HTML erstellen. Du notierst beliebig viele Listen-Eintrge zwischen
<li></li>.
0 Du erstellst Hyperlinks nach dem Muster <a href="Zieladresse">
Text fr Hyperlinks</a>.
0 Du schreibst HTML-Tabellen mit den entsprechenden Tags <table>
</table>, <tr></tr>, <th></th> und <td></td>.
65
Ein paar Fragen

0 Du erstellst externe CSS-Dateien und steuerst damit das Aussehen dei-
ner Homepage. Das sind Textdateien mit der Endung .css. Hier notierst
du mit Hilfe von Attributen, wie die einzelnen Tags formatiert werden
sollen. Das Attribut fr die Schriftart heit z. B. font-family.
0 Du arbeitest mit Farben, legst die Breite fest mit Hilfe eines
<div></div>-Containers und dem Attribut width.
0 Du weit, wie du mit den <form></form>-Tags und mit Kontrollkst-
chen ein Umfrageformular vorbereiten kannst und hast den SUBMIT-
Button ausprobiert.
Ein paar Fragen
Und jetzt bist du an der Reihe. Beantworte zuerst ein paar Fragen und lse
dann ein paar Aufgaben. Viel Spa und viel Erfolg!
1. Zwischen welchen Tags wird der Kopfbereich des Dokuments notiert?
2. Wie heit der Farbname fr kastanienbraun? Wie lautet der dazugeh-
rige hexadezimale Farbcode und wie die RGB-Syntax?
3. Wie sehen die Kommentarzeichen aus, die in CSS-Dateien verwendet
werden?
Die Antworten zu den Fragen stecken allesamt auf der CD zum Buch.
Schaue im Ordner fragen nach!
und ein paar Aufgaben
1. Schaue in die Seite index.html. Fge unter der Aufzhlung deiner
Hobbys eine Linie ein. Welches Tag verwendest du dafr?
2. Setze ganz oben auf die Seite index.html einen neuen Absatz, und
zwar unterhalb von <div style="width: 600px;">. Fge dort ei-
nen Verweis auf die zweite Seite umfrage.html ein. Schreibe als Link-
text: Zur Umfrage. Setze ganz oben auf der Umfrage-Seite (direkt unter
<body>) ebenfalls einen Absatz ein. Hier soll einen Link zurck verwei-
sen. Dieser soll heien: Zur Startseite.
66
Deine coole Homepage mit HTML

Kapitel
1

3. Prfe deine Seiten auf Korrekt-
heit. Surfe dazu zum Prfdienst
des W3C. (Dahinter stecken die
Leute, die HTML erfunden haben.)
Surfe zu http://validator.w3.org.
Gehe ins Register Validate by File
Upload. Klicke auf den Button
DURCHSUCHEN. Suche die zu pr-
fende Datei heraus und klicke auf
CHECK.
Die Prfung funktioniert nur richtig, wenn die Datei eine Dokumenttyp-
Deklaration besitzt. Du darfst diese erste Zeile mit <!DOCTYPE usw. also
nicht weglassen.
4. Du legst mit PSPad eine neue Seite an und whlst dafr DATEI|NEU bzw.
[Strg] + [N]? Dann gehst du ja immer ins Register Neue Datei aus Vor-
lage erstellen und whlst die angepasste Vorlage HTML 4.01 Transitio-
nal. Mache diese Vorlage noch perfekter. Ergnze den Link zur CSS-
Datei. Fge also folgende Zeile nachtrglich in die Vorlage ein: <link
rel="stylesheet" type="text/css" href="phpkid.css">. So
sparen wir uns in Zukunft auch das Schreiben dieser Passage.
Die Lsungen fr die Aufgaben findest du, falls mglich, stets auf der CD
zum Buch, und zwar unter dem Ordner loesungen. Schaue im Beispiel
unter loesungen/kapitel01 nach! Und wundere dich nicht ich habe
den HTML-Quellcode mit Tidy automatisch eingerckt.
Verlinke dein Pro-
jekt mit internen
Querverweisen.
67



2
Installiere deinen
eigenen Webserver!
In diesem Kapitel wird es richtig spannend! Du installierst deinen eigenen
Webserver und testest, ob alles funktioniert. Reiten wir gemeinsam mit
den Apachen durch die Prrie!
In diesem Kapitel lernst du also
$ wie du deinen eigenen Webserver mit PHP und MySQL installierst
$ wie du testest, ob alles funktioniert
An alle, die jetzt Angst bekommen: Du kannst deine Eltern, Tanten und
anderweitige potenzielle Geldgeber beruhigen. Der eigene Webserver ist
kein schwerer Kasten, den du nun zustzlich in deine Stube schieben
musst. Es kostet nichts extra, dein eigener Rechner gengt. Alles, was du
zustzlich brauchst, liefere ich dir auf CD mit!
Doch bevor es losgeht, lass mich etwas ausholen Wir mssen da so eini-
ge Dinge klren!
68
Installiere deinen eigenen Webserver!

Kapitel
2 Warum eigentlich ein Webserver?
Warum eigentlich ein Webserver? Und was ist das fr ein Ding? Fragen
ber Fragen, die wir vorher unbedingt beantworten mssen.
Der Webserver ist ein Computer
Zum einen ist der Webserver ein Computer. Es ist der Rechner im Internet,
auf dem deine Webseiten liegen. Dieser Webserver steht in einem groen
Rechenzentrum. Er wird von deinem Dienstleister fr dich bereitgehalten.
(Und um ganz offen zu sein: In den meisten Fllen legt dein Dienstleister
unzhlige weitere Homepages auf diesem Server ab, um Platz zu sparen.)

Kommen wir gleich auf die fr dich wohl wichtigste Kommunikation mit
dem Webserver zu sprechen, auf das Hochladen. Denn wenn du mit dem
Erstellen deiner Homepage fertig bist, ldst du die fertigen Seiten auf den
Webserver.
Zum Hochladen deiner Seiten brauchst du ein sogenanntes FTP-
Programm. Aber keine Sorge, das findest du ebenfalls in diesem Buch.
Auch wie man eine Seite auf den Webserver ldt, erklre ich dir eben-
falls, und zwar weiter hinten. Schaue einfach in den Anhang B!
Der Webserver sorgt nun dafr, dass deine Homepage fr alle sichtbar ist.
Besucher knnen zu deiner Adresse surfen und sehen deine Seiten. So weit,
so gut. Fazit: Ohne Webserver geht es nicht. Denn solange deine Seiten
noch auf deinem eigenen Rechner daheim liegen, kann sie niemand auer
dir sehen. (Oder auer deinen Freunden, denen du die Seite zeigst.)
Der exklusive Server fr
die eigene Homepage? Zu
teuer! Muss nicht sein!
69
Warum eigentlich ein Webserver?

und der Webserver ist ein Programm!
Zum anderen ist der Webserver aber auch eine Software, ein Programm.
Dieses Programm sorgt dafr, dass die Seite weltweit abgerufen werden
kann. Dieses Programm luft nun du ahnst es schon auf dem Webser-
ver.
Versuche dir einmal vorzustellen, wie das mit dem Surfen funktioniert:
Der Webserver-Rechner mit Webserver-Programm steht irgendwo im
Internet, in irgendeinem Rechenzentrum. Dort liegt deine Homepage,
wie eben geklrt. Doch was passiert, wenn ein Surfer deine Homepage
betrachten mchte? Dann tippt sie oder er erst einmal die entsprechende
Webadresse in den Browser ein, z. B. http://www.phpkid.de.
Nach Druck auf [Enter] erhlt der Webserver (also dieser Computer im
Internet) eine Anforderung zum Abruf der Seite. Fachleute sprechen von
einem sogenannten HTTP-Request. Der Webserver sucht deine Homepage
aus seinem Speicher heraus und schickt sie zum Betrachter zurck. Der
Betrachter an seinem heimischen PC sieht nun deine Homepage in sei-
nem Browser und kann sie lesen.
Dieser Betrachter wird brigens als Client bezeichnet. Der Client schaut
sich die Seiten auf dem Server an. Und schon haben wir die schnste
Client-Server-Beziehung.
Warum unbedingt ein eigener Webserver?
Das mit dem Webserver ist ganz schn und gut. Doch wozu brauchst du
deinen eigenen Webserver? Reicht denn nicht dieses Teilchen beim Dienst-
leister im Internet?
Leider nicht! Die Programmiersprache PHP ist eine Programmiersprache, die
auf dem Webserver luft. Ohne Webserver funktioniert sie nicht. In Zu-
sammenhang mit PHP spricht man deshalb auch von Webserver-
Programmierung. Daraus folgt: Wenn du PHP ausprobieren mchtest, bist
du auf einen Webserver angewiesen.
Eine derartige Programmiersprache wird Server-seitige Programmierspra-
che genannt. Wie gesagt: PHP luft nur auf dem Server, auf dem Web-
server. Der Browser allein kann mit PHP nichts anfangen. Wenn du ver-
suchst, eine PHP-Seite direkt im Browser aufzurufen, wird das nicht zum
gewnschten Ziel fhren!
70
Installiere deinen eigenen Webserver!

Kapitel
2
Da du PHP sicher auf deinem heimischen Rechner ausprobieren mchtest,
musst du wohl oder bel einen eigenen Webserver installieren. Darum also
brauchst du den eigenen Webserver.
Und warum geht das so problemlos bei
JavaScript?
Kennst du Raffael Voglers tolles, aber leider nicht mehr erhltliches Buch
JavaScript fr Kids? Oder den gleichnamigen Nachfolgetitel von Frank
Biet? (JavaScript ist eine weitere Programmiersprache, mit der man Web-
seiten aufpeppen kann.)
Oder hast du dich vielleicht schon anderweitig ber JavaScript informiert
und einiges ausprobiert? Dann wirst du an dieser Stelle mglicherweise die
Stirn runzeln. Moment mal, wirst du protestierend einwerfen. Der Autor
spinnt. Von wegen Webserver! Bei JavaScript ist dieser ganze Webserver-
Zirkus doch auch nicht ntig. Du ffnest deine Seite direkt im Browser es
funktioniert. JavaScript wird ausgefhrt. Du brauchst keinen Webserver.
Warum?
Nun, JavaScript luft direkt im Browser!
Fachleute sagen: JavaScript wird vom Client (Client = Browser) interpre-
tiert. Im Klartext: JavaScript wird vom Browser des Betrachters ausge-
fhrt. Der beste Beweis fr diese Aussage: Schalte doch einmal Java-
Script im Browser ab. Viele Seiten werden jetzt nicht mehr richtig funk-
tionieren. Ganz im Gegensatz zu PHP ist JavaScript also eine Client-
seitige Programmiersprache.
Fassen wir zusammen: JavaScript wird vom Browser ausgefhrt. (Und wenn
du im Browser JavaScript abschaltest, geht gar nichts mehr).
PHP dagegen wird nur vom Server ausgefhrt. Der Browser bekommt stets
eine HTML-Seite zugeschickt. Das hat einen groen Vorteil. Fr PHP ist es
egal, welchen Browser der Betrachter verwendet. PHP funktioniert immer!
Das ist natrlich toll.
Doch wo Licht ist, gibt es auch viel Schatten. Und da kommen wir schon
zum ersten Haken!
71
Wie teuer ist die Homepage mit PHP/MySQL?

Wie teuer ist die Homepage mit
PHP/MySQL?
Wir sprachen eben darber, dass an der Sache mit PHP ein Haken ist: PHP
funktioniert nur dann, wenn dir dein Dienstleister einen Webserver mit
PHP-Untersttzung bietet. Und sptestens an dieser Stelle fngt es an,
richtig rgerlich zu werden.
Du fhrst deine Homepage bisher bei T-Online, AOL oder Freenet? Fehlan-
zeige! Diese Dienstleister sind ungeeignet. Aber auch preiswerte Web-
Visitenkarten bzw. Starterangebote z. B. von 1 und 1, Strato, Domain-
factory usw. bieten oft kein PHP an. Auch hier kommst du also nicht weiter.
Fazit: Du bentigst einen Dienstleister mit PHP- und MySQL-Unterstt-
zung. Schauen wir uns deshalb einige dieser Dienstleister einmal an.
Wir bentigen PHP 5-Untersttzung, um ganz genau zu sein. MySQL
sollte mindestens in Version 4.1, besser in Version 5 oder hher vorliegen.
Kostenlos, aber nicht umsonst: MultiMania
Gerade kein Geld brig? Das macht nichts! Der Anbieter MultiMania bietet
unter www.multimania.de eine kostenlose Homepage an. Das alleine ist
nichts Besonderes, kostenlose Homepages kannst du an vielen Stellen im
Netz bekommen. Interessant ist, dass MultiMania PHP und ttert
auch MySQL-Untersttzung bietet. Sogar das Administrations-Tool
phpMyAdmin zum Einrichten von Datenbanken ist schon vorinstalliert.
Der Haken: Du musst dich mit Zwangswerbung auf deiner Seite abfin-
den. Auch an deine E-Mail-Adresse wird Werbung geschickt. Abgesehen
davon sind die dort eingerichteten Versionen von MySQL und phpMyAd-
min nicht aktuell. Auch die neuen MySQLi-Funktionen von PHP funktio-
nieren zum Zeitpunkt des Schreibens noch nicht. Du kannst dann beim
Datenbankteil (vorerst) leider nicht mitmachen. Doch zumindest fr den
Einstieg in PHP ist MultiMania gut geeignet!
Immerhin kannst du zumindest PHP nach Herzenslust ausprobieren, ohne
einen Cent zu bezahlen. MultiMania ist ein Angebot der Conversis Hosting
GmbH. Frher gehrte der Dienst zu Lycos und hie Tripod.
72
Installiere deinen eigenen Webserver!

Kapitel
2
Bei MultiMania registrieren
Du hast dich fr dieses Angebot entschieden? Trage deinen Usernamen und
das Passwort ein. Das Passwort musst du aus Sicherheitsgrnden zweimal
angeben. Klicke auf LOS GEHTS!:

Dann fllst du das entsprechende Formular aus. Der Mitgliedsname ist be-
sonders wichtig. Dieser Name wird spter zum letzten Teil der Adresse dei-
ner Homepage. Du musst aber auch dein Geburtsdatum, dein Geschlecht
und eine schon existierende E-Mail-Adresse angeben.
Du hast das Anmelde-Formular ausgefllt und abgeschickt? Dann be-
kommst du nun eine E-Mail. Erst mit dieser E-Mail wird die Anmeldung
perfekt: Aktiviere den Hyperlink aus der E-Mail. Du landest auf einer Be-
sttigungs-Seite. Gib Mitgliedsnamen und Passwort ein. Geschafft! Du bist
Mitglied bei MultiMania!
Login bei MultiMania
Zum Einloggen gehst du zu http://www.multimania.de. Nun gibst du Be-
nutzernamen und Passwort ein und klickst auf ANMELDEN. Schon bist du im
Verwaltungsbereich.
Wie bekommst du deine Homepage auf den MultiMania-Server? Mit FTP!
Wie das funktioniert und welche Daten du dafr bentigst, zeige ich dir
im Anhang B ganz genau!
Bei der Anmeldung legst
du Benutzernamen und
Passwort fest.
73
Wie teuer ist die Homepage mit PHP/MySQL?

Hat alles geklappt? Dann findest du deine Seite im Endeffekt mglicher-
weise unter dem Namen http://mitglied.lycos.de/mitgliedsname mit Mit-
gliedsname ist hier natrlich der von dir selbst gewhlte Benutzername
gemeint. Auf jeden Fall zeigt dir MultiMania die Adresse der Seite gleich
nach dem Einloggen an.

Fr ltere Kids: Eigene WWW-Domain
Nase voll von der MultiMania-Reklame? Du bist schon ein etwas greres
Kid? Oder die Augenaufschlag-Papi-ist-der-Beste-Taktik war erfolg-
reich? Dann lohnt es sich vielleicht, ber eine eigene Domne nachzuden-
ken! Das ist eine Adresse, die z. B. nach dem Muster www.deinName.de
aufgebaut wird. Die Vorteile sind gro: Deine Webseite ist unter einer kur-
zen, von dir selbst whlbaren Adresse zu finden.
Gerade hier werben unzhlige Dienstleister (sogenannte Webhoster) um
deine Gunst. Viele dieser Firmen bieten natrlich auch Hosting-Pakete
mit PHP-Untersttzung, in aller Regel auch gleich mit MySQL. Leider kostet
die PHP/MySQL-Option bei einigen Anbietern ordentlich viel Knete.
Nicht so bei der Firma Neue Medien Mnnich. Hier gibt es eine Homepage
mit eigener Domne und PHP/MySQL-Untersttzung fr recht Taschen-
geld-freundliche 4,95 Euro pro Monat. Dafr, dass dieser Dienstleister zu
den besten gehrt, ist das eine gute Leistung! Informiere dich auf der Seite
www.all-inkl.com genauer ber Preise und Leistungen! Ebenfalls berzeugt
bin ich von der Schwarzknster GbR unter www.schwarzkuenstler.info. Hier
gibt es PHP-fhige Webpakete schon ab mageren 1,45 Euro pro Monat.
Noch einen Tick gnstiger ist die Hosting-Firma MW Internet mit dem Pa-
ket Zero Light. Hier gibt es PHP- und MySQL-Untersttzung schon ab 1,40
Euro im Monat. Und das alles ohne Werbung, dafr aber mit 250 Megabyte
Speicherplatz: www.mw-internet.de. (Tipp fr alle mitlesenden Eltern: Die-
ser Anbieter ist nicht nur sehr gnstig, sondern vergibt auch Geschenkgut-
scheine! Und zwar in der Rubrik Sonstiges.)
Und es geht sogar noch gnstiger. Bei http://webnet-service.de bekommst
du das gnstigste PHP- und MySQL-fhige Paket ab 1,29 pro Monat.
Kostenlos, aber nicht
umsonst: Massive Wer-
bung bei jedem Laden
der Seite.
74
Installiere deinen eigenen Webserver!

Kapitel
2 Neue Medien Mnnich und Schwarzknstler GbR haben einen groen
Vorteil: Du kannst deren Angebot vorab kostenlos auf Herz und Nieren
prfen! Bei Neue Medien Mnnich dauert dieser Test 7 Tage. Suche ein-
fach nach der Option Jetzt gratis testen. Bei Schwarzknstler GbR kannst
du das Angebot bis zu 10 Tage testen. Suche die Rubrik Testen Sie uns!
Mit diesem kostenlosen Testaccount erfhrst du zum einen, wie so ein
Anbieter tickt. Zum anderen bekommst du eine zeitlich befristete Test-
homepage mit PHP und MySQL und damit kannst du schon alles machen.
Arbeite das Buch durch und teste die Skripte auf deren Server!
Im nchsten Bild siehst du die Begrungsseite von Neue Medien Mnnich.
Die Schaltflche JETZT GRATIS TESTEN fhrt zum kostenlosen Testaccount:

Ich habe mich bei den meisten der bisher genannten Dienstleister ange-
meldet und bin zufrieden. Hallo Eltern, Groeltern, Tanten, Onkels, Ver-
wandte: Vielleicht wre das ein tolles Weihnachts-, Oster-, Geburtstags-,
Tauf-, Konfirmations- bzw. Jugendweihegeschenk? Die eigene Domain fr
die Tochter, fr den Sohn?
Du suchst den gnstigsten und besten Anbieter? Du mchtest dich vor-
her ber Preise und Leistungen informieren? Surfe zur Seite
www.webhostlist.de und informiere dich. Hier ist besonders die bersicht
zu den Top Ten interessant. Du findest hier Geschwindigkeitstests und
Erfahrungsberichte von anderen Nutzern. Auerdem fhrt der Autor auf
www.phpkid.de/?billig_hosten eine Liste besonders preiswerter Anbieter,
die er mithilfe seiner Leser zusammengetragen hat.
All-inkl.com ist nicht
nur einer der gnstigs-
ten, sondern auch
besten Anbieter.
75
How! Im Reich des Apachen

Lasse dir beim Anmelden von einem Erwachsenen helfen. Denn gerade
bei der Registrierung von Domnen-Namen mssen rechtliche Aspekte
beachtet werden. Du darfst z. B. keinen geschtzten Markennamen fr
deine Homepage verwenden. Nicht nur bei gewerblicher Nutzung (frh
bt sich, hehe!) bentigst du auerdem ein ordentliches Impressum. Das
ist ein Bereich, der deine Adresse, Telefonnummer, Steuernummer usw.
enthlt. Verste knnen dazu fhren, dass du teure Strafgebhren
entrichten musst. Viel mehr dazu, was erlaubt ist und was nicht, verrate
ich dir auch in meinem Buch Bloggen mit WordPress fr Kids.
How! Im Reich des Apachen
Nun haben wir uns auf den vorangegangenen Seiten ausfhrlich ber Web-
server unterhalten. Es gibt den Webserver als Rechner und natrlich auch
das Webserver-Programm. Das Webserver-Programm? Gibt es da nur ein
Programm? Und was kostet diese Software? Interessante Fragen!
Die gute Nachricht: Webserver-Programme gibt es viele. Zum einen teure
wie den sogenannten Internet Information Server von Microsoft. Zum an-
deren auch kostenlose. Und du wirst es nicht glauben am beliebtesten
ist der frei verfgbare Webserver namens Apache. How!
Und weil der so gut ist und weil der weiter nichts kostet, wird er auf den
meisten Webservern im Internet eingesetzt.
Es handelt sich dabei um sogenannte Open Source Software. Die Nutzung
ist kostenlos. Das Projekt wird von vielen Leuten weiterentwickelt. Es gibt
Versionen des Apachen fr Unix/Linux (das Betriebssystem im Web) und
natrlich auch fr Windows. Im Klartext: Du kannst dir dieses tolle Pro-
gramm gemtlich auf deinem heimischen Windows-Rechner installieren.
Ganz einfach: Webserver selbst
installiert!
Genau das machen wir. Wir installieren uns den Apache-Webserver auf
unserem heimischen Rechner. Damit schaffen wir uns eine tolle Testumge-
bung. Ideal auch als Trostpflaster, wenn du noch keine Mglichkeit hast,
deine Seiten im Internet zu verffentlichen.
76
Installiere deinen eigenen Webserver!

Kapitel
2 Nach der herkmmlichen Methode musst du zuerst den Apache-
Webserver einzeln installieren. Dann installierst du PHP, zum Schluss
noch MySQL und phpMyAdmin. Nach jedem Schritt nimmst du unzhlige
schwierige Konfigurations-Einstellungen in irgendwelchen Textdateien
vor. Wenn man sich da nur ein einziges Mal verschreibt, geht gar nichts
mehr! Arghh. Da bekommt man schon am Anfang die ganz groe Krise!
Unser Buch bleibt krisenfrei! Wir sind pfiffig und nutzen eine spezielle In-
stallations-Software. Ich meine das Installationspaket XAMPP von den
Apachefriends. Hinter den Apachefriends stecken Kai Oswald Seidler, Cars-
ten Wiedmann und Kay Vogelgesang die Entwickler dieses tollen Installa-
tionspakets.
Frisch ans Werk! Installiere deinen eigenen Webserver auf der lokalen Fest-
platte. Nebenbei werden auerdem gleich PHP, MySQL und das geniale Tool
phpMyAdmin eingerichtet. Das Beste: Alle diese Kostbarkeiten liegen fr
dich auf der CD bereit, und zwar unter programme/xampp. Unser Dank
geht an Kai, Carsten und Kay, die sich freuen, dass wir ihr XAMPP mit auf
unsere CD legen!
Die XAMPP-Homepage brigens mit einem Hilfe-Forum auch bei Installa-
tionsproblemen findest du unter http://www.apachefriends.org.
Kleiner Tipp fr Mac-Nutzer: Auch fr dich gibt es eine praktische Alter-
native: MAMP. Du kannst dir das Paket unter www.mamp.info herunter-
laden, fr die Buch-CD war es etwas zu gro. (Sonst htten die Videos
nicht mehr gepasst.) Die Installation von MAMP geht zwar anders vor
sich als die von XAMPP. (Sie wird auf www.mamp.info bei Dokumentati-
on erklrt.) Vom Prinzip her arbeitet MAMP jedoch genau wie XAMPP.
So installierst du XAMPP
Und so einfach gelingt die Installation unter Windows. Es funktioniert bei
allen Windows-Versionen ab Windows 2000 bis Windows 7. Und zwar so-
wohl auf der lokalen Festplatte als auch transportabel auf USB-Stick.
(Du kannst dir die Schrittfolge auch zeigen lassen. Das entsprechende Vi-
deo fr dieses Kapitel 2 findest du auf der CD im Ordner videos.)
>
Zuerst achte darauf, dass kein Programm auf deinem Rechner aktiv
ist. Das knnte die Installation stren. Gehe nun in den entsprechen-
den Ordner fr XAMPP auf der CD, und zwar in programme/xampp.
77
Ganz einfach: Webserver selbst installiert!


Der Doppelklick startet die Installation.
>
Doppelklicke auf die Datei xampp-win32-1.7.3.exe. (Falls du die
neuste Version von XAMPP aus dem Internet geladen hast, lautet der
Dateiname vielleicht schon xampp-win32-1.7.4.exe.) Es handelt
sich um ein selbstauspackendes RAR-Archiv. Die Installation wird au-
tomatisch gestartet. Unter Windows Vista und 7 musst du vorher in
aller Regel noch eine Sicherheitswarnung besttigen.
>
Das Fenster XAMPP for Windows erscheint. Schaue zum Feld Destina-
tion Folder. Steht bei dir auch C:\ in diesem Feld? Super! Hier sollte
auf jeden Fall der Laufwerksbuchstabe hin wobei das Laufwerk auch
ein USB-Stick oder eine externe Festplatte sein darf!

Der Installationspfad (Destination Folder) sollte im Beispiel C:\ lauten.
>
Klicke auf INSTALL und gedulde dich die Dateien werden entpackt!
Das kann eine ganze Weile dauern. Im Ergebnis entsteht unter C: bzw.
dem von dir gewhlten Laufwerk ein Extraordner namens xampp. (Da-
von kannst du dich gleich nach erfolgreicher Installation berzeugen.)
78
Installiere deinen eigenen Webserver!

Kapitel
2
>
Nun erscheinen nacheinander merkwrdige schwarze Setup-Bild-
schirme! Dort musst du jeweils den aktiven Buchstaben (y wie yes
bzw. n wie no) mit [Enter] besttigen bzw. ggf. wunschgem anpas-
sen, damit der Einrichtungsprozess abgeschlossen werden kann.

Shortcuts (Verknpfungen) auf dem Desktop und im Startmen sind eine feine Sache.
Das y fr yes ist voreingestellt. Besttige mit [Enter]!
>
Drcke jetzt immer wieder auf [Enter], um die Fragen zu besttigen.
An einer Stelle wirst du gefragt: Should I make a portable XAMPP with-
out drive letters? Wenn du XAMPP nur auf der lokalen Festplatte instal-
lierst, knntest du das n fr no eigentlich belassen. Soll XAMPP jedoch
als portable (tragbare) Version auf einem USB-Stick oder einer tragbaren
Festplatte eingerichtet werden, darfst du keine drive letters (Laufwerks-
buchstaben) zulassen. Aber auch auf der lokalen Festplatte entscheide
ich mich dagegen. So kann ich XAMPP immer schnell mal mitnehmen.
Einfach den XAMPP-Ordner nachtrglich auf den USB-Stick kopieren
und direkt am Computer von Freunden nutzen! Ist doch super, oder? Fol-
ge meiner Empfehlung und tippe an dieser Stelle vorher auf alle Flle ein
y fr yes. Drcke erst dann auf [Enter].
>
Es geht weiter mit dem [Enter], [Enter] um die nchsten beiden
Fenster zu besttigen. Am Schluss landest du bei dieser Auswahl:

79
Ganz einfach: Webserver selbst installiert!

>
Tippe ruhig erst einmal ein x fr exit. Durch Druck auf [Enter] ver-
lsst du das Setup-Skript und kannst dich in Ruhe umsehen.
Apropos installiert: XAMPP hinterlsst dabei keinerlei Spuren. Keine Eintr-
ge in irgendwelchen Registrierdatenbanken, kein nichts! Wenn du XAMPP
lschen mchtest, lschst du einfach den kompletten Ordner xampp! (Oder
du rufst die Datei uninstall_xampp.bat aus dem xampp-Ordner auf.)
So startest du XAMPP
Du mchtest XAMPP starten? Und damit den Apache Webserver, PHP,
MySQL und phpMyAdmin? Kein Problem! Wozu gibt es denn das neue Ver-
knpfungssymbol auf dem Desktop? Doppelklicke einfach auf das Symbol
XAMPP Control Panel bzw. rufe diesen Eintrag ber das Startmen auf.
Das geniale XAMPP Control Panel startet. Damit zndest du nun den Apa-
che-Webserver und den MySQL-Datenbankserver. Dafr bentigst du nur
die beiden oberen START-Schaltflchen. Klicke zuerst auf den obersten
START-Knopf, den rechts neben Apache. Warte ein paar Sekunden. Whle
danach den START-Knopf darunter, den rechts neben MySQL.

Starte den Apache-Webserver (oberstes Modul) und MySQL (zweites Modul von oben) jeweils
durch Klick auf die daneben angeordnete START-Schaltflche. Der Text Running erscheint und
die START-Schaltflche verwandelt sich in eine STOP-Schaltflche.
Nach Klick auf die jeweilige START-Schaltflche meldet sich gegebenen-
falls ein warnendes Fenster deiner Firewall. Das geht in Ordnung, Win-
dows passt schlielich auf. Erlaube je nach Firewall den Zugriff bzw. Ein-
satz des Webservers und von MySQL in deinem lokalen Netz.
80
Installiere deinen eigenen Webserver!

Kapitel
2

Nanu, es gibt Probleme mit XAMPP? Achte darauf, dass kein konkurrie-
rendes Webserver-Programm aktiv ist. Unter Windows 2000 bzw. XP Pro-
fessional knnte das der Internet Information Server sein. Den darfst du
nicht aktivieren, da dieser den Apache-Webserver behindern wrde.
Auch das Telefonierprogramm Skype (www.skype.com) musst du ggf.
herunterfahren, da es sich oft nicht mit XAMPP bzw. dem lokalen Apa-
che-Webserver vertrgt. Es kann auch sein, dass eine lokale Firewall oder
ein im Hintergrund arbeitender Virenscanner dafr sorgt, dass XAMPP
nicht richtig luft. Auch die aktuellen Browser prsentieren ggf. alle
mglichen Sicherheitsabfragen und Warnungen, ehe sie dich an XAMPP
heranlassen. Im Zweifelsfalle gilt: Versuch macht klug! Trenne dich wh-
rend der Arbeit mit XAMPP unbedingt vom Internet aus Sicherheits-
grnden! Schalte erst dann die Firewall aus bzw. berwinde die Sicher-
heitsmechanismen deines Browsers.
So beendest du XAMPP
Du mchtest deine PHP-MySQL-XAMPP-Sitzung beenden? Dann musst du
beide Module durch Klick auf STOP wieder herunterfahren. Schalte erst
MySQL ab und warte einige Sekunden. Stoppe danach den Apache-Webser-
ver. Der grne Text Running muss an beiden Stellen verschwunden sein.
Auch wenn du das Fenster des XAMPP Control Panel schliet das Steu-
erpult bleibt aktiv! Es nistet sich ganz rechts unten im Systembereich
ein. Du findest es neben der Uhrzeit. Ein Doppelklick auf dieses Symbol
zaubert das Steuerpult hervor.

Du mchtest nun auch das XAMPP-Steuerpult beenden? Klicke im XAMPP
Control Panel auf die Schaltflche EXIT. Du findest sie als unterste Schalt-
flche in der rechten Reihe. Erst jetzt ist XAMPP wirklich inaktiv.
81
Nur noch etwas Handarbeit und fertig!

Wo liegen die Dateien von XAMPP?
XAMPP hat nun alles installiert, Webserver, PHP, MySQL, phpMyAdmin usw.
Fantastisch. Doch wo liegen die ganzen Module? XAMPP legt den Apa-
che-Webserver, PHP, MySQL, phpMyAdmin usw. in Unterordnern unter
C:\xampp ab.
0 Den Apache-Webserver findest du unter C:\xampp\apache
0 Die PHP-Dateien liegen unter C:\xampp\php
0 MySQL findest du z. B. unter C:\xampp\mysql
Auch andere Module wie Perl, Mercury Mail Server und der FileZilla-FTP-
Server werden installiert. Diese Komponenten bentigen wir jedoch nicht,
du kannst sie ignorieren. Was fr uns wichtig ist: Fr deine eigenen Daten
hat XAMPP den Ordner htdocs eingerichtet. Du findest dieses Verzeichnis
unter C:\xampp\htdocs.
Merke dir diesen Ordner gut! Noch einmal langsam und zum Mitschrei-
ben: Alles, was du jetzt PHP-mig anstellen wirst, legst du ab unter
C:\xampp\htdocs!
Nur noch etwas Handarbeit
und fertig!
Hat alles perfekt funktioniert? Probiere es aus! Teste, ob dein lokaler Web-
server funktioniert.
Die Startseite fr deinen lokalen Webserver findest du stets unter der
Adresse http://127.0.0.1. Tippe diese Adresse einfach in deinen
Browser ein. Falls dir diese Nummer zu kryptisch ist, kannst du dir auch
die Adresse http://localhost merken. Last but not least gibt es noch
eine dritte Methode. Kennst du den Namen deines PCs? Meiner heit
z. B. Monarch. Dann tippe ich http://monarch und drcke [Enter].
Auch das geht also, es fhren tatschlich drei Wege zum gleichen Ziel!
82
Installiere deinen eigenen Webserver!

Kapitel
2
Wir einigen uns am besten auf http://localhost! Tippe diese Adresse
ein und drcke [Enter]. Je nach Version von XAMPP siehst du nach Klick
auf den Link Deutsch diese oder eine hnliche Seite:

XAMPP begrt dich mit einer Begrungs-Seite.
Dahinter verbirgt sich aber nichts weiter als eine Status- und Demoseite,
die die Macher von XAMPP fr dich vorinstalliert haben.
Du wunderst dich, warum in diesem Ordner schon so viel drin steckt? Das
sind vor allem Demo- und Beispielprogramme. Du kannst diese Dateien und
Ordner bedenkenlos lschen. Du traust dich nicht, das alles zu lschen?
Dann habe ich einen anderen Tipp: Benenne den Ordner htdocs um in
htdocs_alt. Erstelle nun unterhalb von xampp einen neuen, leeren Ordner
namens htdocs. Auch das funktioniert! (Wenn du dich nicht beim Ordner-
namen verschrieben hast!)
Nach dem Druck auf [Enter] will sich dein PC stets ins Internet ein-
whlen? Versuche eine Option wie Offline bleiben. Whle z. B. den Be-
fehl DATEI|OFFLINEBETRIEB. Probiere es dann erneut.
83
Testen: phpinfo() auf localhost

Testen: phpinfo() auf localhost
Wunderbar, jetzt hast du deinen eigenen Webserver. Teste doch einmal, ob
alles funktioniert. Zuerst prfen wir, ob unsere eigenen HTML-Seiten ange-
zeigt werden.
Zuerst eine HTML-Seite
Erinnerst du dich an deinen Ordner html, den du unter C:\phpkid einge-
richtet hattest? Ich meine unser kleines Projekt aus Kapitel 1. Das kommt
uns wie gerufen, denn hier gibt es eine Datei index.html. Das ganze Pro-
jekt binden wir einfach zur Probe in unseren Webserver ein!
>
Kopiere diesen Ordner html komplett nach C:\xampp\htdocs. Der
neue Pfad muss also lauten C:\xampp\htdocs\html!
>
Rufe diese Seite nun auf. Dazu tippst du http://localhost/html.
Wenn alles klappt, wird die im ersten Kapitel erstellte Seite
index.html aufgerufen!

Aber auch hier sind die Vorteile eines Webservers noch nicht ersichtlich. Es
macht keinen groen Unterschied, ob du die Datei direkt von PSPad bzw.
dem Windows Explorer aus startest, oder ber den Webserver abrufst.
Die Magie der index.html
Du knntest diese Datei index.html auch direkt durch Doppelklick star-
ten. Da es eine reine HTML-Seite ist, macht das keinen Unterschied zu-
mindest vom Erscheinungsbild her. Bemerkst du etwas? Wenn du sie ber
http://localhost/html ffnest, dauert das ein wenig lnger.
Es klappt: Aufgerufen wird
die index.html aus dem
Ordner html.
84
Installiere deinen eigenen Webserver!

Kapitel
2
Schlielich muss der Webserver die Anfrage (HTTP-Request) erst bearbeiten
und die passende Seite zurck zum Browser schicken.
Apropos http://localhost/html! Gezeigt wird die index.html, ob-
wohl du diesen Namen berhaupt nicht getippt hattest? Der Englnder
wrde jetzt sagen How come, was ist los? Nun, eine index.html wird
immer dann angezeigt, wenn du den entsprechenden Ordnernamen ein-
tippst.
Wenn keine index.html vorhanden ist, reicht oft auch eine index.htm
oder sogar eine index.php als Startdatei. Das ist ziemlich praktisch. So
musst du nicht erst umstndlich http://localhost/html/index.html
tippen, da http://localhost/html gengt!
und nun ein PHP-Test
Und nun folgt ein kleiner PHP-Test! Dafr schreibst du deine erste PHP-
Datei. Diese nennen wir info.php und legen sie in den Ordner
C:\xampp\htdocs. Richtig, diesmal direkt in den Stammordner deines
lokalen Webs. Wie geht das?
>
Starte PSPad. Whle nun im Men DATEI den Befehl NEU.
>
Bleibe im voreingestellten Register Leere Datei erstellen und doppel-
klicke auf PHP.
>
Eine Datei wird erzeugt, wirklich leer ist sie allerdings nicht. Du fin-
dest hier schon die PHP-Tags vor. Klicke in die leere Zeile zwischen
<?php

?>

>
Notiere folgenden Befehl:
phpinfo();

>
Vergiss nicht, die Datei zu speichern. Zur Erinnerung: Wir wollten sie
info.php nennen (Endung .php!).



85
Testen: phpinfo() auf localhost

Achte unbedingt darauf, die Datei in XAMPP zu speichern. Und zwar im
Ordner xampp, Unterordner htdocs. Denn nur wenn sie in htdocs (oder
einem Unterordner von htdocs) liegt, wird PHP ausgefhrt.

>
Rufe die Seite nun folgendermaen auf. Tippe in den Browser:
http://localhost/info.php
und besttige mit [Enter]. Wenn alles geklappt hat, siehst du solch
ein oder ein hnliches Bild:


Das ist zum einen der Beweis, dass PHP funktioniert. Zum anderen gibt dir
die Funktion umfangreiche Ausknfte. Welche PHP-Version ist auf deinem
System installiert? Wir arbeiten mit PHP 5.3.1. Welches Betriebssystem
wird verwendet? Welche Einstellungen wurden vorgenommen? Fr den
Kenner ist diese Anzeige eine wahre Fundgrube. Fr uns Grund, einen Indi-
aner-Freudentanz aufzufhren!
Es funktioniert: PHP
ist auf deinem System
korrekt installiert.
86
Installiere deinen eigenen Webserver!

Kapitel
2 Du versuchst, die info.php direkt aufzurufen? Das wird misslingen.
Entweder du siehst den Quelltext. Oder Windows beschwert sich, weil es
mit diesem Dateityp nichts anfangen kann. Sptestens an diesem Bei-
spiel merkst du, wie wichtig der Webserver ist. Erst der Webserver sorgt
dafr, dass die PHP-Anweisung hier die Funktion phpinfo() ausge-
fhrt wird. Wichtig zu wissen: Der PHP-Befehl wird ausgefhrt, aber
nicht angezeigt. Der Browser erhlt reinen HTML-Code zugeschickt.
Wenn dus nicht glaubst, mache den Test: Tippe noch einmal die Adresse
http://localhost/info.php. Whle nun im Browser je nach Version
den Befehl SEITE|QUELLCODE ANZEIGEN, ANSICHT|QUELLTEXT bzw. SEITENQUELL-
TEXT ANZEIGEN. Du wirst keine einzige Zeile PHP finden! Was du siehst, ist
der HTML-Quellcode, der durch die phpinfo() entstanden ist!
Noch ein Test: Funktioniert phpMyAdmin?
Hattest du auf der ursprnglichen XAMPP-Begrungsseite den Punkt
TOOLS entdeckt? Dort steckt auch phpMyAdmin, unser Datenbankverwal-
tungsprogramm. Wir brauchen es zwar erst spter trotzdem solltest du
jetzt schon testen, ob der Zugriff funktioniert! Ich empfehle dir, dieses Tool
nicht ber den Link, sondern stets direkt aufzurufen. Dazu tippst du in die
Adresse-Zeile des Browsers: http://localhost/phpmyadmin
Normalerweise startet phpMyAdmin ohne Kommentar. Bei dir erscheint
eine Dialogbox zur Eingabe von Benutzernamen und Passwort? Dann tippst
du als Benutzernamen einfach root, das Passwort-Feld jedoch lsst du frei.
Das sind brigens die gleichen Daten, die du spter auch fr MySQL ver-
wenden wirst: root und nichts.
Schlussbemerkung
Viel Theorie, ich wei. Aber das war wichtig. Auerdem weit du jetzt, wo
du Platz fr deine PHP-Homepage bekommst. Und du bist stolzer Besitzer
eines eigenen lokalen Webservers. Und das ist doch schon allerhand!
XAMPP gibt es brigens auch fr Mac und fr Linux. Dort ist die Vorge-
hensweise leider etwas anders. Lies dir die entsprechenden Anleitungen
auf www.apachefriends.de durch. Du bist Macianer und kommst mit
XAMPP nicht zurecht? Dann solltest du das schon erwhnte MAMP aus-
probieren. Dieses Tool bekommst du unter www.mamp.info.
87
Zusammenfassung

Zusammenfassung
0 Du weit jetzt, wozu ein Webserver dient. Hier liegen die Seiten. Der
Betrachter kann sie ber Eintippen der entsprechenden Webadresse an-
fordern. Diese Anforderung heit HTTP-Request.
0 Du kennst einige Dienstleister mit PHP/MySQL-Untersttzung. Du
kennst z. B. MultiMania (vormals Tripod bei Lycos), einen werbefinan-
zierten Anbieter einer kostenlosen PHP/MySQL-Homepage.
0 Du weit, wie das beste Webserver-Programm heit Apache Webser-
ver. Es ist ein frei verfgbares Programm.
0 Wir haben den Apachen selber auf unserem Rechner eingerichtet. Dabei
half uns ein Installations-Tool namens XAMPP. Angenehmer Nebenef-
fekt: Jetzt laufen auch PHP und MySQL ganz automatisch auf deinem
heimischen Rechner.
0 Du weit, wie du dein eigenes Web aufrufst. Tippe http://localhost
in die Adresse-Zeile des Browser. Drcke [Enter].
0 Du hast am Beispiel der Funktion phpinfo() herausgefunden, dass
eine PHP-Datei nur beim Aufruf ber den Webserver richtig angezeigt
wird. Grund: PHP wird vom Webserver ausgefhrt. Der Browser be-
kommt jedoch reinen HTML-Code zugeschickt.
Ein paar Fragen
1. Kannst du bei Anbietern wie T-Online oder AOL deine Homepage mit
PHP/MySQL installieren?
2. Wie heit das Programm, welches dir den Apache-Webserver, PHP,
MySQL und noch viel mehr auf deinem heimischen Computer einrich-
tet?
3. Unter welchem Pfad legst du deine PHP-Dateien ab, wenn du den Apa-
che-Webserver mit XAMPP installierst hast?
4. Welche Endung hat eine PHP-Datei?
5. Wozu brauchst du einen eigenen Webserver?
88
Installiere deinen eigenen Webserver!

Kapitel
2 und eine Aufgabe
Diese Aufgabe wendet sich an Windows-Nutzer, die
mit PSPad arbeiten. Und damit es nicht so schwer
wird, beginne ich mit einem Trick.
Du mchtest noch schneller ein HTML-Grundgerst in PSPad einfgen?
Klicke auf den Pfeil rechts neben der NEU-Schaltflche (Sie heit eigent-
lich NEUE DATEI ERSTELLEN) und whle HTML. Oder whle DATEI|NEU und
bleibe im Register Leere Datei erstellen. Doppelklicke auf HTML. Auch
jetzt wird ein HTML-Dokument im Standard 4.01 Transitional eingefgt
sogar mit verkrzter DTD. (Allerdings ohne lang="de" und utf-8.)
Und nun kommt endlich deine Aufgabe: Finde heraus, welche Vorlage sich
dahinter verbirgt. Passe diese Vorlage an deine Wnsche an. Sorge also
dafr, dass unser perfektes HTML-Grundgerst von Seite 32 eingebunden
wird. Meinetwegen mit verkrzter DTD und gerne auch ohne Einrckung
der Zeilen. (Damit die Einrckung von PHP besser zur Geltung kommt.) Aber
bitte dafr wieder mit CSS-Link von Seite 50.

89



3
Hallo echo Hallo Welt
Die mhevollen Vorarbeiten sind geschafft! Der Webserver luft. Hchste
Zeit, mit dem Programmieren richtig loszulegen.
In diesem Kapitel lernst du:
$ wie du mit PHP Daten ausgibst
$ wie du mit Variablen arbeitest, den variablen Platzhaltern
$ wie du Zeilenumbrche setzt
$ wie du Sonderzeichen maskierst
$ wie du Fehler erkennst und vermeidest
90
Hallo echo Hallo Welt

Kapitel
3 Daten ausgeben mit echo
Gleich zu Anfang stelle ich die wichtigste Sprachanweisung von PHP vor
echo. Und ich verspreche dir, es ist eine Anweisung mit Nachhall. Doch
vorher klren wir, wie PHP-Dokumente berhaupt aufgebaut sind und wo
du die PHP-Anweisungen notierst.
Wie sind PHP-Dokumente aufgebaut?
Die PHP-Notation ist unkompliziert. Was musst du wissen? Nicht viel!
PHP-Dokumente sind eigentlich nichts weiter als HTML-Dokumente. Sie
besitzen die Endung .php. Sie enthalten zustzlich Abschnitte mit PHP-
Code. Diese PHP-Abschnitte notierst du ganz einfach irgendwo innerhalb
des HTML-Quelltexts. Wo, ist im Prinzip fast egal. Hauptsache du machst
deutlich, dass es sich um einen PHP-Abschnitt handelt.
Wie kennzeichne ich meinen PHP-Code?
Ganz einfach. Zu Beginn des PHP-Teils notierst du Folgendes:
<?php

Am Schluss des PHP-Abschnitts schreibst du dagegen:
?>

Das wars schon. Das ist die Form, die ich dir empfehle.
Du knntest aber auch schreiben:
<?

und
?>

wobei du dann die Kurzform gewhlt httest. (Ich zeige es dir deshalb,
damit du dich nicht wunderst, wenn dir diese Schreibweise bei anderen
Skripten begegnet.) Wir bleiben bei der Langform, da sie zu 100% dem
Standard entspricht. Warum ist die Kennzeichnung des PHP-Abschnitts
eigentlich so wichtig?
91
Daten ausgeben mit echo

Erst durch diese Kennzeichnung wei der Webserver, dass es sich um
PHP-Abschnitte handelt. Denn diese Abschnitte werden nicht einfach so
an den Browser geschickt. Sie werden vorher interpretiert, ausgefhrt.
Vergiss nicht: Der Benutzer bekommt nur eine HTML-Seite mit HTML-
Anweisungen zugeschickt. Den PHP-Code bekommt er nie zu Gesicht!
Hallo Welt dein erstes Skript
Unter Programmierern ist es eine hbsche Tradition, die Welt am Anfang
mit einem krftigen Hallo zu begren. Schreibe ein Skript, welches den
Text Hallo Welt ausgibt. Das Dokument soll hallo.php heien und in
unserem htdocs-Ordner unter C:\xampp abgelegt werden.
>
Erzeuge mit deinem bevorzugten Code-Editor (PSPad, Aptana Studio
usw.) eine neue, leere HTML-Datei. In PSPad whlst du DATEI|NEU,
gehst ins Register Neue Datei aus Vorlage erstellen und doppelklickst
auf die Vorlage HTML 4.01 Transitional. (Falls du die Aufgabe von Sei-
te 88 gelst hast, gibt es auch einen schnelleren Weg.)
>
Nun erscheint das schon bekannte Grundgerst einer HTML-Datei.
Bereite zwischen <body></body> einen PHP-Bereich vor. Kleide die
PHP-Tags auerdem durch <p></p> ein. Damit sorgst du dafr, dass
der Text innerhalb des obligatorischen HTML-Blockelements notiert
wird. Der Bereich innerhalb von <body></body> sieht dann so aus:
<p>
<?php

?>
</p>

>
Notiere zwischen den PHP-Tags <?php ?> jetzt folgende PHP-Zeile:
echo "Hallo Welt!";

>
Nicht vergessen: Speichere dein Dokument. Whle den Namen
hallo.php. Denke an den korrekten Speicherpfad: xampp/htdocs!
PSPad bietet dir beim Speichern den Dateityp HTML Document an. Doch
wir brauchen PHP. Stelle daher im Listenfeld bei Dateityp vorher Alle Da-
teien (*.*) ein. Notiere dann den Dateinamen im Dateiname-Feld.
92
Hallo echo Hallo Welt

Kapitel
3 Die Sprachanweisung echo sorgt dafr, dass die entsprechenden Daten
ausgegeben werden. Die auszugebenden Daten notierst du innerhalb von
Gnsefchen. Die Zeile wird am Ende durch ein Semikolon abgeschlos-
sen.
Quelltext fr die hallo.php
So sieht das gesamte Beispiel aus. Ich habe den Titel in der vierten Zeile
angepasst und auerdem eine beschreibende berschrift eingefgt. Aber
Hallo der eigentliche PHP-Teil ist nur ganz kurz:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN">
<html lang="de">
<head>
<title>Hallo-Welt-Skript</title>
<meta http-equiv="content-type" content="text/html;
charset=utf-8">
<link rel="stylesheet" type="text/css" href="phpkid.css">
</head>
<body>
<h3>Hallo-Welt-Skript</h3>
<p>
<?php
echo "Hallo Welt!";
?>
</p>
</body>
</html>

Du mchtest auch mit einer externen CSS-Datei arbeiten? Damit die sechs-
te Zeile im Quelltext Sinn macht? Dann vergiss nicht, dass du die Datei
phpkid.css ebenfalls in den Ordner htdocs kopieren musst. Sonst wer-
den deine Stile nicht angezeigt!
Teste dein Dokument mit dem Webserver
Sicher bist du neugierig, ob alles funktioniert. Rufe dein Dokument im
Webserver auf. Da du es direkt im Wurzelordner htdocs gespeichert hast,
ist das ganz einfach. Tippe http://localhost/hallo.php und drcke
auf [Enter]. Wenn alles geklappt hat, msstest du folgendes Bild sehen:
93
Daten ausgeben mit echo


Der PHP-Code wird interpretiert: Der Browser gibt den Hallo Welt-Text aus.
Hats funktioniert? Herzlichen Glckwunsch!
Huch, bei dir gibt es eine Fehlermeldung? Oder der Text wird nicht ange-
zeigt? Beachte, dass die Anzeige nur funktioniert, wenn du die Seite ber
den Webserver startest. Das direkte Aufrufen mit Doppelklick fhrt dazu,
dass der PHP-Abschnitt nicht interpretiert wird. Kunststck, wenn du
den Webserver umgehst? Weitere Fehlermglichkeiten bespreche ich ein
paar Seiten weiter hinten im Abschnitt Fehlermeldung. Also, cool blei-
ben!
PSPad: Raffinierte Farbhervorhebung
Mal was anderes: Ist dir eigentlich die interessante farbliche Darstellung in
PSPad aufgefallen? Sowohl die HTML- als auch die PHP-Befehle werden
durch unterschiedliche Farben optisch gut hervorgehoben. Dafr sorgt der
HTML multihighlighter eine raffinierte Farbhervorhebungsautomatik.

Stelle zur Probe einmal einen anderen Highlighter ein. Dazu klickst du ein-
fach auf den Text HTML multihighlighter aus der Statuszeile. Nun erscheint
Der HTML Multihigh-
lighter ist automatisch
aktiv. Du erkennst es an
der entsprechenden
Anzeige in der Status-
zeile.
94
Hallo echo Hallo Welt

Kapitel
3
ein Dialogfenster und zeigt dir eine Auswahl vieler anderer Farbhervorhe-
bungs-Module. Probiere doch einmal die Einstellung HTML. So wird nur
der HTML-Code farblich hervorgehoben. Du kannst den Fokus aber auch
ausschlielich auf PHP legen.
Du musst den Highlighter aber normalerweise nicht von Hand whlen.
PSPad erkennt den Dateityp automatisch anhand der Endung einer Datei.
Rufe doch einmal die phpkid.css auf und prfe, welcher Highlighter ge-
whlt ist. Richtig: Cascading Style Sheets.
Variablen: Mein rechter, rechter
Platz ist leer
Die Welt haben wir schon begrt. Wunderbar! Richten wir unser Augen-
merk deshalb auf die nchste Umgebung: Auf Katja, Leon, Peer, Manja und
auf wen auch immer. Schmettere einem dieser lieben Menschen ebenfalls
einen freundlichen Gru entgegen.
Bleiben wir im Beispiel einfach bei Katja. Begre sie mit PHP! Erstelle ein
neues PHP-Dokument. Nenne es katja.php und lege es wieder in den
Ordner htdocs. Als Titel und berschrift schlage ich Persnliche Begr-
ung mit Variablen vor. Doch was sind Variablen?
Was sind Variablen?
Variablen sind Platzhalter! Es sind Speicherstellen im Hauptspeicher des
Rechners. Stell dir eine Variable einfach als Behltnis vor. Es ist ein Behlt-
nis, welches dir fr die Dauer der Programmausfhrung zur Verfgung
steht. Was du hineinpackst, bleibt dir berlassen. Du kannst den Inhalt der
Variablen beliebig ndern und erweitern. Auch den Namen des Behlters
selbst kannst du frei whlen. Na ja, fast frei zumindest.
Die Namen von Variablen beginnen immer mit einem Dollarzeichen. Ver-
wende keine Umlaute, Leer- oder Sonderzeichen! So wre $eimer ein
erlaubter Variablenname, nicht aber $meine schssel. Der Unterstrich
(_) ist jedoch gestattet. Er dient oft als Ersatz fr das verbotene Leerzei-
chen. So wre $dein_name eine wunderbare Variable. Selbst kurze Vari-
ablen wie $i oder $k kannst du verwenden. Weiterhin gilt: Gro- und
Kleinschreibung werden unterschieden. So sind $vorname und
$Vorname zwei unterschiedliche Variablen. (Damit solche Probleme gar
nicht erst auftreten, rate ich zu genereller Kleinschreibung!)
95
Variablen: Mein rechter, rechter Platz ist leer

Beachte zustzlich: Einige in PHP reservierte Wrter drfen nicht als Va-
riablenname verwendet werden. Das sind Wrter wie while, if,
switch, for usw. usf. Auerdem ganz wichtig: Beginne Variablennamen
nie mit einer Zahl. Nicht funktionieren wird ein Name wie $68name. (In
der Variablen selbst sind jedoch Ziffern gestattet.)
Der Platzhalter $vorname
Fr unser Katja-Beispiel habe ich mir die Variable $vorname ausgedacht.
Dieser muss ich nur noch einen Wert zuweisen. Im Beispiel soll es der Na-
me Katja sein. Wie mache ich das? So:
$vorname = "Katja";

Die Variable selbst steht links. Danach folgt ein sogenannter Zu-
weisungsoperator. Dann notiere ich den eigentlichen Wert des Variablen-
Platzhalters. Und dieser befindet sich rechts, getreu dem Motto Mein
rechter, rechter Platz ist leer.
Warum notiere ich den Namen Katja in Gnsefchen? Weil es sich um
Text handelt. In diesem Zusammenhang spricht man von einem soge-
nannten String. Strings werden stets im Gnsefchen notiert. Bei Zah-
len dagegen brauchst du keine Gnsefchen zu setzen. Klar?
Der gesamte Quelltext des PHP-Bereichs sieht so aus.
<?php
$vorname = "Katja";
echo "Hallo $vorname!";
?>

Denke an das Semikolon am Zeilenende. Jede Zeile wird in PHP in der Regel
durch ein Semikolon abgeschlossen!

Hallo Katja! So sieht mein
Beispiel aus.
96
Hallo echo Hallo Welt

Kapitel
3
Das Beispiel findest du auf der CD im Ordner kapitel03. Schaue in die
Datei katja1.php.
Wie funktioniert das Skript?
Ganz einfach! In der ersten Zeile taucht die Variable $vorname das erste
Mal auf. Du weist ihr gleich den Wert Katja zu. Doch warum steht Katja in
Gnsefchen? Bei Katja handelt es sich um Text. Und Text entspricht dem
sogenannten Datentyp String. Das muss durch Gnsefchen verdeutlicht
werden, denn Strings mssen stets in Gnsefchen stehen.
Neben dem Datentyp String kennt PHP noch den Datentyp Integer. Die-
ser Datentyp steht fr eine normale Ganzzahl wie 5 oder 9834. Als wei-
teren Datentyp gibt es in PHP den Datentyp Float (Kommazahl). Spter
lernst du den Typ Boolean fr Wahrheitswerte wie true oder false
kennen. Wie du siehst, sind es alles in allem nur wenige Datentypen. Da
PHP die Datentypen automatisch erkennt, musst du dich darum nicht
weiter kmmern. (Der Fachmann sagt: Die Variablen sind nicht typisiert.)
In Zeile 1 hast du die Variable also initialisiert, wie der Profi sagen wrde.
Nicht vergessen: Die Zeile wird dann durch ein Semikolon abgeschlossen.
Noch einmal im Klartext: Wir haben uns unseren eigenen Behlter na-
mens $vorname eingerichtet und dort den Text Katja hineingetan.
Nun zur zweiten Zeile. Hier sorgt die echo-Anweisung nun dafr, dass
etwas ausgegeben wird. Das Ausgabegut steht brigens wieder in Gnse-
fchen. Auch hier handelt es sich um Text. Richtig erkannt: Es wird ein
String ausgegeben! Nach dem Wort Hallo und einem Leerzeichen hat unse-
re Variable $vorname ihren groen Auftritt. Nun wird der Wert ausgege-
ben, der in der Variablen gespeichert ist. Dieser lautet Katja.
Fazit: Im Browser erscheint der Text Hallo Katja!
Ausgabe verschnern mit
HTML-Tags
Die Ausgabe gefllt dir noch nicht? Verschnere sie einfach! Du kannst im
Zusammenhang mit echo ganz problemlos HTML-Tags einsetzen. Die Ver-
sion 2 des Katja-Beispiels sieht folgendermaen aus:
97
Wie Pech und Schwefel: Strings verketten

<?php
$vorname = "Katja";
echo "Hallo <b>$vorname</b>!";
?>

Wie du siehst, kannst du ganz problemlos HTML-Tags in deinen Ausgabe-
String einfgen. Hier habe ich zustzlich mit dem Tag-Paar <b></b> fr
bold (fett) gearbeitet.
Passe dein Beispiel dementsprechend an. Speichere und aktualisiere die
Ansicht im Browser. Dazu drckst du die Funktionstaste [F5]. Das geht
natrlich nur, wenn du die Seite http://localhost/katja.php noch
aufgerufen hast.

Wie du in der Abbildung siehst, werden die Tags korrekt ausgegeben. Zum
Vergleich habe ich den Quelltext der Webseite aufgerufen. Das solltest du
ruhig ebenfalls einmal probieren. Whle dazu im Men ANSICHT den Befehl
QUELLTEXT.
Vergewissere dich! Im Quelltext der Webseite ist tatschlich kein PHP-
Code mehr enthalten. Denn schlielich sorgt der Webserver dafr, dass
PHP interpretiert, ausgefhrt wird. Und der Webserver schickt halt den
HTML-Code Hallo <b>Katja</b>! an den Browser.
Das Beispiel findest du auch auf der CD, und zwar wieder im Ordner
kapitel03. Der Dateiname dieser Version lautet katja2.php.
Wie Pech und Schwefel: Strings
verketten
PHP ist einfach! Unter dem Motto Freiheit fr Kettenhunde reden wir nun
ber die Hundeleine in PHP. Ich meine den Verkettungsoperator Punkt.
Doch eigentlich brauchen wir ber diesen Punkt gar nicht so viele Worte zu
Der Beweis: Ansicht im
Browser und im HTML-
Quelltext.
98
Hallo echo Hallo Welt

Kapitel
3
verlieren. Der groe Vorteil: Strings und Variablen mssen nicht verkettet
werden. Zumindest gilt das in den meisten Fllen. Doch was ist mit Verket-
ten berhaupt gemeint?
Unter Verketten versteht man das Verbinden von zwei oder mehr Zei-
chenketten. Dazu wird normalerweise ein sogenannter Verkettungsope-
rator verwendet. Als Verkettungsoperator dient in PHP der Punkt.
Schaue dir doch noch einmal unser Beispiel von eben an:
<?php
$vorname = "Katja";
echo "Hallo <b>$vorname</b>!";
?>

Du setzt die Variable einfach so mir nichts dir nichts in die Zeichenkette
hinein. Das spart viel Schreibarbeit und scheint fr uns ganz selbstver-
stndlich zu sein. Ist es auch, denn diese raffinierte Technik ist eine Spezia-
litt von PHP.
Bei herkmmlichen Programmiersprachen gilt jedoch: Eine Variable darf
grundstzlich nicht so einfach innerhalb von Gnsefchen notiert werden.
Sie muss stets ohne Gnsefchen stehen. Das knnen wir mit PHP nach-
spielen. Schau dir zum Vergleich dieses vereinfachte Beispiel an. Hier ge-
ben wir nur den Wert aus der Variablen aus:
<?php
$vorname = "Katja";
echo $vorname;
?>

Die Variable selber wurde dank der Gnsefchen schon in der ersten Zeile
als Zeichenkette gekennzeichnet. Es ist also vllig berflssig, in der
zweiten Zeile noch Gnsefchen aufzuschreiben.
Strings und Variablen verketten? Meist
unntig!
Eine Variable wird normalerweise nicht in Gnsefchen gesetzt. Der Rest
jedoch muss als Zeichenkette gekennzeichnet werden. Um Variable und
umgebende Zeichenketten zu verbinden, bedient man sich in herkmmli-
chen Programmiersprachen der Technik des Verkettens.
99
Wie Pech und Schwefel: Strings verketten

Warum? In diesen Sprachen darf die Variable nicht einfach Teil des Strings
sein. Sie muss mit dem String verkettet werden. Was in anderen Program-
miersprachen das einzig Wahre ist, geht natrlich auch in PHP.
Du kannst das Beispiel von oben also auch in dieser Verkettungs-Variante
aufschreiben. Hier als die Version 3 des Katja-Beispiels:
<?php
$vorname = "Katja";
echo "Hallo <b>" . $vorname . "</b>!";
?>

Interessant ist die zweite Zeile. Das Ergebnis entspricht der Version 2. Nur
die Schreibweise ist komplizierter geworden. Die Variable wird zu ihrer
linken und rechten je mit dem umgebenden String verkettet. Die Ausgabe
jedoch ndert sich nicht, es erscheint weiterhin der Text Hallo Katja! im
Browser.
Wie schon erwhnt: In PHP ist das umstndliche Verketten von Strings mit
Variablen in den meisten Fllen nicht ntig. Die Variable vertrgt es, mit in
das Gnsefchen-Boot genommen zu werden. Wir haben uns in diesem
Beispiel also zu viel Arbeit gemacht. Dieses Zuviel an Arbeit findest du
zum Vergleichen unter dem Namen katja3.php auf der Buch-CD.
Strings verketten manchmal gehts nicht
ohne!
Warum habe ich dir diese umstndliche Variante hier schon gezeigt? Nun,
in manchen Fllen kommst du um das Verketten nicht drum herum! Zum
Beispiel bei Funktionen. Oder bei den sogenannten Feldvariablen, den Ar-
rays. Einverstanden, die Arrays kennst du noch nicht. Das verschieben wir
also auf spter. Doch mit einer Funktion knnen wir uns an dieser Stelle
schon beschftigen.
Nix verstehen? Nehmen wir ein Beispiel! Angenommen, du mchtest den
markigen Satz: Hallo Katja, willkommen in 2010! ausgeben. Weiterhin
wnschst du, dass das Jahr automatisch erzeugt wird. (Wenn du das Buch
in 2011 oder 2012 liest, soll natrlich auch 2011 bzw. 2012 ausgegeben
werden.) Wie geht das? Mit einer Funktion! Du nimmst einfach eine ent-
sprechende Funktion mit dem passenden Argument.
100
Hallo echo Hallo Welt

Kapitel
3 Zum Ausgeben der aktuellen Jahreszahl dient die Funktion date("Y")
oder auch date('Y'). Um genauer zu sein: Es ist eine Funktion mit Ar-
gument. Die Funktion selbst lautet dabei date(). Das Argument ist
hierbei "Y". Und nun noch ein paar Worte zu den Gnsefchen: Ob du
die doppelten oder die einfachen Gnsefchen whlst, ist eigentlich
egal. Da du aber Gnsefchen nicht einfach ineinander verschachteln
darfst, musst du in manchen Fllen die Variante mit den einfachen Gn-
sefchen whlen. Entscheide also von Fall zu Fall.

Schreibe die entsprechende Zeile also folgendermaen:
echo "Hallo <b>$vorname</b>, willkommen in " . date("Y") . "!";

Hier haben wir mit Hilfe der Verkettung dafr gesorgt, dass die Funktion
funktioniert. Das Jahr wird korrekt berechnet. (Vergleiche, wenn du
magst, mit dem Vorbild-Beispiel katja4.php auf der CD.)
Achte beim Verketten unbedingt darauf, dass Leerzeichen mit berck-
sichtigt werden mssen. So musst du im Beispiel nach dem Wort in un-
bedingt ein Leerzeichen setzen, bevor du das schlieende doppelte Gn-
sefchen setzt. Da das Ausrufungszeichen jedoch direkt hinter der Jah-
reszahl notiert werden soll, ist dort kein Leerzeichen ntig.
Wrdest du auf die Verkettung verzichten, wre das Ergebnis grausam. Bei
der Variante mit doppelten Gnsefchen date("Y") wrde es Fehlermel-
dungen hageln. Warum? Weil du versucht hast, Gnsefchen ineinander
zu verschachteln. Das solltest du dir also nicht antun.
Aber auch eine Vernderung von date("Y") in date('Y') fhrt nicht
zum gewnschten Ergebnis. Zugegeben, das Gnsefchen-Problem haben
wir damit auf raffinierte Art gelst. Folgender Quellcode
echo "Hallo <b>$vorname</b>, willkommen in date('Y')!";

Die Jahreszahl wird durch
die Funktion date("Y")
erzeugt.
101
Kleine Zeilenumbruchkunde

fhrt jedoch zu dieser Anzeige:

Die Funktion wird nicht ausgefhrt, sondern im Klartext angezeigt.
Was ist passiert? Statt die Funktion auszufhren, zeigt sie der Webserver
im Klartext an. Kunststck, die Funktion wurde als String behandelt, als
einfache Zeichenfolge. Und das ist natrlich Quatsch mit Soe, denn so
kann sie nicht funktionieren.
Kleine Zeilenumbruchkunde
Kennst du den Breakdance? Oder das berhmt-berchtigte englische
Breakfast? Alles hat irgendwie mit Brechen zu tun. Beim Breakdance
bricht man sich womglich die Knochen, beim englischen Breakfast
nein, lassen wir das jetzt.
Mit <br> einen HTML-Zeilenumbruch erzeugen
Ich wollte eigentlich auf den Break hinaus, auf den Umbruch. Ich zeige dir,
wie du problemlos einen Zeilenumbruch (<br>) in dein Dokument zauberst.
Dafr erweitern wir einfach mal unser Katja-Beispiel. Ich greife dafr auf
eine frhere Fassung zurck, auf unsere Version 2: Hier noch einmal der
PHP-Teil:
<?php
$vorname = "Katja";
echo "Hallo <b>$vorname</b>!";
?>

Und jetzt ergnzen wir eine zweite echo-Zeile! Damit die neue Zeile auch
wirklich auf die neue Zeile rutscht, fge ich zustzlich einen HTML-
Umbruch ein. Dafr sorgt das Zeichen <br>.
102
Hallo echo Hallo Welt

Kapitel
3

<?php
$vorname = "Katja";
echo "Hallo <b>$vorname</b>!<br>";
echo "Super, dass du mal vorbeischaust.";
?>

Im Browser sieht das Ganze so aus, zustzlich habe ich ber den Befehl
SEITE|QUELLTEXT ANZEIGEN (Internet Explorer) bzw. ANSICHT|SEITENQUELLTEXT
ANZEIGEN (Firefox) gleich den HTML-Quelltext aufgerufen.

Bisher haben wir nur einen Umbruch im Browser erzeugt. Im Hintergrund
findet jedoch kein Zeilenumbruch statt. Dieses Beispiel kannst du unter
dem Namen katja-br.php von der CD abrufen.
Umbruch im Editor: Der Befehl \n wie new line
Wie wre es zustzlich noch mit einem Umbruch im Editor? Zugegeben, bei
zwei Zeilen ist das vielleicht nicht so wichtig. Doch wenn du hufiger mit
echo arbeitest, entsteht irgendwann eine Endlos-Zeile im Editor. Wenn
du hinter den Kulissen einen Zeilenumbruch wnschst, verwendest du den
PHP-Befehl new line. Das entsprechende Zeichen heit: \n
Vor dem n wird lediglich ein Backslash notiert, ein rckwrtsgelehnter
Schrgstrich. Das n selbst steht als Abkrzung fr new line. Und so sieht
das renovierte Beispiel aus, ich habe gleich zweimal mit \n gearbeitet:
<?php
$vorname = "Katja";
echo "Hallo <b>$vorname</b>!<br>\n";
echo "Super, dass du mal vorbeischaust.\n";
?>
Im Quelltext siehst du
zwar das Tag <br>,
aber keinen
Zeilenumbruch.
103
Maskenball: Das Escape-Zeichen \

Beim Aufruf im Browser wirst du keinen Unterschied zur vorherigen Vari-
ante feststellen. Nur der Blick in den Quelltext offenbart den kleinen, aber
feinen Unterschied:

Vergleiche mit der Datei katja-nl.php von der CD.
Maskenball: Das Escape-Zeichen \
Mit dem Backslash hat es eine besondere Bewandtnis. Eben habe ich dir
diesen schiefen Kollegen im Zusammenhang mit dem Zeilenumbruch
vorgestellt. Mit \n wird eine neue Zeile im Editor erzeugt, du erinnerst
dich.
In diesem Fall wird unser Strich-Kumpel also zu einem Steuerbefehl fr
die Anzeige des Quelltextes.
Die wichtigsten Umbruch-Steuerbefehle
Es gibt brigens noch mehr solcher interessanten Steuerbefehle. Die wich-
tigsten davon stelle ich dir in dieser Tabelle vor:
\n \r \t
erzeugt neue
Zeile
erzeugt return (neuen Absatz) erzeugt Tabulatorschritt
(Sprung)

Gut, damit haben wir die eine Bedeutung geklrt. Doch hast du schon ein-
mal darber nachgedacht, was das komische Zeichen \ wohl sonst noch
bedeuten mag?
Mit \n erzeugst du
die Zeilenumbrche
auch im Quelltext.
104
Hallo echo Hallo Welt

Kapitel
3
Backslash als Escape-Zeichen
Dieser Backslash (\) wird auch als Escape-Zeichen bezeichnet. Denn nor-
malerweise dient er zum Maskieren bestimmter Sonderzeichen, die du
sonst nicht so einfach ausgeben darfst.
So darfst du z. B. Gnsefchen nicht einfach im Klartext in dein Skript
hineinschreiben. Gnsefchen signalisieren schlielich, dass ein String
beginnt bzw. endet.
Doch wenn du unbedingt die Gnsefchen bentigst? Vielleicht, weil du
eine Passage in Anfhrungszeichen setzen willst? Die eine Mglichkeit
lautet: Ersetze die Gnsefchen durch einfache Gedankenstriche.
Die andere Lsung: Maskiere die Gnsefchen durch das Escape-
Zeichen.
<?php
$vorname = "Katja";
echo "Hallo <b>\"$vorname\"</b>!<br>\n";
?>

Das Ergebnis im Browser sieht dann so aus:

Vergleiche mit der Datei escape.php auf der Buch-CD.
Du musst auch das Dollar-Zeichen ($) oder den Backslash (\) maskieren,
falls du diese Zeichen per echo als HTML ausgeben willst. Denn auch
diese Zeichen haben normalerweise eine Sonderbedeutung.
Nach dem Escapen
werden auch Gnsef-
chen korrekt angezeigt.
105
Keinen Durchblick? Kommentare setzen!

Keinen Durchblick? Kommentare
setzen!
Steigst du noch durch deinen Quelltext durch? Klar doch! Bei zwei oder
drei Zeilen ist das alles noch kein Problem!
Doch wie sieht das bei umfangreichen Projekten aus? Weit du nach Wo-
chen immer noch genau, was die geniale Zeile 87 macht? Und wozu die
schlieende geschweifte Klammer in Zeile 145 dient? Der Mensch vergisst
(und auch Buffi-Hunde haben nicht gerade das beste Gedchtnis.)
Gewhne dir deshalb frhzeitig an, mit Kommentaren zu arbeiten! Das
sind Bereiche, die nur von dir gesehen werden, aber auf den Programm-
ablauf keinen Einfluss haben. Kommentare helfen dir, den PHP-Quellcode
zu erklren.
Einzeilige Kommentare
Willst du schnell mal einen einzeiligen Kommentar setzen, verwendest du
den Doppelslash //:
// Das ist ein einzeiliger Kommentar

Du kannst diesen Kommentar auch direkt an das Ende einer Zeile setzen,
z. B. folgendermaen:
$vorname = "Katja"; // Variable $vorname initialisieren
Kommentare ber mehrere Zeilen ziehen
Wenn du dagegen ganze Romane schreiben mchtest, bietet dir PHP
auch dafr eine Mglichkeit. Fasse deine mehrzeiligen Kommentare zwi-
schen den Zeichen /* und */ zusammen:
/* Das ist ein Kommentar, der sich
im Beispiel gleich ber mehrere Zeilen
erstreckt und Platz im Buch verschwendet */

106
Hallo echo Hallo Welt

Kapitel
3 Also ich habe es mir inzwischen angewhnt, ausgiebig mit Kommentaren
zu arbeiten. Ich kann dir diese Vorgehensweise nur empfehlen. Ein ande-
rer Trick besteht darin, dein Skript einfach durch Leerzeilen zu gliedern.
Tippe ruhig auf [Enter], um vor und nach einer wichtigen Zeile eine
Leerzeile zu erzeugen. Das erhht die bersicht enorm. Der Pro-
grammablauf wird dadurch jedoch nicht gestrt.
Fehlermeldung? Cool bleiben!
Es ist zum Auswachsen! Du tippst deinen Code und ldst das Dokument in
den Webserver? Eine Fehlermeldung taucht auf. Du korrigierst, ldst erneut
der Fehler bleibt. Ach ja, das Speichern. Du hattest vergessen, vor dem
Aktualisieren zu speichern. Neu laden und was sehen deine vom Bild-
schirmflimmern beranstrengten uglein jetzt? Eine neue Fehlermeldung!
Es ist manchmal fast zum Auswachsen und es gibt Momente, da wrden
Hund Buffi und Buchautor Hanke den PC mitsamt Monitor am liebsten
gemeinsam aus dem Fenster werfen. Doch halt! Cool bleiben, lautet die
Devise. Hier ein paar Tipps, wie du Fehler vermeiden kannst.
Semikolon ; am Zeilenende vergessen?
Vergiss nicht, dass eine Programmier-Zeile am Ende mit einem Semikolon
abgeschlossen werden muss. Das vergessene Semikolon ist einer der hu-
figsten Fehler. Praktisch alle Zeilen mssen mit einem Semikolon abge-
schlossen werden. (Nur in Ausnahmefllen lsst du das Semikolon weg.
Aber darauf kommen wir noch zu sprechen!)

Schau dir die Abbildung an. Das Gemeine an der Geschichte: Die Fehler-
meldung bezieht sich nicht etwa auf die Zeile, in der das Semikolon fehlt.
Es wird die nchste Zeile (hier Zeile 14) moniert. Klar, denn da du das Semi-
kolon vergessen hast, wei der PHP-Interpreter nicht, dass die Zeile schon
zu Ende war.
Grausam: Schon ein
vergessenes Semikolon
fhrt zu einer
Fehlermeldung.
107
Fehlermeldung? Cool bleiben!

Variablen korrekt benannt?
Ein anderer typischer Fehler schleicht sich immer wieder bei den Variablen
ein. Hast du dem Variablennamen auch wirklich ein Dollarzeichen vorange-
stellt?

Wenn ich Dollarzeichen sage, meine ich auch Dollarzeichen. Mir passiert es
gelegentlich, dass ich eine Variable statt $vorname als vorname schreibe.
Was ich hier im guten Glauben richtig gemacht zu haben glaubte, ist na-
trlich ein Fehler. Hast du die Gro- und Kleinschreibung bei Variablen
beachtet? Wenn du die Variable mit $Vorname initialisierst und versuchst,
mit $vorname darauf zuzugreifen, kann das einfach nicht gelingen.
Variablen drfen auerdem nicht mit einer Zahl beginnen, eine Bezeich-
nung $68vorname wrde ebenfalls zu einer Fehlermeldung fhren.
Gnsefchen richtig gesetzt?
Ein anderer typischer Fehler ist das Vergessen eines Gnsefchens. Wenn
du statt
$vorname = "Katja";

einfach schreibst
$vorname = "Katja;

gibt es auf jeden Fall Probleme. Jedes einschaltende Gnsefchen ben-
tigt auch ein Ausschalt-Pendant.
Falsche Klammersetzung?
Apropos Ein- und Ausschalten. Im Verlauf des Buches wirst du mit Klam-
mer-Blcken arbeiten. Nutze die schon von CSS bekannten geschweiften
Klammern { }, um mehrere Zeilen zu einem Block zusammen zu fassen.
Bei den sogenannten Fallunterscheidungen oder den Schleifen zeige ich dir
dieses Prinzip spter noch ganz genau. Soviel schon vorweg: Auch das ver-
sehentliche Vergessen einer ffnenden oder schlieenden Klammer fhrt
natrlich zu Fehlermeldungen.
Verschreiber bei den
Variablennamen
gehren ebenfalls
zu den hufigen
Fehlern.
108
Hallo echo Hallo Welt

Kapitel
3
Probleme gibt es vor allem dann, wenn du mehrere Klammern-Blcke
ineinander verschachteln musst, und nicht mehr durchblickst, wo welche
Klammer nun geschlossen werden soll. Auch hier schon an dieser Stelle
mein Tipp: Kommentare setzen! Notiere, wo du welche Klammer ffnest
und wieder schliet.
Bei dir wird der PHP-Code berhaupt nicht ausgefhrt? Nur der HTML-
Teil der Seite erscheint? Hast du denn die Seite ber den Webserver auf-
gerufen? Also z. B. ber http://localhost/katja.php? Das einfache
Doppelklicken auf den Eintrag funktioniert nicht. Vergiss nicht, dass PHP
erst durch den Webserver gezogen werden muss: Bei PHP handelt es
sich schlielich um Server-Programmierung!
Schlussbemerkung
Was fr ein Kapitel! Du kannst nun programmieren. Na gut, ein wenig zu-
mindest schon. Du kennst Variablen, weit, wie du Text ausgibst und
kmpfst (hoffentlich erfolgreich) mit einer Vielzahl von Fehlern.
Zusammenfassung
0 Du weit, dass PHP-Dokumente HTML-Dokumente mit der Endung
.php sind. Du weit, dass PHP-Bereiche von <?php ... ?> umschlos-
sen werden.
0 Du kennst die Sprachanweisung echo zur Ausgabe von Daten. Setze
den auszugebenden String in Gnsefchen, schliee die Zeile durch
ein Semikolon ab: echo "Hallo Welt!";
0 Du kennst das Konzept der Variablen, der variablen Platzhalter. Du
mchtest eine Variable initialisieren? Notiere die Variable links, den
Wert rechts. Setze dazwischen das Gleichheitszeichen, hier Zuwei-
sungsoperator genannt: $vorname = "Katja"; (Die Leerzeichen vor
und nach dem Istgleichzeichen haben lediglich eine optische Funktion.)
0 Du weit, dass du bei der Ausgabe mit echo selbst mit HMTL-Tags ar-
beiten kannst. Notiere Strings und Variablen einfach innerhalb eines
Gnsefchen-Paars. Du bentigst keinen Verkettungsoperator, wenn
du mehrere Elemente zu einem String zusammensetzen mchtest. Eine
Zeile wie echo "Hallo <b>$vorname</b>!"; ist fr PHP kein Pro-
blem.
109
Ein paar Fragen

0 In wenigen Fllen musst du doch den Verkettungsoperator Punkt ver-
wenden, beispielsweise bei der Rckgabe von Werten aus Funktionen.
Du hast den Verkettungsoperator im Zusammenhang mit der Funktion
date() kennengelernt.
0 Du kennst den Steuerbefehl \n, mit dem man einen Zeilenumbruch
auch im Editorfenster erzeugt. Du weit, dass man mit \ sonst nicht
darstellbare Sonderzeichen wie " oder $ maskieren (escapen) kann:
Schreibe z. B. \" bzw. \$
0 Du kennst meine Empfehlung zum Setzen von Kommentaren. Einzeilige
Kommentare notierst du hinter //, mehrzeilige Kommentare kleidest du
in die Zeichen /* und */ ein.
0 Wir haben besprochen, woher viele Fehler herrhren. Vergiss keinesfalls
das Semikolon am Zeilenende oder das schlieende Gnsefchen. Ach-
te stets auf die korrekte Schreibweise der Variablen.
Ein paar Fragen
1. Wie nennt man das Gleichheitszeichen zwischen Namen und Wert einer
Variablen?
2. Nenne drei Datentypen fr Variablen in PHP!
3. Mit welchem Steuerbefehl erzeugst du eine neue Zeile im Editor?
und ein paar Aufgaben
1. Schreibe ein PHP-Dokument, welches den Satz PHP macht Spa! aus-
gibt. Nenne es fun.php.
2. Wie heit dein bester Kumpel? Speichere ihren/seinen vollstndigen
Namen in zwei Variablen. Nenne die erste Variable $vorname, die zwei-
te $nachname. Gib den Namen mit PHP aus, indem du diese beiden Zei-
chenketten gemeinsam ausgibst. Speichere das Dokument unter dem
Namen kumpel.php.
3. Fge in die Datei kumpel.php einen Kommentar ein, der dir jede Zeile
erklrt.
111



4
Spa mit Datum und
Uhrzeit
Time is money, Zeit ist Geld! So lautet das gnadenlose Motto vieler Er-
wachsener. Ich habe mir fr dieses Kapitel einen ungleich besseren Wahl-
spruch ausgedacht. Er lautet: Time is fun, Zeit macht Spa.
In diesem Sinne strzen wir uns nun ins Abenteuer Zeit. In diesem Kapitel
lernst du:
$ wie du mit den entsprechenden Funktionen Zeit und Datum ausgibst
$ wie du mit if-else-Kontrollstrukturen eine tageszeitabhngige Begr-
ung programmierst
$ wie du mit sogenannten Feldvariablen (Arrays) die Wochentage aus-
gibst
$ wie du mit Arrays in der Kurzform umgehst
$ wie du Monatsnamen in sogenannten assoziativen Arrays speicherst


112
Spa mit Datum und Uhrzeit

Kapitel
4 Immer up to date
Bist du up to date? Ich bin es nicht! Wenn mich einer nach dem Datum
fragt, zucke ich meist mit der Schulter. Wozu gibt es denn Computer? Fra-
gen wir doch einmal den Webserver, welches Datum wir gerade haben!
Bei den nun zu besprechenden Funktionen wird stets Datum und Uhrzeit
des Webservers zurckgegeben. Du arbeitest am heimischen PC? Dann
sind Datum und Uhrzeit natrlich identisch mit den Angaben deines PCs.
Auch bei den zu Beginn besprochenen Dienstleistern sollte es keine
Probleme geben. Wenn deine Seiten jedoch auf einem amerikanischen
Webserver liegen, handelt es sich bei der Serverzeit natrlich um die
amerikanische Zeit!
Das Datum ermitteln
Du mchtest Datum und Uhrzeit ermitteln? Dann brauchst du die Funktion
date()! Erinnerst du dich? Wir hatten uns diese Funktion im vorigen Kapi-
tel kurz angeschaut, allerdings nur im Zusammenhang mit dem Jahr. Der
Code zum Ermitteln des aktuellen Jahrs lautet: date("Y"). Als Ergebnis
bekommst du eine vierstellige Jahresanzeige wie 2008.
Doch das Jahr alleine reicht mir nicht aus. Selbst der schusselige Buchautor
kennt in der Regel den richtigen Jahrgang! Wo bleiben die Monate, die
Tage? Die holen wir uns schnell dazu! Fge der Funktion einfach weitere
Schalter hinzu.
Angenommen, du mchtest das Datum im Format 1.8.08 ausgeben. Also
den Tag und den Monat ohne fhrende Null und das Jahr mit zwei Stellen.
Dann schreibst du z. B.
echo date("j.n.y");

Wichtig sind die Buchstaben j, n und y. Die Punkte dienen lediglich zum
Gestalten.
Ran an die Praxis, probiere das doch gleich einmal aus! Erstelle eine neue
PHP-Datei, ich schlage den Namen datum1.php vor. Wir wollen das aktu-
elle Datum mit der eben besprochenen Funktion ausgeben.
Ich zeige dir auf der nchsten Seite, was ich zwischen den Tags
<body></body> notiert habe:
113
Immer up to date

<h2>Das aktuelle Datum ausgeben</h2>
<p>
<?php
echo date("j.n.y");
?>
</p>



Die Schalter zur Ermittlung des Datums
In der folgenden Tabelle habe ich dir alle Schalter zur Ermittlung des Da-
tums aufgeschrieben. Bitte bekomme keinen Schreck, denn hinterher pro-
bieren wir das Ganze an weiteren Beispielen aus!
Schalter Erklrung Beispiel
j
Monatstag ohne fhrende Null 1 bis 31
d
Monatstag mit fhrender Null 01 bis 31
n
Monatszahl ohne fhrende Null 1 bis 12
m
Monatszahl mit fhrender Null 01 bis 12
S
englisches Aufzhlungszeichen (st, rd, th) 1st 3rd 5th
y
Jahreszahl mit zwei Stellen 10
Y
Jahreszahl mit vier Stellen 2010
D
Wochentag, Kurzschreibweise Mon
l (kleines L) Wochentag, Langschreibweise Monday
M
Monatsname, Kurzschreibweise Jan
F
Monatsname, Langschreibweise January
w
Wochentag als Zahl (0=Sonntag) 0 bis 6
z
Tag des Jahres als Zahl 0 bis 365
t
Anzahl der Monatstage 28 bis 31
Weitere Praxisbeispiele
Schauen wir uns ein paar Praxisbeispiele an! Du mchtest nur den Wo-
chentag in der Langform ausgeben? Dann gengt folgende Zeile.
echo date("l");

Diese Funktion verrt dir
stets das aktuelle Datum.
114
Spa mit Datum und Uhrzeit

Kapitel
4
Solle es das Datum in voller Pracht sein? Wochentag und Monat jeweils
mit fhrender 0, also nach dem Muster 01.05.? Und das Jahr in vierstelli-
ger Schreibweise? Dann notierst du einfach:
echo date("d.m.Y");

Du wnschst z. B. folgende englische Schreibweise: 3rd of July 2010? Dann
versuche Folgendes es funktioniert aber nicht unter allen PHP-Versionen:
echo date("jS of F Y");

Wie du siehst, kannst du die Ausgabe des Datums sogar gestalten. Arbei-
te innerhalb von date() mit Leerzeichen und in Grenzen selbst mit an-
deren Zeichen wie hier mit dem Punkt! Setze diese Zeichen einfach an
der gewnschten Stelle innerhalb von date("") ein, wie bei diesem
Beispiel: date("d.m.Y")! Die Punkte dienen hier lediglich als kosmeti-
sches Beiwerk. Nicht alle Zeichen lassen sich jedoch verwenden, deshalb
wrde ich mich auf Leerstellen und den Punkt beschrnken. Im Zweifels-
falle lautet die Devise: Probieren geht ber Studieren.
Du mchtest angeben, wie viele Tage der aktuelle Monat hat? Du willst den
aktuellen Monat dabei ausschreiben (auf Englisch). Dann notierst du bei-
spielsweise folgenden Code (auf einer Zeile):
echo "Der " . date("F") . " hat " . date("t") . " Tage.";

Beachte, dass du hierbei wieder mit einer Verkettung arbeiten musst. An-
sonsten wird die Funktion nicht aktiviert.

Schau dir zum Vergleichen meine Beispieldatei an. Du findest sie im Ordner
kapitel04 unter dem Namen datum2.php.
Mit den entsprechenden
Schaltern gelingt dir die
gewnschte
Schreibweise im Nu.
115
Wer hat an der Uhr gedreht?

Wer hat an der Uhr gedreht?
Niemand, hoffe ich! Zumal die Zeitanzeige in PHP sowieso digital erfolgt.
Das Drehen an irgendwelchen Zeigern ist schon aus diesem Grund gar nicht
mglich.
Wie zeigt man die Uhrzeit an? Auch hier hilft uns die Funktion date() aus
der Patsche. Und wieder brauchen wir du ahnst es sicher lngst ganz
bestimmte Schalterchen fr diesen Zweck. Die wichtigsten Schalter lauten
H (Stunden im 24-Stunden-Format), i (Minuten mit fhrender Null von 00
bis 59) und s (Sekunden von 00 bis 59). Wenn du die Stunden, Minuten
und Sekunden anzeigen mchtest, schreibst du:
echo date("H:i:s");

Wie du siehst, arbeite ich auch hier mit Formatierzeichen. Diesmal verwen-
de ich den fr die Uhrzeit typischen Doppelpunkt (:).
Alle Uhrzeitschalter im Blick
In der folgenden Tabelle habe ich dir alle Schalter zur Ausgabe der Uhrzeit
aufgeschrieben. Trstlich es sind im Gegensatz zum Datum viel weniger:
Schalter Erklrung Beispiel
a
am oder pm am
A
AM oder PM AM
h
Stunde im 12-h-Format 1 bis 12
H
Stunde im 24-h-Format 1 bis 24
i
Minuten von 00 bis 59 04
s
Sekunden von 00 bis 59 12
Die Zeit vergeht ein kleines Beispiel
Zum Ausprobieren schlage ich ein kleines Beispieldokument vor. Nenne es
uhrzeit.php. Ich zeige dir lediglich den Teil zwischen den Tags
<body></body>, der Rest ist ganz normales HTML.
<h3>Beim Aufruf dieser Seite war es genau ...</h3>
<p>
<?php
echo date("H:i:s") . " Uhr";
?>
</p>
116
Spa mit Datum und Uhrzeit

Kapitel
4

Fr die genaue Uhrzeit musst du stndig auf den Reload-Button klicken.
Ist PHP dafr gedacht, um stndig die ganz aktuelle Uhrzeit auszugeben?
Und zwar sekundengenau? Die Antwort lautet: Nein! Denn dann msste
das Skript im Sekundentakt immer wieder aufgerufen werden. Die Seite
msste also sechzigmal pro Minute vom Server abgerufen und an den
Browser geschickt werden. Das ist nicht Sinn der Sache, denn dann wre
der Arbeitsaufwand (die Last) fr den Server zu gro. Fr solche Auf-
gaben bietet sich dagegen die Skriptsprache JavaScript an. Diese luft
schlielich direkt im Browser.
Pause muss sein: Die if-else-
Entscheidungsstruktur
Wenn, ja wenn das Wrtchen wenn nicht wr Dann wr das Leben nur
halb so schwer. Stoen deine Eltern, Tanten oder Bekannten auch manch-
mal solche hilflosen Drohungen aus wie: Wenn du nicht gleich dein Zim-
mer aufrumst, gibt es kein Fernsehen oder Wenn du nicht sofort deine
Hausaufgaben machst, darfst du nicht runter auf die Strae?
Egal ob unerfreuliche Gegenwart oder dstere Vergangenheit. In diesem
Buch sehen wir alles von der optimistisch-heiteren Seite! Glaube es oder
nicht: Mit diesen Beweisen erzieherischer Intoleranz haben dir deine
Erzeuger ganz unbewusst wertvollen Anschauungsunterricht zur Informatik
erteilt. Es geht um die Entscheidungsstrukturen.
Die Entscheidungsstruktur if-else
Nehmen wir doch einmal das Fernseh-Beispiel. Formulieren wir es streng
logisch: Wenn du dein Zimmer aufrumst, gibt es Fernsehen, sonst gibt es
kein Fernsehen.
117
Pause muss sein: Die if-else-Entscheidungsstruktur

Die dazugehrige Schreibweise in der Programmiersprache PHP sieht fol-
gendermaen aus die Betonung liegt hierbei auf wenn und sonst:
Wenn (Zimmeraufrumen) {
Fernsehen;
} sonst {
kein Fernsehen;
}

Zugegeben, in der Programmiererei spricht man Englisch. Aus wenn wird
if und aus sonst else. Und da man beim Programmieren schlecht mit
Fernsehen und kein Fernsehen arbeiten kann, fassen wir es allgemeiner.
Nennen wir die beiden Flle Fall A und Fall B. Dann sieht unser Grundgerst
folgendermaen aus:
if (Bedingung) {
Fall A;
} else {
Fall B;
}

Mit anderen Worten: Es wird eine Bedingung geprft. Wenn diese Bedin-
gung wahr ist, tritt Fall A in Kraft. Sonst also wenn die Bedingung nicht
wahr ist fhrt das Programm Fall B aus.
brigens kann der sogenannte else-Zweig auch weggelassen werden.
Dann sieht die if-Konstruktion vom Schema her so aus:
if (Bedingung) {
Fall A;
}

Es gengt also, ganz einfach die Bedingung zu prfen. Von der Logik her
macht das Sinn. Auch beim Fernseh-Beispiel wei Tochter oder Sohn
ganz genau was ihr oder ihm blht, wenn er das Zimmer nicht aufrumt.
Geschweifte Klammern: Wichtiges Know-how
Sicher fllt dir schon an diesem Beispiel ein interessantes Detail ins Auge.
Zusammengehrende Ausdrcke wie bei diesen if-Strukturen werden in
PHP in der Regel durch ein Paar geschweifter Klammern zusammengehal-
ten { }. Dadurch fasst du diese Ausdrcke zu einem sogenannten Block
118
Spa mit Datum und Uhrzeit

Kapitel
4
zusammen. Dabei gilt: Die Zeile mit der Klammer wird ausnahmsweise
nicht mit einem Semikolon abgeschlossen.
if (Bedingung) {

Ich empfehle dir sehr die von mir verwendete Schreibweise: Schau dir das
Beispiel an. Die ffnende geschweifte Klammer setzt du direkt nach einem
Leerzeichen an das Ende der Zeile. So wirst du auch besser daran erinnert,
an dieser Stelle kein Semikolon zu setzen.
Der schlieenden geschweiften Klammer spendierst du dagegen eine eige-
ne Zeile. Auch hier ist kein Semikolon erlaubt:
}

Ich habe noch einen ganz heien Tipp fr dich: Immer wenn ich eine ff-
nende geschweifte Klammer schreibe, setze ich sofort das Gegenstck.
Egal, wie viele Codezeilen ich spter noch dazwischen schreiben muss.
Warum? So habe ich immerhin schon einmal den Block geschlossen. Denn
das Vergessen einer schlieenden Klammer ist eine hufige Fehlerursache!
Mit meinem Trick ersparst du dir oft stundenlanges Suchen. Hier noch ein-
mal in Kurzform: Wenn du eine ffnende Klammer schreibst, drckst du ein
paar Mal auf [Enter] und notierst danach die schlieende Klammer.
Sicher hast du es lngst bemerkt: Passagen innerhalb von geschweiften
Klammern werden eingerckt. Dabei tippst du vor den einzurckenden
Zeilen 24 Leerzeichen. Mehr zu den Einrckregeln erfhrst du in einer
PDF-Datei auf der Buch-CD unter dokumente/code_einrueckung und
ganz ausfhrlich auch im Nachfolgeband PHP und MySQL Praxisbuch
fr Kids im Kapitel 2.
Wir machen Mittagspause
Grau ist alle Theorie (und zwar selbst bei Farbfernsehen). Deshalb machen
wir gemeinsam eine Pause eine Mittagspause! Und damit es auch alle
Besucher deiner Website merken, teilst du es ihnen einfach mit.
Das folgende Beispiel soll zwischen 12:00 Uhr und 13:00 Uhr (genauer
zwischen 12:00 Uhr und 12:59 Uhr und 59 Sekunden) den Text anzeigen:
Wir machen Mittagspause. Ansonsten soll der Text Willkommen auf
unserer Seite erscheinen. Wie geht das? Ganz einfach! Du brauchst ledig-
lich die Funktion date() mit dem Schalter H. Schlielich verrt dir
date("H") ganz genau, was die Stunde geschlagen hat.
119
Pause muss sein: Die if-else-Entscheidungsstruktur

Hier mein Musterbeispiel, welches ich pause.php nenne. Ich zeige dir den
wichtigsten Teil der Datei:
<h3>Pause zwischen 12:00 und 13:00 Uhr!</h3>
<p>
<?php
if (date("H") == 12) {
echo "Wir machen Mittagspause.";
} else {
echo "Willkommen auf unserer Seite!";
}
?>
</p>


Du kannst gerne mit dem Musterbeispiel von der Buch-CD vergleichen.
Schaue in den Ordner kapitel04.
So funktioniert das Beispiel
Jetzt schauen wir uns die Funktionsweise dieses Beispiels einmal genauer
an. Zuerst schreibst du das Schlsselwort if und tippst ein Leerzeichen. In
den runden Klammern wird nun die Bedingung auf ihren Wahrheitswert
berprft. Die Funktion date("H") ist dir vertraut, doch was hat das dop-
pelte Gleichheitszeichen an dieser Stelle verloren?
Das doppelte Gleichheitszeichen (==) ist der sogenannte Vergleichsope-
rator. Aus dem Mathematikunterricht kennst du das einfache Istgleich.
Das gibt es in PHP auch, wie ich dir im vorigen Kapitel bewiesen habe.
Das einfache Istgleich (=) ist jedoch nur der Zuweisungsoperator. Mit
$vorname = "Katja"; hast du der Variablen $vorname z. B. den String
Katja zugewiesen. Damit es nicht zu Verwechslungen kommt, hat man
als Vergleichsoperator in PHP deshalb das doppelte Istgleich (==) ge-
whlt. Achtung aufgepasst! Verwechsle die beiden Operatoren deshalb
auf keinen Fall, du musst zum Vergleichen unbedingt das doppelte Ist-
gleich (==) verwenden!
Zwischen Zwlf und
Eins macht jeder seins
Mittagspause!
120
Spa mit Datum und Uhrzeit

Kapitel
4
Der Vergleich liest sich also so: Wenn es wahr ist, dass die Uhrzeit der Zahl
12 entspricht, dann wird die nchste Zeile ausgefhrt. Diese Zeile macht
nichts weiter, als den Text Wir machen Mittagspause auszugeben. Tipp:
Falls es bei dir zufllig nicht gerade 12 Uhr ist, kannst du diesen Wert pro-
beweise verndern. (Oder du stellst einfach mal die Uhr deines PCs um.)
Wenn dieser Vergleich jedoch nicht wahr ist? Dann wird der else-Zweig
ausgefhrt. Und dieser gibt lediglich den Satz Willkommen auf unserer
Seite! aus. Eigentlich ganz einfach, oder?
Beachte unbedingt die korrekte Klammersetzung. Wir haben es in diesem
Beispiel mit zwei Blcken zu tun. Zum einen mit dem if-Block, zum ande-
ren mit dem else-Block.
Wie wichtig die richtige Klammersetzung ist, kannst du durch ein Expe-
riment feststellen. Entferne doch zur Probe einmal die Klammer hinter
else. Bei mir ist das in Zeile 15. Nach dem erneuten Aufruf der Seite im
Browser bekommst du eine Fehlermeldung. Diese weist jedoch auf Zeile
17 hin. Klar, denn PHP wusste ja nicht, dass du in Zeile 15 einen Block
ffnen wolltest. Das Programm meckert deshalb die schlieende Klam-
mer in Zeile 17 an! Falls es bei dir fter zu solchen Problemen kommt,
empfehle ich dir noch einmal die heien Hundetipps von den Vorseiten:
Setze zur ffnenden geschweiften Klammer stets sofort das schlieende
Pendant! brigens: Gute Editoren wie PSPad, Notepad++ oder Aptana
Studio heben die dazugehrige schlieende Klammer farblich hervor, so-
bald du die ffnende markierst! Achte einmal darauf!
Vergleichsoperatoren im berblick
Kompliziert? Eigentlich nicht! Mit dem doppelten Istgleich testet man auf
Gleichheit. Das ist jedoch noch nicht alles. Hchste Zeit, dass ich dir nun
auch die anderen Vergleichsoperatoren zeige.
Operator Bedeutung
== Gleich
!= Ungleich
> Grer als
< Kleiner als
>= Grer gleich
<= Kleiner gleich

Diese sechs Operatoren sind relativ einfach zu verstehen. Den Gleich-
heitsoperator hast du schon kennengelernt, das doppelte Istgleich.
121
Pause muss sein: Die if-else-Entscheidungsstruktur

Du kannst jedoch auch prfen, ob zwei Elemente ungleich sind. So ist 12
ungleich 13. Du kannst auch testen, ob das erste Element grer oder klei-
ner als das zweite ist. Die 13 ist z. B. grer als die 12.
Oder du prfst, ob gilt: Das erste Element ist grer gleich bzw. kleiner
gleich dem zweiten Element. Die 12 ist grer gleich 12. Damit ergeben
sich sehr interessante Einsatzmglichkeiten. Zum Beispiel fr eine etwas
lngere Mittagspause?
Apropos Mittagspause. Angenommen, du machst zwischen 11:00 und
13:00 Uhr eine Brotzeit. Wie baust du diesen Tatbestand in den Vergleich
ein? Nichts leichter als das! Schreibe einfach zwei Vergleiche und verknp-
fe diese miteinander. Beide Teilausdrcke mssen wahr sein. Moment mal,
verknpfen? Wie geht das denn? Da kommen uns die nchsten Operatoren
doch wie gerufen!
Na logo! Logische Operatoren zum Verknpfen
Zum Verknpfen von Vergleichen bentigst du die sogenannten logischen
Operatoren. Hier stehen dir die folgenden zwei Operatoren zur Verfgung:
Operator Bedeutung
&& bzw. and Logisches Und, alle Teilausdrcke mssen wahr sein
|| bzw. or Logisches Oder, mindestens ein Teilausdruck muss wahr sein

Wundere dich nicht, dass es zwei Schreibweisen gibt. Ich zeige dir beide,
damit du auch mit der jeweils anderen Schreibweise vertraut bist. Ich je-
doch bevorzuge fr das logische Und das doppelte kaufmnnische Und
(&&). Beim logischen Oder empfehle ich dir die zwei senkrechten Striche,
die Pipe-Zeichen (||).
Wie erzeugst du die Pipe-Zeichen? Kein Problem! Halte die Taste [AltGr]
gedrckt. Tippe dann die zweite Taste von links in der zweiten Reihe von
unten. Die mit den spitzen Klammern, die Taste [<]!
Lange Mittagspause per Und-Verknpfung
Doch jetzt probieren wir diese Operatoren ganz schnell einmal aus! Es ging
schlielich um unsere lange Mittagspause. Hier das Skript, welches ich
und.php getauft habe.
<h3>Pause zwischen 11:00 und 13:00 Uhr!</h3>
<p>
<?php
122
Spa mit Datum und Uhrzeit

Kapitel
4

if (date("H") >= 11 && date("H") < 13) {
echo "Wir machen Mittagspause.";
} else {
echo "Willkommen auf unserer Seite!";
}
?>
</p>

Interessant ist vor allem die vierte Zeile. Hier habe ich zwei Bedingungen
mit dem Und-Operator (&&) miteinander verknpft. Nur wenn beide Teil-
ausdrcke wahr sind, wird der Satz Wir machen Mittagspause ausgege-
ben. Beide Teilausdrcke? Richtig!
Es muss zum einen wahr sein, dass die Stunde grer oder gleich 11 ist.
Damit wren zuerst einmal 11, 12, 13 usw. zugelassen. Der nchste Teilaus-
druck beschrnkt den Bereich jedoch auf alle Werte unter 13. Hier wird
verlangt, dass die Stunde kleiner 13 ist.
Mit anderen Worten: Nur wenn die Stundenzahl zwischen 11 und 13 liegt,
ist die Bedingung wahr. Um noch genauer zu sein: Die Zeitspanne muss
zwischen 11:00 Uhr und 12:59 Uhr liegen, da die 13 selber nicht erreicht
werden darf. Probiere es aus!
Wo gibts denn so was? Zwei Pausen am Tag!
Fehlt zum Schluss noch die Oder-Verknpfung. Diese sorgt schlielich da-
fr, dass mindestens ein Teilausdruck wahr sein muss. Was kompliziert er-
scheint, wird mit dem nchsten Beispiel sicher ganz einfach!
Nehmen wir unser Mittagspausen-Beispiel. Wie wre es mit zwei Mit-
tagspausen? Die eine recht frh von 11:00 bis 11:59 Uhr. Die andere dage-
gen von 14:00 bis 14:59 Uhr, praktisch als Siesta. Da hilft folgende Ver-
gleichs-Konstruktion.
if (date("H") == 11 || date("H") == 14) {
echo "Wir machen Mittagspause.";
}

Dank des Oder-Operators zeigt die Seite den Mittagspausen-Satz nun in
den oben genannten zwei Zeitfenstern an. Zum einen, wenn es zwischen
11:00 und 11:59 Uhr ist; zum anderen aber auch dann, wenn der Zeiger
zwischen 14:00 und 14:59 pendelt. Vergleiche mit der Datei oder.php,
wo ich diese nderung eingebaut habe.
123
Der Tag vergeht: Zwischentne mit elseif

Der Tag vergeht: Zwischentne
mit elseif
Eltern haben ja manchmal Phantasie. Sie versuchen, Tochter oder Sohn
durch unterschiedliche Vergtungsmodelle zu motivieren. Nehmen wir
zum Beispiel das Taschengeld.
Wenn du sofort das Zimmer aufrumst, wird das mit 3 Euro Taschengeld
honoriert. Rumst du das Zimmer dagegen spter auf, gibt es immerhin
noch 2 Euro. Wenn du das Zimmeraufrumen jedoch vergisst, gibt es ber-
haupt kein Taschengeld.
Auch mit diesem Modell haben uns unsere Erzeuger wieder eine wunderba-
re Informatik-Lektion erteilt! Um das Beispiel darzustellen, mssen wir
unsere if-else-Konstruktion um einen weiteren Zweig ergnzen.
Einbau eines elseif-Zweigs
Und schon sind wir beim sogenannten elseif-Zweig angelangt. Der
elseif-Zweig ist immer dann interessant, wenn man mehrere konkrete
Flle voneinander unterschieden mchte. Das Taschengeld-Beispiel lsst
sich folgendermaen symbolisieren:
if (Zimmeraufrumen sofort) {
3 Euro Taschengeld;
} elseif (Zimmeraufrumen spter) {
2 Euro Taschengeld;
} else {
kein Taschengeld;
}

Ziemlich praktisch und raffiniert, findest du nicht?
Dabei knnen sogar noch mehr elseif-Zweige eingebaut werden. Der
nchste elseif-Zweig wird nur ausgefhrt, wenn die Prfung im ber-
geordneten Zweig nicht wahr war. Also wenn das if oder elseif nicht
zum Erfolg gefhrt hat. Auch hier gilt: Der else-Zweig ganz am Schluss
kann wieder weggelassen werden.
124
Spa mit Datum und Uhrzeit

Kapitel
4
Tageszeitabhngige Begrung
Wie wre es mit einem sinnvollen Beispiel? Schreibe doch einmal ein
Skript, welches die Besucher je nach Uhrzeit mit einem anderen Spruch
begrt.
Von 0:00 Uhr bis 10:59 Uhr soll die Begrung lauten: Guten Morgen!.
Von 11:00 Uhr bis 14:59 Uhr dagegen Mahlzeit!. Bis 16:59 Uhr schlage
ich Willkommen zur Kaffeezeit! vor. Ansonsten (also wenn keiner der
obigen Flle zutrifft), soll das Skript Guten Abend einblenden.
Das ist ein Fall fr elseif, und zwar gleich in doppelter Verpackung.
Schau dir mein Beispiel an, ich zeige dir wieder den wichtigen Teil zwi-
schen <body></body>. Ich habe das Dokument willkommen.php ge-
nannt.
<p>
<?php
if (date("H") < 11) {
echo "Guten Morgen!";
} elseif (date("H") < 15) {
echo "Mahlzeit!";
} elseif (date("H") < 17) {
echo "Willkommen zur Kaffeezeit!";
} else {
echo "Guten Abend!";
}
?>
</p>



Auch hier noch ein interessantes Syntax-Detail: Wenn du mit else oder
elseif arbeitest, notierst du dieses Schlsselwort und die dazugehrige
ffnende geschweifte Klammer am besten in der gleichen Zeile wie die
schlieende geschweifte Klammer des vorhergehenden Blocks. Das spart
Platz und erhht die bersicht.
Mahlzeit! Mit elseif
wird die Entschei-
dungsstruktur
erweitert.
125
Feldvariablen: Wochentage aufschreiben

Feldvariablen: Wochentage
aufschreiben
Zurck zur Funktion date(), zurck zu den Wochentagen. Blttere ruhig
ein paar Seiten zurck und schaue dir die Tabelle an. Wenn du den Wo-
chentag als Namen ermitteln mchtest, verwendest du den Schalter l:
date("l")

Die ganze Sache hat einen Haken: Der Wochentag wird in Englisch ausge-
geben, in der Schreibweise Sunday, Monday, Tuesday usw. Fr pfiffige eng-
lischkundige Schler und Fachbuchautoren ist das kein Problem. Doch ob
Otto Normalsurfer immer die englischen Wochentage kennt?
Es wre doch schn, wenn man die Wochentage auf Deutsch anzeigen
knnte!
Wochentage auf Deutsch ausgeben
Richtig! Man knnte fr jeden Wochentag eine eigene Variable verwenden!
Dann knnte man eine if-else-Kontrollstruktur schreiben, die aus
Monday Montag, aus Tuesday Dienstag usw. macht.
Es geht aber auch anders! Warum eine Variable fr jeden Tag? Eine Variable
fr alle Tage ist viel besser! Eine sogenannte Feldvariable, ein Array!
Wenn man mehr als einen Wert in einer Variablen speichern mchte,
kommen die sogenannten Feldvariablen ins Spiel. Eine Feldvariable bildet
ein Feld zusammengehriger Elemente. Stelle es dir vor wie eine Fu-
ballmannschaft oder wie die Schulklasse. Die Feldvariable ist der 1. FC
Pokalsieg oder die Klasse 8c. Die einzelnen Elemente sind die Spieler
bzw. Schler der Klasse.
Feldvariablen werden Array genannt
Feldvariablen werden auch als Arrays bezeichnet, als Werteliste. Das Wort
Array betonst du auf der letzten Silbe. Das A am Anfang wird kurz ge-
sprochen. Die Syntax wiederum sieht folgendermaen aus:
$Variablenname[Index-Wert]
126
Spa mit Datum und Uhrzeit

Kapitel
4
Im Klartext: Zuerst notierst du den Variablennamen wie gewohnt. Dann
setzt du ohne Leerzeichen ein paar eckige Klammern. Doch wie unterschei-
det man die einzelnen Elemente voneinander? Wie macht man kenntlich,
dass es sich um Fuballspieler 1 oder Schler 5 handelt?
Das leistet der sogenannte Index-Wert. Dieser wird in eckigen Klammern
notiert. Der Index-Wert ist eine Art Zhler zur Durchnummerierung! Er wird
auch als key (Schlssel) bezeichnet.
Ganz wichtig: Der erste Wert in einem Array trgt per Voreinstellung die
Schlssel-Nummer 0. Der erste Index-Wert lautet also 0 und nicht 1.
Weil das so wichtig ist, wiederhole ich es noch einmal: In einem Array
beginnt die Zhlung bei 0. Der 8. Spieler der Fuballmannschaft wrde
also den Index-Wert 7 tragen!
Fassen wir zusammen: Arrays, die Wertelisten, bestehen aus mehreren
Werten. Diese werden von PHP intern durchnummeriert. Der entsprechende
Zhler nennt sich Index-Wert oder auch Schlssel (key). Der key (Zhler)
beginnt in der Voreinstellung stets bei 0.
Die Tage als Array
Zurck zu unseren Wochentagen! Schau dir die Sache am Beispiel an! Die
Variable selbst nennen wir $tag. Die einzelnen Wochentage werden durch-
nummeriert. Wir fangen beim Sonntag an. Der Sonntag bekommt die 0 (bei
0 beginnen!) und wird so notiert: $tag[0]. Der Montag sieht so aus
$tag[1] usw. usf.
Liste einfach alle Tage auf und weise die entsprechenden Werte zu. Als Test
gibst du den Donnerstag mit der Sprachanweisung echo aus. Ich habe
mein Dokument wochentage.php genannt. Ich zeige dir hier den PHP-Teil.
<?php
$tag[0] = "Sonntag";
$tag[1] = "Montag";
$tag[2] = "Dienstag";
$tag[3] = "Mittwoch";
$tag[4] = "Donnerstag";
$tag[5] = "Freitag";
$tag[6] = "Samstag";
// Donnerstag ausgeben
echo $tag[4];
?>
127
Feldvariablen: Wochentage aufschreiben

Beachte, dass ich hier mit einem Kommentar arbeite (Zeichen //), um das
Skript direkt im Quellcode erlutern zu knnen.

Da Sonntag Tag 0 ist, muss der Donnerstag Tag 4 sein.
Welcher Tag ist heute?
Das bisherige Skript reit dich sicher nicht gerade zu Begeisterungsstrmen
hin. Mich auch nicht! Um lediglich das Wort Donnerstag auszugeben, ht-
ten wir uns den Stress mit dem Array auch ersparen knnen. Viel interes-
santer ist der heutige Wochentag, als der Tag, an dem du das Buch liest.
Wie ermittelst du mit PHP den Wochentag? Ganz einfach: Dafr sorgt die
Funktion date() im Zusammenspiel mit dem Schalter w: date("w"). Das
Schne an date("w") ist, dass am Sonntag 0 und am Samstag 6 zurck-
gegeben wird. Was fr ein Zufall, denn das passt ganz hervorragend fr
unsere Zwecke. Schlielich beginnt die Zhlung bei Arrays ja auch bei 0!
Mit dem folgenden Skript kannst du den aktuellen Wochentag auf Deutsch
dynamisch im Dokument ausgeben. Vergleiche einfach mit der Datei
heute.php aus dem Ordner kapitel04.
<?php
$tag[0] = "Sonntag";
$tag[1] = "Montag";
$tag[2] = "Dienstag";
$tag[3] = "Mittwoch";
$tag[4] = "Donnerstag";
$tag[5] = "Freitag";
$tag[6] = "Samstag";
$tagnummer = date("w"); // Tag ermitteln
echo "Heute ist " . $tag[$tagnummer] . ".";
?>

Das Prinzip ist einfach! Ich ermittle die tagnummer mit Hilfe der Funktion
date("w") und speichere sie in der gleichnamigen Variablen. Diese Zahl
bergebe ich der Feldvariablen $tag[] in den eckigen Klammern. Heraus
kommt der aktuelle Wochentag.
128
Spa mit Datum und Uhrzeit

Kapitel
4 Arrays die Zweite: Es geht auch
krzer!
Bei der bisherigen Array-Schreibweise handelt es sich um die sogenannte
Langform. Da Programmierer faul sind, mgen sie besonders die alternati-
ven Kurzformen. Die sieht fr das Wochentage-Array folgendermaen aus:
<?php
$tag = array("Sonntag", "Montag", "Dienstag", "Mittwoch",
"Donnerstag", "Freitag", "Samstag");
$tagnummer = date("w"); // Tag ermitteln
echo "Heute ist " . $tag[$tagnummer] . ".";
?>

Nach dem Schlsselwort array folgt die Werteliste. Diese notierst du in
runden Klammern. Jeder Wert wird vom nchsten durch ein Komma ge-
trennt. Da es sich um Strings handelt, notierst du die Tage selbstverstnd-
lich in Gnsefchen.
Beachte, dass es sich trotz des Umbruchs im Buch um eine Zeile handelt!
Wenn du aus Platzgrnden ebenfalls einen Umbruch einbauen mchtest,
dann nur nach einem Komma. Zerreie keinesfalls Text, der innerhalb
von Gnsefchen notiert wurde.
Das Komma hat eine besondere Bedeutung. Alle Werte werden durch
Komma voneinander getrennt. Die Zuweisung der keys (Index-Werte) er-
folgt dabei automatisch hintereinander. Du musst sie nicht extra notieren.
Das Beispiel findest du unter dem Namen heutekurz.php.
Array-Elemente zhlen
Wie viele Tage hat die Woche? Wie viele Schler befinden sich in deiner
Klasse? Zhle die Array-Elemente doch einfach einmal durch! Stelle es fest
mit der Funktion count().
Und wie geht das nun mit count()? Die Funktion funktioniert ganz ein-
fach: In runden Klammern bergibst du Namen des Arrays. Und zwar ohne
irgendwelche eckigen Klammern. Schlielich beziehst du dich nicht auf ein
einziges Element. Das gesamte Array wird ausgewertet.
129
Assoziativ: Monatsnamen als Array

<?php
$tag = array("Sonntag", "Montag", "Dienstag", "Mittwoch",
"Donnerstag", "Freitag", "Samstag");
$tagnummer = date("w"); // Tag ermitteln
echo "Heute ist " . $tag[$tagnummer] . ".<br>\n";
$elementzahl = count($tag);
echo "Die Woche hat $elementzahl Tage.\n";
?>

Du findest das Beispiel zum Vergleich unter dem Namen count.php.

Keine Bange, die Funktion count() zhlt korrekt. Du musst dir also kei-
ne Sorgen machen, dass der Index-Wert 0 irgendeinen Einfluss hat.
Wenn die Fuballmannschaft ein Array darstellen wrde, bekme der elf-
te Spieler zwar den Index-Wert 10. Trotzdem wrde beim Zhlen mit
count() natrlich korrekt die 11 ermittelt.
Assoziativ: Monatsnamen als Array
Das mit den Arrays ist eine ganz feine Sache. Gewiss. Doch nicht immer
sind diese Index-Nummern der Weisheit letzter Schluss. Nehmen wir als
Beispiel ein paar europische Stdte. Diese sollen in einem Array namens
$hauptstadt festgehalten werden. Nach der klassischen Index-Variante
sieht das folgendermaen aus:
$hauptstadt[0] = "Berlin";
$hauptstadt[1] = "Wien";
$hauptstadt[2] = "Warschau";
$hauptstadt[3] = "Paris";

Doch unter $hauptstadt[1] kannst du dir sicher nicht viel vorstellen. Du
musst dir halt merken, dass sich dahinter Wien verbirgt. Je mehr Haupt-
stdte das Array enthlt, desto komplizierter wird die ganze Geschichte.
Die Funktion count()
zhlt die Elemente
eines Arrays.
130
Spa mit Datum und Uhrzeit

Kapitel
4
Logisch, denn unter nackten Zahlen kann sich ein Normalsterblicher von
ein paar Mathematik-Genies abgesehen wenig vorstellen. Anders ausge-
drckt: Mit bloen Zahlen kann man wenig verbinden, wenig assoziieren.
Viel praktischer ist es, wenn man diese Index-Nummern einfach durch ei-
gene Werte ersetzt. Durch Werte, mit denen man etwas assoziieren kann.
Was liegt bei Hauptstdten nher, als die im Web gebruchliche Lnder-
kennung zu verwenden? In unserer assoziativen Variante sieht das Array
folgendermaen aus:
$hauptstadt["DE"] = "Berlin";
$hauptstadt["AT"] = "Wien";
$hauptstadt["PL"] = "Warschau";
$hauptstadt["FR"] = "Paris";

In assoziativen Arrays wird als key statt der Index-Nummer ein ganz ei-
genes Schema erzeugt. Dieses darfst du dir (fast) frei ausdenken. Es kann
sich bei diesen Ersatz-Schlsseln um Strings aber auch um Zahlen
handeln. Der key in assoziativen Arrays wird von Ausnahmen abgese-
hen innerhalb von Gnsefchen notiert.
Einen einzelnen Index-Wert ausgeben
Du mchtest einen einzelnen Index-Wert ausgeben? Kein Problem! Das
Prinzip ist genau das gleiche wie bei den klassischen Arrays mit Zahlen
als Index-Wert. Als zustzlichen Test kannst du gleich noch die Elemente
im Array durchzhlen. Auch hier arbeitet count() wie gewohnt.
Hier zeige ich dir den wichtigsten Teil meiner PHP-Datei haupt-
stadt.php.
<p>
<?php
$hauptstadt["DE"] = "Berlin";
$hauptstadt["AT"] = "Wien";
$hauptstadt["PL"] = "Warschau";
$hauptstadt["FR"] = "Paris";
echo "Polen: " . $hauptstadt["PL"] . "<br>\n";
echo "Elemente im Array: " . count($hauptstadt);
?>
</p>
131
und wieder die Kurzform


Bei assoziativen Arrays kannst du dir den Schlssel frei ausdenken.
Die Wirkungsweise ist klar? In der ersten echo-Zeile ist eigentlich nur die
Ausgabe von $hauptstadt["PL"] interessant. Damit daraus aber eine
ganze Wortgruppe wird, verknpfe ich den String Polen: mit
$hauptstadt["PL"]. Am Schluss sorgt ein Zeilenumbruch <br> dafr,
dass die nchste Zeile auch auf einer neuen Zeile steht. Und das Zeichen
\n kmmert sich darum, dass auch im Quelltext ein Zeilenumbruch erfolgt.
In der nchsten Zeile zhle ich die Elemente des Arrays durch.
und wieder die Kurzform
brigens gibt es auch bei den assoziativen Arrays eine Lang- und eine
Kurzform. Auch bei dieser Kurzform arbeitet man mit runden Klammern.
Davor notierst du wieder das Schlsselwort array.
Zustzlich kommt jedoch das Zeichen Daraus folgt zum Einsatz. Das sieht
so aus: =>. Zum Vergleich zeige ich dir hier die Kurzform des obigen Bei-
spiels:
<p>
<?php
$hauptstadt = array("DE" => "Berlin", "AT" => "Wien",
"PL" => "Warschau", "FR" => "Paris");
echo "Polen: " . $hauptstadt["PL"] . "<br>\n";
echo "Elemente im Array: " . count($hauptstadt);
?>
</p>

Die lange Array-Zeile liest sich wie folgt: Key DE daraus folgt Berlin, Key
AT daraus folgt Wien usw. usf. Vergleich mit der Datei hauptkurz.php.
132
Spa mit Datum und Uhrzeit

Kapitel
4 Den Monat ausgeben
Zurck zu unserem Datums-Beispiel. Wir wollen diesmal den aktuellen
Monat komplett auf Deutsch ausgeben. Damit es bersichtlich bleibt, setze
ich ein assoziatives Array in der Langform ein:
Als Schlssel verwende ich die ausgeschriebenen englischen Monatsnamen.
Warum? Weil die Funktion date("F") schlielich die Monatsnamen aus-
geschrieben ermittelt. Dann brauche ich diesen englischen Monatsnamen
nur noch in der Variablen $monatsname zu speichern. Diesen nutze ich als
Key. Und schon habe ich den deutschen Monatsnamen.
Hier das entsprechende Skript:
<p>
<?php
$monat["January"] = "Januar";
$monat["February"] = "Februar";
$monat["March"] = "Mrz";
$monat["April"] = "April";
$monat["May"] = "Mai";
$monat["June"] = "Juni";
$monat["July"] = "Juli";
$monat["August"] = "August";
$monat["September"] = "September";
$monat["October"] = "Oktober";
$monat["November"] = "November";
$monat["December"] = "Dezember";
$monatsname = date("F"); // engl. Monatsnamen ermitteln
echo "Wir haben " . $monat[$monatsname] . ".<br>\n";
echo "Das Jahr hat " . count($monat). " Monate.";
?>
</p>


Vergleiche mit der Datei monatsnamen.php im Ordner kapitel04.
Die Monatsnamen
werden durch ein
assoziatives Array
bersetzt.
133
Schlussbemerkung

Schlussbemerkung
Nicht schlecht, Herr Specht: Du hast dich ein gutes Stck qualifiziert auf
dem Weg zum richtigen Programmierer: Schlielich zhlen die Entschei-
dungsstrukturen und die Arrays zu den wichtigsten Programmiergrundla-
gen. Und das Spielen mit Datum und Uhrzeit hat hoffentlich ein wenig
darber hinweggetrstet, dass der Stoff nicht immer ganz einfach ist.
Zusammenfassung
0 Du weit, dass du mit der Funktion date() das Datum ermitteln
kannst. Mit den richtigen Schaltern und mit Formatierzeichen wie
Punkt oder Leerzeichen gelingt fast jede gewnschte Ausgabe. Fr Tag
und Monat ohne fhrende Null und das Jahr mit zwei Stellen schreibst
du z. B. echo date("j.n.y");
0 Auch die Uhrzeit kann mit der Funktion date() ganz einfach ermittelt
werden. Wenn du die Stunden, Minuten und Sekunden anzeigen mch-
test, schreibst du z. B.: echo date("H:i:s");
0 Du hast die if-else-Entscheidungsstruktur kennengelernt. Es wird
eine Bedingung auf Wahrheit geprft. Wenn diese Bedingung wahr ist,
tritt Fall A in Kraft. Sonst also wenn die Bedingung nicht wahr ist
fhrt das Programm Fall B aus:
if (Bedingung) {
Fall A;
} else {
Fall B;
}


0 Du kennst die wichtigsten Vergleichsoperatoren wie das Istgleich (==),
die Zeichen Grer als (>), Kleiner als (<) und Grer gleich (>=) und
Kleiner gleich (<=).
0 Du kennst die logischen Operatoren Und (&&) bzw. Oder (||), mit denen
du mehrere Vergleiche miteinander verknpfen kannst. Beim logischen
Und mssen alle Teilausdrcke wahr sein. Beim logischen Oder muss
dagegen mindestens ein Teilausdruck wahr sein.
134
Spa mit Datum und Uhrzeit

Kapitel
4
0 Du kennst den elseif-Zweig, mit dem mehrere Bedingungen hinter-
einander geprft werden knnen. Der nchste elseif-Zweig wird nur
ausgefhrt, wenn die Prfung im bergeordneten Zweig nicht wahr war.
0 Du hast dich mit dem Konzept der Feldvariablen vertraut gemacht, der
sogenannten Arrays. Eine Feldvariable bildet ein Feld zusammengeh-
riger Elemente. Indizierte Arrays besitzen als Schlssel einen Zhler, der
normalerweise bei Null anfngt zu zhlen. So wird das erste Element
des Arrays $tag so definiert: $tag[0];
0 Du weit, dass es neben den indizierten Arrays auch die sogenannten
assoziativen Arrays gibt. Dabei wird der Nummern-Schlssel durch eine
selbst whlbare Zeichenfolge ersetzt. Nimm Zeichenfolgen, mit denen
du etwas assoziieren kannst. So wre $hauptstadt["DE"] =
"Berlin"; eine gute Mglichkeit, die Hauptstadt von Deutschland zu
speichern.
0 Du weit, dass es bei Arrays eine Lang- und eine Kurzform gibt. Bei der
Kurzform werden die einzelnen Array-Elemente in runden Klammern
zusammengefasst. Vorangestellt wird das Schlsselwort array. Bei as-
soziativen Arrays musst du zustzlich mit dem Zuweisungsoperator =>
(Daraus folgt) arbeiten.
0 Du kennst die Funktion count(), mit der sich die Elemente eines Arrays
zhlen lassen.
Ein paar Fragen
1. Mit welcher Funktion kannst du Datum und Uhrzeit darstellen? Nenne
nur die Funktion ohne Schalter oder Formatierzeichen.
2. Was bedeutet if-else und wofr brauchst du diese Schlsselworte?
3. Welches Zeichen verwendet man, wenn man zwei Elemente auf Gleich-
heit testen will?
4. Wie sieht der Vergleichsoperator aus, der auf Ungleichheit prft?
5. Mit welcher Zahl beginnt die Zhlung bei indizierten Arrays?
6. Mit welcher Funktion kannst du die Elemente eines Arrays zhlen?
135
und ein paar Aufgaben

und ein paar Aufgaben
1. Schreibe ein PHP-Dokument, welches einen Satz nach diesem Muster
ausgibt: Heute ist Tag 5 des 3. Monats in 2009. Dabei sollen natrlich
der aktuelle Tag, der aktuelle Monat und das aktuelle Jahr eingesetzt
werden. Speichere das Dokument unter dem Namen heuteist.php.
2. Spa muss sein. Erzeuge eine Seite, die den Surfer an allen Werktagen
normal begrt. Nur am Sonntag soll der Text ausgegeben werden: Am
Sonntag ist das Internet leider geschlossen. Nenne das Dokument
sunday.php. (Tipp: Nutze die Entscheidungsstruktur fr diesen Zweck.)
3. Erstelle ein Dokument, welches das Datum in folgender freundlicher
Schreibweise ausgibt: Heute ist Mittwoch, der 11. Februar 2011. (Ge-
meint ist das zum Zeitpunkt des Lesens aktuelle Datum!) Im Klartext:
Sowohl der Wochentag als auch der Monatsname sollen in der deut-
schen Schreibweise ausgegeben werden. Der Dateiname soll
tagmonat.php heien.
137



5
Seiten mit Passwort
schtzen
Webseiten so sicher wie die Bank von England? Solange es Hacker gibt,
wird das wohl immer ein Traum bleiben. Doch etwas Sicherheit ist mglich:
Erzeuge einen Passwortschutz, der zumindest von Normalsterblichen
schwer zu knacken sein wird. Sorge dafr, dass bestimmte Informationen
nur nach Eingabe eines Passwortes angezeigt werden. Schlielich stehen
die Passwrter selber im PHP-Code, werden also dem Betrachter nicht an-
gezeigt.
Beste Gelegenheit, gleich ein paar weitere wichtige PHP-Techniken zu trai-
nieren. Deshalb lernst du in diesem Kapitel:
$ wie du Daten aus einem Formular mit post bzw. get verschickst
$ wie du Daten aus Formularfeldern ausliest und verarbeitest
$ wie du Bedingungen nicht nur mit if-else, sondern auch mit der so-
genannten switch-Anweisung berprfen kannst
$ wie du Variablen auf Vorhandensein testest und Fehler vermeidest
$ wie du externe Dateien mit include einbindest


138
Seiten mit Passwort schtzen

Kapitel
5 Formular fr das Passwort
Auf los gehts los! Erstelle eine Datei mit einem Passwortschutz. Wer das
Passwort kennt, sieht die geheimen Inhalte. Wer nicht, hat einfach Pech
gehabt. Doch wie fragen wir das Passwort ab? Ganz einfach, mit einem
Formular!
Fr das nchste Kapitel empfehle ich gute HTML-Formularkenntnisse.
Falls du hier noch Lcken hast, schlage einfach noch einmal im 1. Kapitel
nach. Immerhin haben wir dort schon eine erste Formularseite erstellt.
Schreibe ein Formular
Ich zeige dir Schritt fr Schritt, wie das Beispiel aufgebaut wird. Mache
einfach mit. Das Beispiel nennst du passwort.php. Hier siehst du die ers-
te Version dieser Datei, ich prsentiere dir diesmal das komplette Doku-
ment.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="de">
<head>
<title>Kennen Sie das Passwort?</title>
<meta http-equiv="content-type" content=
"text/html; charset=utf-8">
<link rel="stylesheet" type="text/css"
href="phpkid.css">
</head>
<body>
<h3>Wie lautet das Passwort?</h3>
<form action="passwort.php" method="post">
<input type="text" name="pass">
<input type="submit" value="Senden">
</form>
</body>
</html>

Zum berprfen: Du findest mein Beispiel in einem Unterordner namens
version1.
139
Senden mit Methode: post oder get?


Die Seite erzeugt ein Formular mit einem Eingabefeld. Mehr nicht!
Zur Erinnerung: Das Formular wird durch <form> eingeleitet und mit
</form> geschlossen. Das Formular selber besteht aus folgenden Zeilen:
<form action="passwort.php" method="post">
<input type="text" name="pass">
<input type="submit" value="Senden">
</form>

Schau dir die zweite Formularzeile an, denn hier entsteht das Texteingabe-
feld. Dafr sorgt die Anweisung <input type="text" name="pass">.
Ganz wichtig ist fr unsere Zwecke der Name des Feldes. Dafr habe ich
mir die Bezeichnung pass ausgedacht. (So kurz wie mglich!) Die Zuwei-
sung erfolgt durch das Attribut-Werte-Paar name="pass".
Das Formular selber wird durch Klick auf den Submit-Button abgeschickt.
Damit hier die Aufschrift Senden prangt, verwende ich das Attribut-Werte-
Paar value="Senden". Tja, und wenn du nun auf den Button SENDEN
klickst? Dann passiert erst einmal berhaupt nichts! Oder passiert doch
etwas?
Senden mit Methode: post oder get?
Das, was mit einem Formular geschieht, wird direkt im einleitenden
<form>-Tag festgelegt. Schau dir dieses Tag und seine Attribute etwas
genauer an:
<form action="passwort.php" method="post">
140
Seiten mit Passwort schtzen

Kapitel
5
Das Attribut action
Das Attribut action kmmert sich um die Formular-Aktion. Action ist
also dafr verantwortlich, was mit dem Formularinhalt passiert. Und was
passiert damit? In unserem Beispiel besteht die Aktion lediglich aus dem
Dateinamen passwort.php. Im Klartext: Die Formulardatei verschickt den
Inhalt an sich selbst! Nanu, ist das denn richtig? Ja, genau das ist beab-
sichtigt!
Beachte bitte, welchen Dateinamen du deiner Datei verpasst hast. Falls
du von meinem Vorschlag abgewichen bist, musst du den Namen eintra-
gen, den du fr deine Datei gewhlt hast! Im Zweifelsfall lsst du das
Gnsefchenpaar einfach leer. Dann wird die aktuelle Datei aufgerufen:
<form action="" method="post"> und du bist alle Sorgen los!
Das Attribut method
Das zweite wichtige Attribut ist das Attriut method. Es handelt sich dabei
praktisch um die Versende-Methode. Es gibt zwei Werte, die du verwenden
kannst. Das sind zum einen der Wert get und zum anderen der Wert post.
Was ist der Unterschied? Mache den Test!
Probiere doch einmal den Wert get aus. Ersetze post durch get und rufe
das Formular ber den Webserver auf. Tippe einen Wert in das Formularfeld
und klicke auf SENDEN. Der Wert wird einfach nach einem Fragezeichen an
die Adresse (an die URL) angehngt. Dort steht pass= und dahinter das,
was du in das Texteingabefeld getippt hast.

Fr unsere Passwortabfrage ist das vllig ungeeignet. Es sei denn du mch-
test, dass das Passwort fr alle sichtbar bertragen wird.
Vllig ungeignet:
method="get" hngt
die Werte an die URL.
141
Ausgabe des Passworts

Ich empfehle generell die Verwendung von post. Denn nur bei der Verwen-
dung des Wertes post wird der Formularinhalt im Hintergrund weitergelei-
tet. Und tatschlich verwendet man in der Praxis bei Formularen in der
Regel den Wert post. Der Wert get dagegen kommt seltener vor.
In Ausnahmefllen ist method="get" doch interessant. Denn nur so ist
es mglich, dass der Benutzer auch einen Bookmark (Lesezeichen) auf
eine Seite setzen kann. Die Formulardaten werden dabei mit im Lesezei-
chen gesichert, schlielich gehren sie dann zur URL dazu.
Ausgabe des Passworts
Ich fasse zusammen: Wir fangen das Passwort in unserem Formular auf.
Der Formularinhalt (also das Passwort) wird im Hintergrund an das Doku-
ment passwort.php geschickt. Nach Klick auf SENDEN ruft sich die Seite
praktisch erneut auf. Das alles ist inzwischen sicher klar.
Jetzt steht das Passwort zur Verfgung. Doch wie kommst du an das Pass-
wort heran?
Formularwerte als assoziatives Array
Im vorigen Kapitel hatte ich dich mit den sogenannten assoziativen Arrays
geqult. Erinnerst du dich? Die Mhe war nicht umsonst, denn jetzt trgt
dieses Wissen Frchte. Auch Formulare werden von PHP als assoziatives
Array verwaltet.
Hoppla, du hast vergessen, was Arrays sind? Arrays sind Wertelisten, die
aus einem Schlssel-Werte-Paar (key-value) bestehen. Bei den einfachen
indizierten Arrays ist der Schlssel ein bei 0 beginnender Index-Wert. Bei
den assoziativen Arrays dagegen lsst sich nicht nur der Wert, sondern
auch der Schlssel (key) frei bestimmen.
Bei den von PHP zurckgegebenen Formularen entspricht der Name des
Formularfelds dem Schlssel (key). Der Wert (value) ist dagegen das,
was der Benutzer in das Feld eingetippt hat. Das Array selber jedoch
heit $_POST, zumindest gilt das dann, wenn im <form>-Tag das Attri-
but-Werte-Paar method="post" verwendet wurde. Beachte: Wenn du
method="get" verwenden wrdest, wrde das Array $_GET heien. Wir
bleiben in unseren Beispielen jedoch stets bei method="post".
142
Seiten mit Passwort schtzen

Kapitel
5
Ein Versuch: Das Passwort ausgeben
Was weit du inzwischen? Das von einem Formular zurckgegebene Array
heit $_POST. Das Formularfeld selber heit im Beispiel pass. Ergo: Der im
Formularfeld pass eingetragene Wert muss sich mit $_POST["pass"]
ermitteln lassen. Beweise, mein lieber Watson, wir brauchen Beweise!
Natrlich, Holmes.
Also mache einen Versuch. In unserer zweiten Version der passwort.php
gebe ich das Passwort einfach im Klartext aus! Und zwar mit der allseits
beliebten Sprachanweisung echo. Ergnze einfach den PHP-Bereich unter-
halb des Formulars. Notiere also unter dem Tag </form> und ber dem
abschlieenden </body> noch Folgendes.
<?php
echo "<p>" . $_POST["pass"] . "</p>\n";
?>

Die <p></p>-Tags dienen einfach nur dazu, einen Block zu bilden. Du ht-
test sie auch weglassen knnen. Wenn du sie verwendest, musst du in die-
sem Fall wieder mit dem Verkettungsoperator Punkt (.) arbeiten.

Damit ist der Beweis erbracht: Der Zugriff auf den in das Formularfeld
pass eingegebenen Wert funktioniert! Zum Vergleich: Diese zweite Version
des Dokuments findest du im Unterordner version2.
Du rgerst dich, dass du assoziative Array-Variablen auf umstndliche
Art und Weise mit dem String verketten musst? Gewhnliche Variablen
dagegen nicht? Dann verrate ich dir einen Geheimtrick: Du musst den
key bei assoziativen Variablen nicht unbedingt in Gnsefchen schrei-
ben. Statt $_POST["pass"] kannst du unter bestimmten Bedingungen
auch mit $_POST[pass] auf das Passwort zugreifen. Und zwar immer
dann, wenn diese Variable selber zu einem Abschnitt gehrt, der in Gn-
sefchen eingekleidet wurde.
Tatsache! Nach Klick auf
Senden wird das Passwort
angezeigt.
143
Testen mit if-else

Dann kannst du das Passwort also statt auf diese Weise
echo "<p>" . $_POST["pass"] . "</p>\n";
auch folgendermaen ohne Verkettung ausgeben:
echo "<p>$_POST[pass]</p>\n";
Das ist aber nur deshalb gestattet, weil die gesamte echo-Anweisung
innerhalb von Gnsefchen notiert wurde. Auerhalb von Gnsef-
chen solltest du diese Schreibweise nicht verwenden!
Testen mit if-else
Frisch ans Werk, nun kommt die Passwortabfrage. Wer das Passwort kennt,
gelangt an die Inhalte heran. Wer nicht, wird ber seine Unkenntnis infor-
miert. Als Musterpasswort schlage ich die Zeichenfolge a?iX379 vor.
Die Version 3 der Passwort-Abfrage arbeitet mit if-else. Damit sind wir
zwar noch nicht am Ziel aller Wnsche angelangt, aber immerhin schon ein
Stck weiter. Ich zeige dir diesmal den gesamten Teil zwischen
<body></body>:
<h3>Wie lautet das Passwort?</h3>
<form action="passwort.php" method="post">
<input type="text" name="pass">
<input type="submit" value="Senden">
</form>
<?php
if ($_POST["pass"] == "a?iX379") {
?>
<h3>Geschtzter Bereich</h3>
<p>Hier stehen die geheimen Inhalte ...</p>
<?php
} else {
?>
<p>Leider kennen Sie das Passwort nicht!</p>
<?php
}
?>
144
Seiten mit Passwort schtzen

Kapitel
5
Die fr uns interessante Zeile steckt in:
if ($_POST["pass"] == "a?iX379") {

Hier wird getestet, ob der aus dem Feld pass ausgelesene Inhalt mit der
Zeichenfolge a?iX379 bereinstimmt. Nur dann zeigt das Skript den Be-
reich mit den geschtzten Inhalten an.
Ich arbeite dabei mit einer if-else-Entscheidungsstruktur. Im if-Bereich
teste ich auf bereinstimmung. Wenn dieser Ausdruck wahr ist, wird der
geschtzte Bereich angezeigt. Falls nicht, greift der else-Zweig. Es er-
scheint der Satz Leider kennen Sie das Passwort nicht!
Ist dir etwas aufgefallen? In diesem Beispiel habe ich PHP- und HTML-
Abschnitte miteinander vermischt. Die HTML-Abschnitte stehen zwar
auerhalb der PHP-Bereiche. Zumindest scheinbar. Trotzdem befinden sie
sich innerhalb eines PHP-Klammer-Blockes ({ }): Dafr arbeite ich
einfach mit mehreren PHP-Abschnitten, die die HTML-Bereiche jeweils
umklammern. Je nach Bedarf schalte ich den PHP-Bereich dafr ab und
wieder ein. Wie du siehst, kannst du HTML-Abschnitte also ganz prob-
lemlos in PHP einbinden. Hauptsache, du markierst korrekt, wo ein PHP-
Abschnitt beginnt und wo er wieder aufhrt. Hauptsache, du vergisst
nicht eine der hier notwendigen geschweiften Klammern!
Schnheitsfehler? Variablentest
mit isset()!
Fllt dir an der dritten Version des Beispiels etwas auf? Richtig, es funktio-
niert! Herzlichen Glckwunsch. Nur wer das Passwort kennt, wird an die
geschtzten Inhalte herangelassen.
Doch der Satz Leider kennen Sie das Passwort nicht wird auch dann ein-
geblendet, wenn die Seite zum allerersten Mal aufgerufen wird. Soviel H-
me ist ungesund. Du musst dem Besucher ja nicht gleich am Anfang auf
die Nase binden, dass du ihr oder ihm die Passwortkenntnis nicht zutraust.
145
Schnheitsfehler? Variablentest mit isset()!


Gleich beim Aufrufen der Seite wird dem Besucher Unkenntnis unterstellt.
Und tatschlich befindet sich an dieser Stelle ein Schnheitsfehler. Der Satz
sollte erst dann eingeblendet werden, nachdem der Formularinhalt abge-
schickt wurde. Und nicht gleich am Anfang! Wie schaffst du das?
Prfen, ob die Variable berhaupt
vorhanden ist
Du prfst einfach, ob die Variable berhaupt definiert und damit vorhanden
ist. Denn wenn das Formular noch nicht abgeschickt wurde, kann eine Va-
riable namens $_POST["pass"] noch nicht existieren! Oder? Das Array
$_POST wird schlielich erst nach dem Abschicken des Formularinhalts
erzeugt.
Nutze die Funktion isset(). Die Funktion isset() prft, ob eine Vari-
able berhaupt gesetzt ist. Erst dann gibt sie den Wert wahr (true) zu-
rck. Bei Nichtvorhandensein wird als Testergebnis jedoch false zu-
rckgegeben. Die Syntax dieser Funktion sieht folgendermaen aus:
isset($Variable). Du bergibst die zu testende Variable einfach in
runden Klammern.
Baue das Skript um, verbessere es: Aus dem else-Zweig machst du einfach
ein elseif! Und hier testest du nun, ob die Passwort-Variable gesetzt ist.
Verndere also folgende Zeile:
else {

in
elseif (isset($_POST["pass"])) {

und schon hast du das Problem (vorerst) gelst.
146
Seiten mit Passwort schtzen

Kapitel
5
Die Wirkungsweise ist noch nicht ganz klar? Die Zeile liest sich wie folgt:
Prfe, ob die Variable $_POST["pass"] gesetzt ist. Wenn ja, gibt die
Funktion isset() den Wert true zurck. Und if bzw. elseif testet
schlielich auf Wahrheit. In diesem Fall (also nur bei gesetzter Variable)
wird der Text Leider kennen Sie das Passwort nicht ausgegeben.
Da die Variable beim ersten Aufruf der Seite jedoch noch nicht gesetzt ist,
passiert gar nichts. Falls du vergleichen willst, schaust du dir das Beispiel
im Ordner version4 an!
Aufgepasst mit den vielen Klammern in der elseif-Zeile! Das Vergessen
solch einer Klammer fhrt unweigerlich zu einer Fehlermeldung. Wo
kommen die ganzen Klammern her? Die Bedingung fr elseif wird in
runden Klammern getestet. Die notierst du zuerst. Dann setzt du dort
den isset()-Test hinein, der schlielich auch ein paar runde Klammern
bentigt. Zum Schluss platzierst du innerhalb dieser runden Klammern
die Variable, in unserem Fall $_POST["pass"]. Nach einem Leerzeichen
folgt dann noch die geschweifte Klammer, die schlielich unseren Block
einleitet.
Mit dieser vierten Version der Passwortabfrage hast du ein wichtiges
Etappenziel erreicht. Und da das Passwort im PHP-Bereich steht, wird es
fr Auenstehende auch nicht angezeigt.
Das Skript noch etwas sicherer machen
In diesem Skript steckt ein kleines Problem. Es handelt sich um einen un-
sichtbaren Hinweis (Notice), den ich fr dich hier sichtbar gemacht habe:

Der Hinweis bezieht sich auf Zeile 15 und besagt, dass der Index pass
nicht definiert wre. Schau dir Zeile 15 noch einmal genau an:
if ($_POST["pass"] == "a?iX379") {
Das Skript produziert
intern einen (normaler-
weise unsichtbaren)
Hinweis.
147
Mehr Mglichkeiten mit switch

Und tatschlich steht dort $_POST mit dem Index pass. Fakt ist: Der Hin-
weis erscheint nur beim allerersten Aufruf der Seite. Wenn der Nutzer also
noch keinen Formularinhalt eingetragen und abgeschickt hat. Das ist lo-
gisch: Wenn noch kein Formularinhalt abgeschickt wurde, kann es auch
keine Variable $_POST mit dem Index pass geben.
Derartige Notices (Hinweise) sind zwar keine Fehler, sie gelten aber als
schlechter Programmierstil und lassen sich vermeiden. Undefinierte Indi-
zes oder undefinierte Variablen geben Hackern gewisse Chancen, in das
Skript einzudringen und Variablenwerte zu manipulieren. (Auch wenn die
Chancen in diesem Fall sicher recht klein sind.)
Die Lsung ist in diesem Fall ganz einfach. Fge auch in das einleitende if
von Zeile 15 die eben besprochene isset()-Variablenprfung ein und
zwar zustzlich als erster von zwei Teilausdrcken. Verknpfe beide Teil-
ausdrcke mit dem &&-Operator.
if (isset($_POST["pass"]) && $_POST["pass"] == "a?iX379") {

Nun wird auch hier zuerst das Vorhandensein der Variablen
$_POST["pass"] berprft. Erst bei einem Erfolg findet der zweite Test
statt. Vergleiche mit dem Beispiel aus dem Ordner version5.
Wie du diese normalerweise unsichtbaren Hinweise einblendest, verrate ich
dir brigens im Nachfolgeband PHP und MySQL Praxisbuch fr Kids.
Mehr Mglichkeiten mit switch
Ich bin nie zufrieden! Ein einziges lumpiges Passwort abfragen? Das kann
doch jeder! Als nchste Stufe schwebt mir eine Seite vor, die mehrere
Passwrter entgegennimmt. Je nach Passwort soll der Betrachter andere
Informationen angezeigt bekommen. Das ist sozusagen die Hohe Schule
der Passwortkunst. Folgende Passwrter sollen mglich sein:
0 a?iX379
0 a?iX380
0 a?iX381
Richtig, denkst du dir vielleicht: Da arbeite ich mit if und mehreren
elseif-Bereichen. Stimmt. Gute Idee. Der Ansatz ist vom Prinzip her vllig
korrekt! Doch gerade fr solche Flle gibt es eine Alternative zur stndigen
Elseifferei. Schau dir die switch-Fallunterscheidung an.
148
Seiten mit Passwort schtzen

Kapitel
5
Die switch-Fallunterscheidung
Du mchtest auf verschiedene Eingaben unterschiedlich reagieren? Dann
bietet sich die switch-Fallunterscheidung an. Hier schlgst du gleich
mehrere Fliegen mit einer Klappe. Die Syntax lautet:
switch(Variable) {
case Wert1:
Anweisung;
break;
case Wert2:
Anweisung;
break;
case Wert3:
Anweisung;
break;
...
default:
Anweisung;
}

Sieht kompliziert aus? Es ist einfacher, als du vielleicht denkst: Die
switch-Fallunterscheidung untersucht, ob eine Variable mit den aufgelis-
teten Werten bereinstimmt. Deshalb schreibst du in der ersten Zeile
switch(Variable) {

Dabei ist das Wort Variable der Platzhalter fr die zu prfende Variable.
(Fr unsere Zwecke setzen wir an dieser Stelle nachher natrlich wieder
$_POST["pass"] ein.) Beachte die ffnende geschweifte Klammer ({) am
Schluss der Zeile, da switch() wieder einen Block bentigt.
Die bereinstimmung selber wird nun mit dem Schlsselwort case getes-
tet. Hinter dem Leerzeichen notierst du den Wert, mit dem die Variable
evtl. bereinstimmen knnte.
case Wert1:

Wert1 ist hier natrlich der Platzhalter fr die entsprechende Zahl bzw.
Zeichenfolge. In unserem Fall wrdest du als ersten Wert notieren
a?iX379.
Beachte, dass am Ende der case-Zeile ein Doppelpunkt gesetzt werden
muss. Gibt es eine bereinstimmung? Dann wird die betreffende Anwei-
sung nach dem Doppelpunkt ausgefhrt. Die Programmabarbeitung muss
149
Mehr Mglichkeiten mit switch

durch das Schlsselwort break beendet werden. Das Wort break steht
hier fr Abbruch.
Falls es keine bereinstimmung gibt, wird in der nchsten case-Zeile wei-
tergeprft. Sollte in keiner der case-Zeilen eine bereinstimmung erzielt
worden sein, wird die unter default: stehende Anweisung ausgefhrt.
Soweit die Theorie. Nun zur Praxis!
Wir switchen los: Das praktische Beispiel
Das praktische Beispiel nenne ich zur Unterscheidung switch.php. Achte
also auf diesen neuen Dateinamen. Und hier die genaue Schrittfolge zur
Erstellung des Quelltexts.
>
Zuerst bernimmst du das Formular aus dem allerersten Passwort-
Beispiel. Der einzige Unterschied: Beachte den bei action einzutra-
genden Wert. Da das neue Projekt unter dem Namen switch.php
gesichert wird, musst du hier auch switch.php notieren!
>
Hier drucke ich ganz schnell zur Veranschaulichung noch einmal den
gesamten HTML-Quellcode ab, der vorerst zwischen <body></body>
stehen muss. Die berschrift kannst du natrlich frei whlen:
<h3>Drei Passworte abfragen</h3>
<form action="switch.php" method="post">
<input type="text" name="pass">
<input type="submit" value="Senden">
</form>

>
Ich zeige dir nun die Vorgehensweise, mit der ich meine Skripte
erstelle. Und zwar beginne ich dabei stets auen und arbeite mich
nach innen vor. Also, mach mit: Unter dem Formular fgst du zuerst
einen PHP-Bereich ein. Dazwischen lsst du genug Platz zum Ergn-
zen der noch folgenden Codezeilen.
<?php
(einige Zeilen Platz lassen)
?>

>
Nun notierst du innerhalb des PHP-Bereichs zuerst eine if-
Anweisung, mit der du auf das Vorhandensein der Variable
$_POST["pass"] testest. Nun sieht der gesamte PHP-Bereich fol-
gendermaen aus:
150
Seiten mit Passwort schtzen

Kapitel
5
<?php
if (isset($_POST["pass"])) {
(auch hier wieder einige Zeilen Platz lassen);
}
?>

Was habe ich hier gemacht? Ich spanne die if-Abfrage praktisch um das
gesamte Skript herum. Und zwar als eine Art Klammer. Im Klartext: Die
in diesem untergeordneten Block enthaltenen Zeilen sollen nur dann
ausgefhrt werden, wenn die Variable gesetzt ist. Das schtzt uns zum
einen vor unsichtbaren Hinweisen. Zum anderen macht unsere noch fol-
gende switch-Fallunterscheidung tatschlich nur bei gesetzter Variable
Sinn! Diese alles umspannenden if-Abfragen sind brigens eine hufi-
ge Programmiertechnik. In den meisten Fllen wird dabei wie hier auf
den else-Zweig verzichtet, da dieser nicht bentigt wird.
>
Das Prinzip ist klar? Gut! Innerhalb des if-Blocks notiere ich nun die
switch()-Fallunterscheidung.
>
So sieht der gesamte PHP-Bereich aus. Die von mir hervorgehobenen
ersten zwei und letzten zwei Zeilen sind die, die du eben aufgeschrie-
ben hast. Der Rest ist neu hinzugekommen, er erzeugt die switch()-
Fallunterscheidung.
<?php
if (isset($_POST["pass"])) {
switch($_POST["pass"]) {
case "a?iX379":
echo "<p>Passwort-Bereich 1</p>";
break;
case "a?iX380":
echo "<p>Passwort-Bereich 2</p>";
break;
case "a?iX381":
echo "<p>Passwort-Bereich 3</p>";
break;
default:
echo "<p>Leider kennen Sie das Passwort nicht!</p>";
}
}
?>
151
Inhalt mit include einbinden

Zur Information: Aus Grnden der bersichtlichkeit habe ich hier auf das
Einbinden von HTML-Bereichen verzichtet. Eine Zeile wie
echo "<p>Passwort-Bereich 3</p>";

steht als Platzhalter fr den entsprechenden Passwortbereich.

Und, schon ausprobiert? Sehr gut! Wie du siehst, kannst du auch mit
switch() eine Passwortabfrage erzeugen.
Inhalt mit include einbinden
Apropos Platzhalter fr den entsprechenden Passwortbereich. Wre es
nicht schner, die betreffende Seite extern ablegen zu knnen? Damit du
die geheimen Infos viel einfacher bearbeiten kannst? Wie gut, dass es
include() gibt!
Mit der Funktion include() kannst du externe Dateien einbinden und
auswerten. Notiere in runden Klammern einfach den Dateinamen und
evtl. den Pfad zur jeweiligen Datei, und zwar von Gnsefchen umhllt.
Wichtig zu wissen: Durch den Einsatz von include() wird die PHP-
Notation automatisch abgeschaltet. Die einzubindende Datei wird als
normale HTML- bzw. Textdatei betrachtet. Um die Datei info1.html
einzubinden, schreibst du z. B. include("info1.html").
>
Erstelle nun eine Datei fr jeden Passwort-Bereich. Als Endung ent-
scheidest du dich fr die Endung .html. Die erste Datei nennst du im
Beispiel info1.html.
<h3>Bereich fr Passwort 1</h3>
<p>Hier stehen die Infos fr die
Besitzer des 1. Passworts.</p>

Drei Passwrter stehen
zur Auswahl.
152
Seiten mit Passwort schtzen

Kapitel
5
>
Erzeuge nach diesem Muster die zwei weiteren externen Dateien na-
mens info2.html und info3.html. Achte darauf, dass du diese
Dateien im Beispiel in den gleichen Ordner legst, in dem die
switch.php liegt.
Und nun baust du die switch.php um. Der derart umgestaltete
switch()-Block sieht folgendermaen aus:
switch($_POST["pass"]) {
case "a?iX379":
include("info1.html");
break;
case "a?iX380":
include("info2.html");
break;
case "a?iX381":
include("info3.html");
break;
default:
echo "<p>Leider kennen Sie das Passwort nicht!</p>";
}

Probiere es aus, es funktioniert. (Das Vergleichs-Beispiel auf CD heit hier
switch2.php.) Der Vorteil liegt auf der Hand: Es ist fr dich nun viel ein-
facher, den Inhalt der Passwort-Bereiche zu bearbeiten und anzupassen.
Merkst du etwas? Du kennst jetzt zwar die switch()-Fallunter-
scheidung an einem praktischen Beispiel. Doch mit dem Thema Sicher-
heit hat die bisherige Vorgehensweise nicht das geringste zu. Der Besu-
cher braucht nur (durch Raten) den direkten Link zur Datei info1.html,
info2.html bzw. info3.html zu kennen. Schon gelangt sie oder er an
deine ach so geheimen Daten heran! Mehr Tipps zur Sicherheit folgen
deshalb im nchsten Abschnitt.

Mehr Sicherheit: Endungs- und
Ordnertricks
Zurck zum Thema Sicherheit. So flexibel und angenehm die include-
Methode zu sein scheint. Hier zeigen sich offenbar die Grenzen. Trotzdem
153
Mehr Sicherheit: Endungs- und Ordnertricks

habe ich ein paar Ideen, wie du mehr Sicherheit erreichen kannst. Schau dir
einfach meine Ideen an und mache dir deine eigenen Gedanken:
0 Verwende Dateinamen, die sich nicht so leicht raten lassen. Wie wre es
mit d_75uzRxei.html?
0 Verwende eine andere Dateiendung als .html. Der Funktion
include() ist die Endung egal. Du kannst deine Dateien auch .txt,
.inc oder sogar .exe nennen.
0 Es geht noch wilder: Verwende z. B. die Endung .gif, .zip oder .mid.
Bei all diesen Endungen zeigen die meisten Browser die Datei nicht im
Klartext an, da sie keine HTML-Datei erwarten. Gif-Grafiken werden als
Bild erkannt. Dateien mit .zip am Ende will der Browser herunterladen,
da er hier ein sogenanntes gepacktes ZIP-Archiv vermutet. Noch pfiffi-
ger ist vielleicht die Endung .mid. Die meisten Browser bestehen dar-
auf, eine derartige Datei abzuspielen, da sie an der Endung eine Midi-
Klangdatei zu erkennen glauben.
0 Nutze einen (oder mehrere) Unterordner fr deine Dateien. Wie wre es
mit content007? Dass der Besucher zum einen den richtigen Ordner-
namen fr den Unterordner errt und zum anderen den korrekten Da-
teinamen, ist schon mehr als unwahrscheinlich.

Verstecke die Dateien im Unterordner und verpasse ihnen eine falsche Dateiendung.
Ich habe mich im ersten Beispiel fr eine Kombination aus der letzten und
der vorletzten Idee entschieden. Der Funktion include() ist die Dateien-
dung der einzubindenden Datei schlielich herzlich egal. Also benenne ich
meine Textdateien einfach um.
154
Seiten mit Passwort schtzen

Kapitel
5
Vergleiche mit meiner Beispieldatei include.php. Die einzelnen Textda-
teien habe ich mit der Endung .mid versehen und in einem Unterordner
namens content007 abgelegt. Tipp: Das Umbenennen einer Datei gelingt
im Windows-Explorer. Rechtsklicke auf die Datei, whle den Befehl
UMBENENNEN. Lege die neue Endung fest.
Schon wieder wirst du nur mit einem Teil der Wahrheit abgespeist. Ich
frchte, dass an dieser Stelle wohl wieder etwas handfestes Hunde-
Know-how gefragt ist! Es gibt eine weit sicherere Lsung, als dir der
Buchautor glauben machen mchte. Zugegeben, nicht bei allen Dienst-
leistern klappt es. Jedoch bei vielen kostenpflichtigen Anbietern wie z. B.
bei www.all-inkl.com. Wie lautet der Trick? Lege die zu schtzenden Da-
teien zuerst in einem separaten Unterordner ab, wie hier schon gezeigt.
Diesen Unterordner schtzt du nun mit dem Konfigurationstool deines
Dienstleisters! (Dahinter verbirgt sich eine als htaccess bezeichnete
Technik.)
Ein Beispiel? Gut! Ich habe fr dich einen Ordner namens safe eingerich-
tet. Dort liegt eine derartige .htaccess-Datei. Sie schtzt diesen Ordner
vor dem Zugriff von auen. Im safe-Ordner kannst du also ohne Reue
HTML-Dateien wie info1.html, info2.html oder info3.html ablegen
sie sind von auen nicht sichtbar. Vergleiche mit meiner Lsung
include2.php. Probiere aus, ob es auch bei deinem Hoster funktioniert.
Und noch einen Trick habe ich herausgefunden. Du kannst die zu schtzen-
den Dateien auch in einen anderen sicheren Ordner legen. Ich meine einen
Ordner, der beim Dienstleister von Hause aus geschtzt ist. So ist bei
www.all-inkl.com der Ordner cgi-bin von auen nicht erreichbar und
das ganz ohne schtzende .htaccess-Datei. Er ist fr Skripte vorbehalten.
Wenn du jedoch hier Dateien ablegst und diese per include() einbindest,
werden die Dateien auch aus diesem Ordner herausgeholt.
Schlussbemerkung
In diesem Kapitel hast du nicht nur viel zum Thema Passwortschutz gelernt.
Du hast bei dieser Gelegenheit auch erfahren, wie Formulare abgeschickt
und ausgewertet werden. Mit der switch()-Fallunterscheidung kennst du
eine weitere wichtige Methode, Eingaben auf bereinstimmung zu ber-
prfen. Auerdem weit du nun, wie du externe Dateien per include()
einbinden kannst.
155
Zusammenfassung

Zusammenfassung
0 Du weit, wie Formulare ausgewertet werden. Notiere im <form>-Tag
das Attribut action. Gib als Wert den Namen bzw. Pfad der PHP-Datei
an, die die Formulardaten entgegennehmen soll. (Wenn du das Gnse-
fchenpaar leer lsst, wird automatisch wieder die aktuelle Datei auf-
gerufen.) Das Attribut method dagegen steuert die Versendemethode
(get bzw. post). Schreibe method="post", wenn die Daten im Hin-
tergrund bermittelt werden sollen.
0 Der Formularinhalt wird als assoziatives Array zurckgegeben. Bei Aus-
wahl von method="get" heit dieses $_GET, bei method="post" da-
gegen $_POST. Den Wert eines Formularfeldes kannst du im letzten Fall
ber $_POST["Feldname"] auslesen.
0 In Ausnahmefllen darfst du den key bei assoziativen Arrays auch ohne
Gnsefchen notieren, schreibe z. B. $_POST[Feldname]. Durch diese
Komfortschreibweise ersparst du dir das Verketten des brigen Strings
mit den Array-Variablen.
0 Die Funktion isset() testet, ob eine Variable berhaupt vorhanden ist.
Sie gibt wahr oder falsch zurck. Du mchtest prfen, ob ein Pass-
wortfeld namens pass existiert? Das erreichst du mit
isset($_POST["pass"]).
0 Die switch()-Fallunterscheidung untersucht, ob eine Variable mit den
aufgelisteten Werten bereinstimmt. Je nach bereinstimmung kannst
du ganz unterschiedliche Codezeilen ausfhren lassen. Damit ist
switch() eine Alternative zu if und elseif. Mit switch() kannst
du jedoch nur auf bereinstimmung testen. Die Prfung, ob ein Wert
z. B. grer, kleiner oder ungleich ist, ist if bzw. elseif vorbehalten.
0 Binde externe Dateien mit der Funktion include() in deine PHP-
Abschnitte ein. Die einzubindende Datei wird dabei unabhngig von der
Endung als normale HTML- bzw. Textdatei betrachtet. Mchtest du hier
PHP-Code einbinden, musst du das in der externen Datei erstens durch
die Endung .php und zweitens durch die PHP-Tags <?php und ?>
kenntlich machen.
156
Seiten mit Passwort schtzen

Kapitel
5 Ein paar Fragen
1. Bei welcher Versendemethode werden Formulardaten im Hintergrund
an das entsprechende Skript geschickt?
2. Angenommen, du verschickst den Formularinhalt mit method="get".
Wie greifst du im PHP-Skript auf den Inhalt eines Feldes namens pass
zurck?
3. Wie heit die Funktion, mit der du die Existenz einer Variablen prfen
kannst?
4. Angenommen, du legst eine Datei namens inhalt.txt in den Unter-
ordner daten. Der Pfad zu dieser Datei lautet also da-
ten/inhalt.txt. Du mchtest diese Datei ber include() vom
Wurzelordner aus einbinden. Wie sieht die komplette Funktion aus?
und ein paar Aufgaben
1. Schreibe ein PHP-Dokument namens vorname.php. Erstelle hier ein
Formular mit Texteingabefeld, in welches der Benutzer seinen Vornamen
eingeben kann. Nenne das Texteingabefeld vorname. Nach Klick auf
SENDEN soll unter dem Formular ein persnlicher Begrungssatz wie
Hallo Petra! stehen.
2. Gib den Inhalt des Formularfelds ($_POST["vorname"]) in einer Syn-
tax wieder, die auf die Verknpfung mit dem umgebenden String ver-
zichtet.
3. Falls noch nicht getan: Sorge dafr, dass die Begrung nur dann er-
folgt, wenn das Formular zum einen abgeschickt wurde (Ist die Variable
gesetzt?) und zum anderen aber auch, wenn das Feld nicht leer ist. Ver-
knpfe also zwei Bedingungen miteinander. Tipp: Ein Leerstring wird
durch ein Paar Gnsefchen symbolisiert.
4. Wie gut sind deine generellen Formularkenntnisse? ndere das Pass-
wortbeispiel aus dem ersten Teil des Kapitels (Datei passwort.php)
wie folgt ab: Das Formularfeld soll das Passwort bei der Eingabe nicht
mehr im Klartext anzeigen. Stattdessen sollen je nach Browsertyp
Sternchen bzw. Kreise erscheinen.

157



6
Etwas Mathe:
Taschen(geld)rechner
Kennst du das auch? Da bekommt man nun regelmig eine gewisse Sum-
me pro Monat. Und dann ist am Ende des Geldes noch so viel Monat brig.
Wo verschwinden sie hin, die sauer verdienten Piepen? Was passiert mit
deinem Taschengeld? Ich glaube, hinter diesem Phnomen steckt eines der
letzten groen Rtsel der Menschheit. Versuchen wir gemeinsam, zumin-
dest etwas Licht in das Dunkel zu bringen. In diesem Kapitel zeige ich dir
aus aktuellem Anlass, wie du
$ mit den Grundrechenarten umgehst
$ einen Einnahme-Ausgaben-Vergleich erstellst
$ das Ergebnis absolut und in Prozent darstellst
$ Zahlen rundest und mit Nachkommastellen fllst
$ ein Diagramm zur Auswertung zeichnest
$ einen einfachen Taschenrechner programmierst
$ die Berechnung mit Hilfe einer Funktion erleichterst
Mit anderen Worten: In diesem Kapitel dreht sich alles rund um die Ma-
thematik. Ganz unabhngig davon, welche Einstellung du zu diesem Schul-
fach hast bzw. hattest.
158
Etwas Mathe: Taschen(geld)rechner

Kapitel
6 Nicht ohne Grund: Grundrechenarten
Eine Programmiersprache wre keine Programmiersprache, wenn man da-
mit nicht rechnen knnte. Und genau wie in der Schule geht es auch in
PHP mit den Grundrechenarten los. Wir wollen uns ja nicht gleich am An-
fang beranstrengen!
Plus, Minus, Mal, Geteilt
Die vier Grundrechenarten lauten Plus, Minus, Mal und Geteilt. Die ent-
sprechenden Rechenoperatoren sehen in PHP so aus: +, -, * und / (Schrg-
strich). Auerdem gibt es vom Plus- bzw. Minuszeichen jeweils noch ein
Doppelmoppel-Exemplar namens ++ bzw. --. Mit dem Doppelplus wird
nicht etwa doppelt addiert. Es handelt sich vielmehr um den Operator zum
Inkrementieren. Inkremen wie bitte? Mit Inkrementieren ist lediglich das
Hinzuzhlen von 1 gemeint. Rechentechnisch steckt also die Anweisung
$i = $i + 1 dahinter. Zur Variablen $i (oder $kaugummi oder wie auch
immer) wird also der Wert 1 hinzugezhlt.
Und warum schreibt man dann nicht einfach $i = $i + 1, sondern
$i++? Weil Programmierer faule Gesellen sind und krzen, wo es nur
geht. Zugegeben, so ein $i++ sieht auf den ersten Blick recht unge-
wohnt aus. Nach einer gewissen Eingewhnungszeit gehts aber dann
recht fix! hnlich verhlt es sich mit dem Gegenstck --. Damit wird de-
krementiert, also um 1 vermindert. Fr die Berechnung $i = $i - 1
schreibt man also $i--. Merke dir diese Anweisungen!
Grundrechenarten im berblick
Und nun zeige ich dir die vier Grundrechenarten nebst Inkrement- und
Dekrement-Operator fein suberlich aufgelistet in einer Tabelle. Ich habe
gleich ein Anwendungsbeispiel hinzugeschrieben.

Operator Bedeutung Beispiel
+ Addition $a = 8 + $c
- Subtraktion $c = $b 2
* Multiplikation 10 * 4
/ Division $x / $y
++ addiert 1 hinzu
$i++ (ist die Abkrzung fr $i = $i + 1)
-- zieht 1 ab
$i-- (steht fr $i = $i - 1)
159
Rechenpraxis: Zwei mal Drei macht Vier

Rechenpraxis: Zwei mal Drei
macht Vier
und Drei macht Neune. Zumindest behauptet das Pippi Langstrumpf. Ich
frchte, dass ich whrend meiner Schulzeit zu hnlichen Ergebnissen ge-
langt war. Egal ob kleines Einmaleins oder groe Berechnungen: Mit PHP
lsst sich das alles endlich wunderbar nachprfen.
Ran an die Praxis, jetzt wird gerechnet. Wir begngen uns dabei mit der
Multiplikation. Notiere das Grundgerst fr eine HTML-Datei. Ich zeige dir
nun den kompletten Teil zwischen den Tags <body></body>.
<h2>Zwei mal Drei</h2>
<p><?php
$a = 2;
$b = 3;
$c = $a * $b;
echo $c;
?></p>

Das Skript ist einfach: Die zu multiplizierenden Werte halte ich in den Vari-
ablen $a und $b fest. Das Ergebnis speichere ich in der Variablen $c und
gebe das Ganze durch eine simple echo-Anweisung aus.
Der PHP-Teil wird auerdem vom Tag-Paar <p></p> eingefasst, damit das
Ergebnis innerhalb eines Absatzes ausgegeben wird. Du weit schon, jegli-
cher Text sollte innerhalb eines Block-Elements notiert werden. Und das
Ergebnis selbst?

Zugegeben, Autor und Pippi gehren nicht gerade zu den Leuchten in Ma-
thematik. Aber zum Glck gibt es ja die Rechenfunktionen von PHP!
brigens, falls du das Beispiel suchst: Ich habe es unter dem Namen
pippi.php auf der CD abgespeichert.
Plutimikation frei nach
Pippi Langstrumpf. PHP
rechnet genauer!
160
Etwas Mathe: Taschen(geld)rechner

Kapitel
6 Einnahmen minus Ausgaben:
Taschengeldrechner
Wie wrs zur Abwechslung mit einer Subtraktion? Schlielich werden im
Leben wohl mehr Dinge abgezogen als hinzugefgt. Beim Taschengeld
zum Beispiel.
Formular erzeugen
Erstelle doch einmal ein Formular mit zwei Feldern. Das eine Feld nimmt
den Einnahme-Wert entgegen und wird mit a benannt. Das zweite Feld ist
fr die Ausgaben gedacht, es bekommt den Namen b verpasst. Dein Skript
berechnet Einnahmen minus Ausgaben und prsentiert dir das meist er-
nchternde Ergebnis.
Das Dokument heit brigens rechner.php, denn schlielich musst du
auch den Dateinamen wissen. Diesen brauchst du fr das Attribut action
im Formular, denn das Formular schickt den Inhalt an sich selber.
Der Quelltext ist simpel. Wenn du beim vorigen Kapitel gut mitgekommen
bist, verstehst du die Wirkungsweise auf Anhieb.
<h2>Einnahme-Ausgabe-Rechnung</h2>
<form action="rechner.php" method="post">
<p>Einnahme: <input type="text" name="a"><br>
Ausgabe: <input type="text" name="b"></p>
<input type="submit" value="Berechnen">
</form>
<?php
$c = $_POST['a'] - $_POST['b'];
echo "<p>Das Ergebnis lautet $c</p>\n";
?>

Der PHP-Teil besteht lediglich aus zwei Zeilen, die sich sofort erschlieen.
Mit $_POST['a'] ermittelst du den Wert aus Feld a, mit $_POST['b']
dagegen die Zahl aus Feld b. Die Differenz wird berechnet, in der Variablen
$c gespeichert und in der zweiten PHP-Zeile ausgegeben.
161
Einnahmen minus Ausgaben: Taschengeldrechner

Du mchtest Bruchzahlen notieren, z. B. 12,5? Dann beachte, dass Dezi-
malbrche in PHP (und in anderen Programmiersprachen) nicht mit dem
Komma getrennt werden. Im angelschsischen Raum wird dafr der
Punkt verwendet, denn die Amis oder Englnder kennen unsere Bedeu-
tung fr das Komma nicht: Schreibe Kommazahlen also stets mit Punkt
statt Komma! Fr 12,5 musst du also notieren: 12.5!

Ist es dir schon aufgefallen? In diesem Kapitel verwendet der Autor die
Schreibweise $_POST['a'] und nicht $_POST["a"]. Warum die einfa-
chen statt der doppelten Gnsefchen? Gibt es da einen Unterschied?
Nein, den gibt es nicht. Es ist in unserem Fall vllig egal, ob du die einfa-
chen oder die doppelten Gnsefchen verwendest. Das Thema spielt
erst dann eine Rolle, wenn du Gnsefchen ineinander verschachtelst.
Denn gleichrangige Gnsefchenpaare drfen nicht ineinander ver-
schachtelt werden.
Nimm die Schreibweise, die dir am besten behagt. In der Praxis wirst du
mal diese, mal jene Schreibweise vorfinden und der Autor dieses Buches
will dich wahrscheinlich nur an diese Praxis gewhnen.
Kein Ergebnis anzeigen beim ersten Aufruf
So simpel knnen wir das Skript nicht stehen lassen. Denn selbst beim ers-
ten Aufruf der Seite erscheint nun der Text Das Ergebnis lautet 0. Wozu
haben wir im vorigen Kapitel lang und breit die if-Abfrage besprochen?
Prfe, ob die beiden Variablen gesetzt sind. Beim ersten Aufruf der Seite
wird das noch nicht der Fall sein. Der Inhalt der Formularfelder wird
schlielich erst dann verschickt, wenn du auf die Schaltflche BERECHNEN
klickst. Verbinde diese Abfrage durch den &&-Operator (AND). Erst wenn
beide Bedingungen wahr sind, soll das Ergebnis eingeblendet werden.
Dezimalbruch auf
Angelschsisch: Trenne
mit Punkt statt mit
Komma!
162
Etwas Mathe: Taschen(geld)rechner

Kapitel
6
Hier siehst du den PHP-Teil mit dieser zustzlichen if-Klammer:
<?php
if (isset($_POST['a']) && isset($_POST['b'])) {
$c = $_POST['a'] - $_POST['b'];
echo "<p>Das Ergebnis lautet $c</p>\n";
}
?>
Besser testen: Die Funktion empty()
Zeit, dass ich mich mal wieder melde, dein Hund Buffi! Offenbar teilt dir
der Autor nur die halbe Wahrheit mit und speist dich mit der Funktion
isset() ab. Was passiert, wenn du nichts in die Felder eintrgst und
trotzdem auf die Schaltflche BERECHNEN klickst? Das Skript berechnet
das Ergebnis 0. Warum? Leer gelassene Felder werden als Leerstring in-
terpretiert, was in diesem Fall gleichbedeutend ist mit der Ziffer Null.
Nimm statt isset() doch einfach die Funktion empty()! Mit empty()
erreichst du fast das Gegenteil von isset(). Zur Wiederholung: Die
Funktion isset() prft, ob eine Variable gesetzt ist und gibt nur dann
true zurck. Sonst liefert isset() jedoch den Wert false. Das ist be-
kannt. Mit der neuen Funktion empty() dagegen kannst du herausfin-
den, ob eine Variable nicht gesetzt ist, ob sie leer ist oder ob sie dem
Wert 0 entspricht. In allen diesen drei Fllen liefert die Funktion true
zurck, sonst ist der Wert von empty() false. Du schlgst also gleich
drei Fliegen mit einer Klappe!
Weil empty() ebenfalls einen Wahrheitswert zurckgibt, eignet sich die
Funktion genau wie isset() so wunderbar fr den Einsatz in if-
Strukturen. Der Test lautet dann wie folgt: empty($Variable).
Einen Haken gibt es noch an der Geschichte. Mit isset() ermittelst du,
ob eine Variable gesetzt ist, nur dann gibt die Funktion true zurck. Mit
empty() hingegen erhltst du true, wenn die Variable eben nicht ge-
setzt (oder leer oder 0) ist. Hmm. Eigentlich wollten wir es ja umgedreht
haben. Doch hier greift ein neuer Trick! Stelle der Funktion ein Ausrufe-
zeichen voran! Mit diesem Ausrufezeichen verkehrst du die Funktion in
ihr Gegenteil, dieses Ausrufezeichen ist eine Art Umkehroperator.
Schreibe also !empty($Variable).
163
Einnahmen minus Ausgaben: Taschengeldrechner

Und so sieht das Beispiel aus, wenn du statt isset() mit empty() ar-
beitest:
<?php
if (!empty($_POST['a']) && !empty($_POST['b'])) {
$c = $_POST['a'] - $_POST['b'];
echo "<p>Das Ergebnis lautet $c</p>\n";
}
?>

Bei leer gelassenem Feld erfolgt keine Berechnung.
Zum Vergleich: Die derart verbesserte Version findest du unter dem Na-
men rechner_hund.php auf der CD. Probiere sie aus!
Noch besser testen: Funktion is_numeric()
Der Hund Buffi aus der Randspalte wird in letzter Zeit ein wenig vorlaut!
Die Funktion empty() ist keine schlechte Idee, das gebe ich zu. Und die
berlegungen aus seinem Tipp sind schon sehr wichtig.
Trotzdem sollten wir an dieser Stelle weiterdenken. Denn !empty() unter-
drckt auch die Eingabe einer 0 in eines dieser Formularfelder. Zugegeben,
in den meisten Fllen macht die Eingabe von Nullen nicht viel Sinn. Aber
wenn du auer der Reihe doch mal eine 0 brauchst?
Wer den Trick kennt, tippt einfach 0.0 oder 0. in das Formularfeld ein. Das
geht. Besser wre es, wenn du gleich die Funktion is_numeric() verwen-
den wrdest. Sie prft, ob ein Wert eine Zahl ist. Nur dann gibt sie true
zurck, ansonsten false! Das ist doch viel eleganter, findest du nicht?
Und so sieht das Beispiel aus, wenn du statt !empty() mit is_numeric()
arbeitest. (Dabei prfe ich zuerst aus Sicherheitsgrnden mit isset(), ob
die Variable berhaupt existiert. Erst dann teste ich, ob sie einem Zahlwert
entspricht. So vermeide ich Fehlermeldungen.)
164
Etwas Mathe: Taschen(geld)rechner

Kapitel
6

<?php
if (isset($_POST['a']) && is_numeric($_POST['a']) &&
isset($_POST['b']) && is_numeric($_POST['b'])) {
$c = $_POST['a'] - $_POST['b'];
echo "<p>Das Ergebnis lautet $c</p>\n";
}
?>

Ein weiterer Vorteil: Fehleingaben wie Buchstaben oder Leerzeichen werden
auf diese Weise von vornherein ignoriert. Das Beispiel findest du unter dem
Namen rechner_autor.php auf der CD zum Buch!
$_SERVER['PHP_SELF']: Daten an
sich selbst schicken
Wirf doch einmal einen kritischen Kontrollblick auf das Formular. Auf die
erste Zeile deines Formulars. Die Aktion interessiert uns. Bisher haben wir
hier den Dateinamen notiert:
<form action="rechner.php" method="post">

oder auch:
<form action="rechner_hund.php" method="post">

Eigentlich ist das eine zuverlssige und sichere Lsung. Doch wenn du den
Namen der eigentlichen Datei nderst? Und wenn du dann vergisst, auch
den Wert hinter action zu ndern? Dann klappt die Formularauswertung
natrlich erst einmal nicht und die Fehlersuche beginnt.
Da gibt es eine beliebte, allerdings nicht sonderlich sichere Lsung!
Es gibt eine sogenannte Servervariable, die Namen und Pfad der Datei
zurckgibt. Diese Variable steht im Array $_SERVER zur Verfgung. Der
entsprechende key (Schlsselwert) fr diesen Fall heit 'PHP_SELF'.
Notiere also $_SERVER['PHP_SELF']; und schon hast du den schns-
ten Selbstverweis. Denn diese Variable enthlt im aktuellen Fall den Na-
men rechner.php oder rechner_hund.php (mit Pfad), je nachdem,
wie dein PHP-Dokument heit.
165
Wie viel bleibt brig? Prozentrechnung!

Mit anderen Worten: Du kannst dein Formular auch so einleiten:
<form action="<?php echo $_SERVER['PHP_SELF']; ?>"
method="post">

Vergiss jedoch keinesfalls die Anweisung echo. Erst damit sorgst du dafr,
dass der in der Variablen $_SERVER['PHP_SELF'] steckende String aus-
gegeben und hinter action geschrieben wird.
Diese Variante wird von Sicherheitsexperten leider als kritisch eingestuft,
da auch der Inhalt von Servervariablen wie $_SERVER['PHP_SELF']
durch Hacker manipuliert werden kann. Im Buch verwende ich sie des-
halb nicht.
Wenn du dir wirklich die Arbeit erleichtern willst, lsst du das Gnsef-
chenpaar hinter action einfach leer. Das Versenden klappt trotzdem. Denn
dadurch bleibt die aktuelle Datei automatisch der Empfnger der Formular-
daten.
Den Trick hatte ich dir ja weiter vorne schon verraten.
Wie viel bleibt brig?
Prozentrechnung!
Lust auf Prozentrechnung? Richtig, die Sache mit den Torten. Soviel zu-
mindest ist bei mir vom Matheunterricht noch brig geblieben. Und auch in
PHP kannst du natrlich nach Herzenslust Stcke aus der Torte heraus-
schneiden.
Nimm einfach das vorhandene Dokument, passe es an und speichere es
unter dem Namen prozent.php. Vergiss nicht, den Wert hinter action
anzupassen, im Beispiel muss dieser jetzt natrlich prozent.php lauten.
Du kannst auch <?php echo $_SERVER['PHP_SELF']; ?> als Wert
hinter action eintragen, auch wenn es nicht die sicherste Lsung ist. Oder
du lsst das Gnsefchenpaar einfach leer das funktioniert auch!
Der Quelltext im berblick
Im Beispiel mchtest du ermitteln, wie viel Prozent vom Taschengeld noch
brig geblieben sind. Du gibst Grundwert und Prozentwert ein und ermit-
telst den Prozentsatz. Die Einnahme entspricht dabei stets 100%, doch die
Ausgabe, also der Prozentsatz?
166
Etwas Mathe: Taschen(geld)rechner

Kapitel
6 Mathematisch lsst sich das mit einem Dreisatz lsen. Du kannst auch
Verhltnisgleichung dazu sagen. Die Einnahme ist bekannt, diese setzt du
zu 100% (Wert 100) ins Verhltnis. Auch die Ausgabe kennst du, doch es
fehlt die Angabe fr Prozent. Du berechnest also Ausgabe * 100,
geteilt durch Einnahme.
Hier prsentiere ich dir nun den Quelltext im berblick.
<?php
if (isset($_POST['a']) && is_numeric($_POST['a']) &&
isset($_POST['b']) && is_numeric($_POST['b'])) {
$c = $_POST['a'] - $_POST['b'];
$d = $_POST['b'] * 100 / $_POST['a'];
echo "<p>Das Ergebnis lautet $c.</p>\n";
echo "<p>Ausgegeben wurden also $d Prozent.</p>\n";
}
?>

Teste das Skript ruhig einmal aus. Nimm fr den Anfang einfache Werte.
Du kannst als Einnahme 100 und als Ausgabe z. B. 20 notieren. Das Skript
sollte nun auch fr Prozent eine 20 ermitteln.
Die Funktion round() zum Runden
Mache einmal ein Experiment mit krummen Werten! Gib bei der Einnahme
eine 12 ein. Ausgegeben hast du dagegen 5 Euro 50 Cent: Fr die Ausgabe
notierst du also 5.5 (mit Punkt statt Komma, nicht vergessen!) und klickst
auf BERECHNEN.

Huch, so eine lange Prozentzahl? So genau wolltest du es vielleicht gar
nicht wissen? Du wnschst die Prozentangabe lieber mit zwei oder ganz
und gar ohne Nachkommastellen?
Bei krummen Werten
erfolgt die Ausgabe
langer Nachkomma-
stellen.
167
Wie viel bleibt brig? Prozentrechnung!

Nutze die Funktion round(). Die Syntax lautet:
round(Wert, Nachkommastellen)
Fr den Platzhalter Nachkommastellen notierst du einfach den ge-
wnschten Wert, z. B. 2 oder 0. Im Beispiel werde ich den Prozentsatz mit
zwei Nachkommastellen ausgeben. Dazu fge ich eine zustzliche Zeile ein:
echo "<p>Das Ergebnis lautet $c.</p>\n";
$d = round($d, 2);
echo "<p>Ausgegeben wurden also $d Prozent.</p>\n";

Die Zahl in der Variablen $d wird lediglich gerundet und erneut in $d ge-
speichert. Das Ergebnis kann sich sehen lassen:

Du findest das Skript unter dem Namen round.php auf der CD!
Zahlen formatieren mit sprintf()
So ganz zufrieden bin ich bisher jedoch immer noch nicht. Die Prozentzahl
haben wir wunderbar gerundet. Doch was ist mit dem Dezimalbruch fr die
Whrung? Diese Zahl erscheint mal ohne Dezimalstellen, mal mit einer (wie
im Beispiel) oder in manchen Fllen mit zweien. Gerade fr die Ausgabe der
Whrung wre eine einheitliche Schreibweise schn!
Die Zahl sollte stets mit zwei Nachkommastellen angezeigt werden! Kein
Problem, diesen Wunsch erfllt uns die Funktion sprintf(). Diese Funkti-
on formatiert einen String (oder eine Zahl) und gibt diese formatiert zu-
rck.
Die Grundsyntax lautet:
sprintf("Formatieranweisung", Argument2)
Das zweite Argument ist klar, da setzen wir die Variable $c ein. Doch wie
sieht das erste Argument aus, welche Formatieranweisung sollen wir neh-
men?
Gerundet sieht der
Prozentsatz doch viel
schner aus!
168
Etwas Mathe: Taschen(geld)rechner

Kapitel
6 Die von mir empfohlene Formatieranweisung heit %01.2f. Bitte frage
mich nicht, was sich genau hinter dieser Zeichenfolge verbirgt, sondern
merke sie dir einfach. Die von dir zu verwendende Funktion lautet im
Beispiel demnach sprintf("%01.2f", $Variable). Diese Formatier-
anweisung sorgt dafr, dass der Wert der Variablen stets mit
zwei Nachkommastellen ausgegeben wird.
Probiere es aus. Das derart erweiterte Skript sieht folgendermaen aus. Auf
der CD findest du es unter dem Namen sprintf.php:
<?php
if (isset($_POST['a']) && is_numeric($_POST['a']) &&
isset($_POST['b']) && is_numeric($_POST['b'])) {
$c = $_POST['a'] - $_POST['b'];
$d = $_POST['b'] * 100 / $_POST['a'];
$c = sprintf("%01.2f", $c);
echo "<p>Das Ergebnis lautet $c.</p>\n";
$d = round($d, 2);
echo "<p>Ausgegeben wurden also $d Prozent.</p>\n";
}
?>



Im gewissen Sinne besteht eine Verwandtschaft zu round(): Zuviel Nach-
kommastellen werden gerundet. Im Gegensatz zu round() fllt
sprintf() die fehlenden Nachkommastellen jedoch mit Nullen auf.
Schnell noch ein Supertipp von mir! Wie wre es mit der Ausgabe der
Whrung? Auch das kannst du mit der Funktion sprintf() erledigen!
Schreibe einfach sprintf("%01.2f Euro", $c) und schon erscheint
hinter dem Wert der Text Euro.
Der Wert wird nun
stets mit zwei
Nachkommastellen
angezeigt.
169
Traurige Sulen: Ergebnis als Diagramm


Die Formatier-Funktion eignet sich sogar zur Ausgabe der Zeichenfolge Euro.
Vergleiche mit dem Quelltext der Datei sprintf_euro.php von der CD!
Du gibst einen Ausgabewert ein, der hher liegt als der Einnahmewert?
Oder sogar eine negative Zahl? Dann entspricht der ermittelte Prozent-
wert mglicherweise nicht deinen Erwartungen! Um ganz professionell
vorzugehen, knntest du diese Fehleingaben durch if-Abfragen abfan-
gen. Und so wird es in der Praxis auch tatschlich gemacht. (Mehr zu
dieser Technik erfhrst du im Kapitel 8.) Im Beispiel verzichten wir je-
doch aus Grnden der Vereinfachung darauf!
Traurige Sulen: Ergebnis als
Diagramm
Hast du Lust, mit den Zahlen etwas zu spielen? Erstelle zur Abwechslung
doch einmal ein Sulendiagramm. Bei dieser Gelegenheit rundest du den
Prozentwert so, dass keine Nachkommastellen brig bleiben.

Zuerst zeige ich dir den kompletten Quelltext im berblick. Danach folgt
die kurze Erklrung. Aber eigentlich ist da gar nicht viel zu erklren.
Einfach aber wir-
kungsvoll: Ein Su-
lendiagramm zur
Visualisierung der
Daten.
170
Etwas Mathe: Taschen(geld)rechner

Kapitel
6
<?php
if (isset($_POST['a']) && is_numeric($_POST['a']) &&
isset($_POST['b']) && is_numeric($_POST['b'])) {
$c = $_POST['a'] - $_POST['b'];
$d = $_POST['b'] * 100 / $_POST['a'];
$c = sprintf("%01.2f Euro", $c);
echo "<p>Das Ergebnis lautet $c.</p>\n";
$d = round($d, 0);
echo "<p>Ausgegeben wurden also $d Prozent.</p>\n";
echo "<h3>Vergleichsdiagramm:</h3>\n";
echo "<table><tr>";
echo "<td width='100' bgcolor='green'>&nbsp;</td>";
echo "<td>Einnahme</td></tr></table>\n";
echo "<table><tr>";
echo "<td width='$d' bgcolor='red'>&nbsp;</td>";
echo "<td>Ausgabe</td></tr></table>\n";
}
?>

Der Trick besteht einfach darin, mit Tabellen zu arbeiten. Du bentigst so
viele Tabellen wie Sulen, im Beispiel also zwei. Jede Tabelle besteht nur
aus einer einzigen Zeile und zwei Zellen. Die Zelle der ersten Tabelle ist 100
Pixel breit (width='100') und besitzt die Hintergrundfarbe grn
(bgcolor='green'). Das habe ich so vorgegeben.
Die Breite der zweiten Tabellezeile wird dagegen durch den Prozentwert
gesteuert. Und dieser liegt dank unserer Rundung auf Ganzzahlen genau
zwischen 0 und 100. Zumindest solange wie du positive Zahlen eintrgst,
die nicht ber dem Eingabewert liegen.
Wozu habe ich das Zeichen &nbsp; in der Tabellenzelle notiert? Das mache
ich deshalb, weil die Zelle nicht leer gelassen werden darf. Erst mit diesem
geschtzten Leerzeichen sorge ich dafr, dass die Zelle nicht als leer be-
trachtet wird und formstabil bleibt. Das Beispiel findest du in der Datei
diagramm.php auf der Buch-CD.
Plus, Minus, Mal, Geteilt? Select!
Als nchstes Beispiel schlage ich einen simplen Taschenrechner vor. Dazu
erweiterst du einfach das Subtraktions-Beispiel. Du kannst eines der ersten
Beispiele verwenden, die Prozentrechnung und das Sulendiagramm inte-
ressieren hierbei nicht.
171
Plus, Minus, Mal, Geteilt? Select!

Bist du bereit? Subtrahieren ist out, Wahlfreiheit ist in: Per Auswahlfeld
whlst du die gewnschte Rechenoperation, egal ob Addition, Subtraktion,
Multiplikation oder Division.

Das Prinzip ist eigentlich gar nicht so schwer. Im Formular ergnzt du das
Auswahlfeld (<select></select>). Und im PHP-Teil liest du dieses Feld
aus.
Der Quelltext im berblick
Zuerst zeige ich dir den Quelltext im berblick. Danach besprechen wir das
Wichtigste! Die Datei selber heit im Beispiel select1.php.
<h2>Taschenrechner</h2>
<form action="select1.php" method="post">
<p>Zahl 1: <input type="text" name="a"><br>
Rechenoperation:
<select name="rz">
<option>+</option>
<option>-</option>
<option>*</option>
<option>/</option>
</select><br>
Zahl 2: <input type="text" name="b"></p>
<input type="submit" value="Berechnen">
</form>
<?php
if (isset($_POST['a']) && is_numeric($_POST['a']) &&
isset($_POST['b']) && is_numeric($_POST['b'])) {
switch($_POST['rz']) {
case "+":
$c = $_POST['a'] + $_POST['b'];
break;
Ein simpler Taschenrech-
ner mit PHP. Die Auswahl
erfolgt per SELECT-
Auswahlfeld.
172
Etwas Mathe: Taschen(geld)rechner

Kapitel
6

case "-":
$c = $_POST['a'] - $_POST['b'];
break;
case "*":
$c = $_POST['a'] * $_POST['b'];
break;
case "/":
$c = $_POST['a'] / $_POST['b'];
break;
}
echo "<p>Das Ergebnis lautet <b>$c</b></p>\n";
}
?>
So liest du ein SELECT-Feld aus
Das Herzstck des Skriptes ist das neue Feld SELECT wie Auswhlen. Dieses
Feld wird von <select></select> eingehllt. Die einzelnen Tags
<option></option> bilden die verschiedenen Optionen. Also die Aus-
wahlmglichkeiten, die in der Liste herunterklappen. In diesem Fall handelt
es sich um die vier Grundrechenoperatoren.
Das Auswahlfeld
Fertig ist das wunderbare Auswahlfeld, unsere praktische Klappliste.
<select name="rz">
<option>+</option>
<option>-</option>
<option>*</option>
<option>/</option>
</select>

Auerdem gebe ich dem Feld im einleitenden Tag <select> noch einen
Namen mit auf dem Weg. Ich nenne das Feld rz (wie Rechenzeichen).
Je nach Auswahl schickt das Feld den entsprechenden Value zurck, also
entweder den String +, -, * oder /. So einfach ist das.
Auch nicht weiter kompliziert ist die Auswertung im PHP-Teil! Hier arbeite
ich mit der aus dem vorigen Kapitel bekannten switch-Anweisung. Erin-
173
So liest du ein SELECT-Feld aus

nerst du dich? Eine Variable wird auf das Vorhandensein eines Wertes ge-
prft, hier die Variable $_POST['rz']:
switch($_POST['rz']) {

Bei bereinstimmung mit einem bestimmten Wert wird die jeweilige Re-
chenoperation ausgefhrt, z. B. die Addition.
case "+":
$c = $_POST['a'] + $_POST['b'];

Die Ausfhrung wird dann durch das Schlsselwort break abgebrochen.
break;

So funktioniert es auch bei den anderen drei Fllen, zumindest sinngem.
In diesem Fall kannst du auf den default-Zweig verzichten, da die Variab-
le $_POST['rz'] sowieso nur einen der vier Werte annehmen kann. Zum
Vergleichen: Du findest das Beispiel auch in der Datei select1.php.
Werte in Formularfeldern speichern
So schn unser Rechner bisher funktioniert: Eine Sache ist recht rgerlich.
Nach Klick auf BERECHNEN wird zwar das Ergebnis angezeigt. Doch die Wer-
te sind lngst aus den Eingabefeldern verschwunden.
Kein Problem, speichere die Werte einfach dauerhaft in den Formularfel-
dern. Wie? Mit einem kleinen Trick. Baue die beiden Zahlen-Eingabefelder
im Formular einfach um. Schreibe statt
<p>Zahl 1: <input type="text" name="a"><br>

einfach folgende aufgebohrte Zeile:
<p>Zahl 1: <input type="text" name="a" value="<?php
if (isset($_POST['a']) && is_numeric($_POST['a'])) {
echo $_POST['a'];
}
?>"><br>

ndere auch die zweite input-Zeile von
Zahl 2: <input type="text" name="b"></p>

in
174
Etwas Mathe: Taschen(geld)rechner

Kapitel
6

Zahl 2: <input type="text" name="b" value="<?php
if (isset($_POST['b']) && is_numeric($_POST['a'])) {
echo $_POST['b'];
}
?>"></p>

Der Trick ist schnell erklrt: Du notierst einfach zustzlich das Attribut
value in den beiden <input>-Formularfeldern. Damit lsst sich ein Wert
schon vorher in das Formular eintragen. Den Wert schreibst du jedoch nicht
fest, sondern dynamisch in das Feld, und zwar ber einen kurzen PHP-
Abschnitt. Notiere also die Anweisung <?php ... p>. Prfe innerhalb des
PHP-Bereichs zuerst, ob $_POST['a'] bzw. $_POST['b'] existieren.
Dann gibst du die Werte aus mit echo $_POST['a'] bzw. echo
$_POST['b'].
Du findest das Skript unter dem Namen select2.php auf der CD zum
Buch.
Rechner de luxe: Wir schreiben
eine Funktion
An dieser Stelle folgt nun die groe Herausforderung von Kapitel 6. Sozu-
sagen der Hhepunkt. Bist du bereit? Stelle deinen Gehirnkasten auf Emp-
fang, denn du schreibst eine eigene Funktion! Eine Funktion fr das Re-
chenskript!
Zugegeben, an der Funktionalitt des kleinen Taschenrechner-Pro-
gramms wird sich dabei nichts ndern. Zumindest nicht nach auen.
Aber du bist nach dieser Aktion um einige wichtige Kenntnisse reicher.
Und das sollte doch die Mhe allemal wert sein, oder?
Was ist eine Funktion?
Eine Funktion ist eigentlich nichts weiter, als eine Sammlung von Pro-
grammzeilen. Es ist ein Programmabschnitt, der etwas fr dich tut. Ein
Programmbereich mit einem speziellen Namen. Man kann eine Funktion
aufrufen, bergibt ihr ein paar Argumente und bekommt das verarbeitete
Ergebnis zurck. Klingt zu kompliziert?
175
Rechner de luxe: Wir schreiben eine Funktion

Denke einfach an die vordefinierten Funktionen. Es gibt hunderte davon in
PHP. Einige kennst du schon, andere bringe ich dir im Verlauf des Buches
noch bei. Die Funktion isset($variable) z. B. prft eine Variable auf
Existenz. Sie gibt je nach Sachstand den Wahrheitswert true oder false
zurck. Die bergebene Variable (der Prfling) wird hierbei auch als Argu-
ment bezeichnet.
Eine Funktion kann auch mehrere Argumente besitzen. Erinnerst du dich an
die Funktion sprintf(), die wir eben besprochen haben? Nimm die Zeile:
$c = sprintf("%01.2f", $c);

Die Funktion besitzt gleich zwei Argumente, die durch ein Komma getrennt
werden. Das erste Argument steckt in der Formatieranweisung. Das zweite
Argument ist der Wert, der formatiert wird. Im Beispiel gibt die Funktion
den formatierten Wert zurck, der hier erneut in der Variablen $c gespei-
chert wird.
Halten wir fest: Eine Funktion besitzt ein paar runde Klammern, die sich
ohne Leerzeichen nahtlos an den Funktionsnamen anschlieen. Innerhalb
der runden Klammern werden die sogenannten Argumente bergeben.
Mehrere Argumente trennt man durch ein Komma voneinander. Eine
Funktion gibt in der Regel etwas zurck, das kann ein String, eine Zahl
oder ein Wahrheitswert sein.
Keine Bange: Ob du nach einem Komma hinter einem Argument ein
Leerzeichen lsst oder nicht, bleibt dir berlassen. Ein Leerzeichen erhht
die bersicht, muss aber nicht unbedingt sein. In der Praxis findest du
stets beide Varianten vor.
Funktionen selber schreiben
Ich hatte vorhin behauptet, dass eine Funktion eine Sammlung von Pro-
grammzeilen ist. Eine Art Programm-Modul also, was auf Abruf zur Verf-
gung steht. Wo stecken denn diese Programmzeilen? Bei den vordefinierten
Funktionen ist die Antwort ganz einfach: Sie sind in PHP fest eingebaut, du
bekommst sie nicht zu Gesicht. Vordefinierte Funktionen arbeiten wie ein
schwarzer Kasten, in den man etwas hineintut und etwas anderes zurck-
bekommt.
Ganz anders sieht die Sache aus, wenn du eine Funktion selber schreibst.
Dann kannst du bestimmen, was in der Funktion passiert, denn du baust
den Funktions-Kasten selber zusammen. Doch warum solltest du das ber-
haupt tun?
176
Etwas Mathe: Taschen(geld)rechner

Kapitel
6
0 Funktionen sind ideal, wenn du eine bestimmte Funktionalitt in PHP
vermisst, aber hufig bentigst.
0 Funktionen sind dann sinnvoll, wenn du eine dieser Aktionen immer
wieder durchfhren willst.
Im Klartext: Funktionen sind etwas fr Faule, die sich ihre Codezeilen
gerne aufbewahren. Und natrlich etwas fr Pfiffige, die damit in man-
chen Fllen viel Schreibarbeit sparen.
Grundsyntax einer Funktion
Wenden wir uns von der Theorie nun der Praxis zu: Die Grundsyntax einer
Funktion sieht folgendermaen aus, beachte das einleitende Schlsselwort
function vor dem Funktionsnamen:
function Funktionsname(Argument[, Argument])
{
Codezeile(n);
return $variablenwert;
}

Zusammengehalten wird der Funktions-Block wieder durch geschweifte
Klammern diesmal bekommt die einleitende Klammer eine eigene Zeile!
Wie schon bei Variablennamen gilt auch bei Funktionsnamen: Gro- und
Kleinschreibung werden unterschieden. Leerzeichen, Umlaute und die
meisten Sonderzeichen sind tabu. Beginne einen Funktionsnamen nie mit
einer Zahl. Der Unterstrich (_) jedoch ist erlaubt.
Nehmen wir einmal an, du bentigst eine Funktion, die bei einem Produkt-
preis aus dem Nettowert den Bruttowert berechnet. So eine Funktion gibt
es nicht in PHP. Der Nettowert ist der Preis des Produktes ohne die soge-
nannte Mehrwertsteuer. (Hinter der Mehrwertsteuer verbirgt sich eine Ab-
gabe, die in Deutschland auf fast jedes Produkt aufgeschlagen wird und die
du damit automatisch mit bezahlst.) Diese Mehrwertsteuer betrgt 19%.
Die Berechnung selber ist simpel: Du brauchst nur den Nettowert mit 1.19
zu multiplizieren. Das ist schon alles.
Ich nenne die Funktion nettoinbrutto(), weil sie den Nettowert in ei-
nen Bruttowert umwandelt. Erstelle eine neue PHP-Seite und mache mit!
Die Funktion besitzt nur ein einziges Argument:
177
Der Rechner im Einsatz

function nettoinbrutto($wert)
{
$wert = $wert * 1.19;
return $wert;
}

Die Funktion nimmt das Argument entgegen, multipliziert es mit 1.19 und
gibt diesen Wert zurck. Innerhalb der Funktion wird dafr die Variable
$wert verwendet.
Variablen, die du in der Funktion deklarierst, haben normalerweise auch
nur innerhalb dieser Funktion Gltigkeit. Die Variable $wert ist im bri-
gen Skript nicht sichtbar. Auch umgedreht gilt diese Regel. Die Funktion
kann nur auf die Werte zurckgreifen, die du ihr als Argument bergibst.
berprfe, ob die Funktion funktioniert. Ergnze unterhalb der Funktion
noch folgende Zeilen:
$zahl = 100;
$zahl = nettoinbrutto($zahl);
echo $zahl;

Herauskommen muss 119. (Die Mehrwertsteuer betrgt in diesem Fall also
19, da 19% von 100 19 sind.) Und, klappt es? Statt dieser drei Zeilen
kannst du auch schreiben:
echo nettoinbrutto(100);

Das Beispiel findest du in der Datei mwst.php.
Der Rechner im Einsatz
Soweit zu den Vorbemerkungen. Zurck zu unserem Rechner, zur Datei
select1.php oder vielmehr der verbesserten Variante select2.php.
Speichere das Dokument ruhig unter einem anderen Namen, ich schlage
nun function.php vor.
Nach diesen Vorbungen knnen wir uns endlich an die groe Funktion
wagen. Es geht um die Funktion zum Berechnen! Unsere Funktion selber
nenne ich berechne() und bergebe ihr gleich drei Argumente. Es sind
die erste Zahl, die zweite Zahl und der entsprechende Rechenoperator.
178
Etwas Mathe: Taschen(geld)rechner

Kapitel
6
Und nun zeige ich dir, wie ich den PHP-Teil aufgebaut habe. Dank der neu-
en Funktion konnte ich hier erst einmal radikal ausmisten:
<?php
if (isset($_POST['a']) && is_numeric($_POST['a']) &&
isset($_POST['b']) && is_numeric($_POST['b'])) {
include("function_modul.inc.php");
$c = berechne($_POST['a'], $_POST['b'], $_POST['rz']);
echo "<p>Das Ergebnis lautet <b>$c</b></p>\n";
}
?>

brig geblieben sind neben der if-Abfrage und der echo-Zeile fr das
Ergebnis nur noch zwei weitere Zeilen. Das nennt man klar und bersicht-
lich, findest du nicht? Das Berechnen wird von der neuen Funktion ber-
nommen. Die ganzen langen switch-Zeilen und all das Programmge-
strpp verschwindet damit in der Funktionskiste. Doch ehe wir uns die
Kiste anschauen, betrachten wir den Funktionsaufruf. Der Funktionsauf-
ruf erfolgt in der Zeile:
$c = berechne($_POST['a'], $_POST['b'], $_POST['rz']);

Die Funktion nimmt die drei Argumente entgegen, berechnet das Ergebnis
und gibt dieses zurck. Das Skript speichert das Ergebnis in der Variablen
$c und gibt den Inhalt mit echo() aus.
Doch was ist mit der Funktion selber? Wo steckt die? Hier verwendet der
Autor die Modulbauweise. Die Codezeilen fr die Funktion selber hat er
in einer separaten externen Datei abgelegt. Die Datei wird dabei ober-
halb des Funktionsaufrufes eingebunden. Das sollte man tun, damit die
Funktion noch vor dem Aufruf eingelesen werden kann. So steht sie
praktisch schon auf Abruf bereit. Fr das Einbinden dieser externen Da-
tei dient die im vorigen Kapitel besprochene include()-Anweisung.
include("function_modul.inc.php");
Diese externe Datei heit function_modul.inc.php und liegt im Bei-
spiel im gleichen Ordner. Warum diese Doppelendung, warum nicht ein-
fach function.txt? Die Endung .php ist ideal, weil dadurch der Code
nicht sichtbar ist. Denn PHP-Dateien werden vom Webserver nicht im
Klartext angezeigt. Die davor platzierte Endung .inc steht fr include,
einfgen. So weit du also, dass es eine externe Include-Datei ist, die du
an dieser Stelle einfgst.
179
Der Rechner im Einsatz

Quellcode der Datei function_modul.inc.php
Nun zur Funktionskiste selber. Schau dir dafr den Quellcode der externen
Datei mit dem gewichtigen Namen function_modul.inc.php an. (Den
Namen function_modul habe ich so gewhlt, dass er mglichst selbster-
klrend ist.)
Gibt es da Besonderheiten? Da die Datei als PHP-Datei deklariert wurde,
muss sie zum einen auch von <?php ... ?> eingehllt werden. Nur so
kann der Quellcode nicht von jedermann eingesehen werden, wenn die
Seite zufllig direkt aufgerufen wird. Auerdem habe ich am Anfang ein
paar Kommentarzeilen eingefgt, damit ich spter noch verstehe, was die
Funktion berhaupt macht.
<?php
// Funktion fr Grundrechenarten
// Argumente: Zahl 1, Zahl 2 und Rechenoperator
// zurckgegeben wird das Ergebnis
function berechne($zahl1, $zahl2, $operator)
{
switch($operator) {
case "+":
$ergebnis = $zahl1 + $zahl2;
break;
case "-":
$ergebnis = $zahl1 - $zahl2;
break;
case "*":
$ergebnis = $zahl1 * $zahl2;
break;
case "/":
$ergebnis = $zahl1 / $zahl2;
break;
}
return $ergebnis;
}
?>

Programmtechnisch jedoch bietet die Funktion nichts Neues. Es ist genau
die gleiche switch-Anweisung, die ich schon fr die erste Version dieses
Rechners verwendet habe. Nur fr die Variablen habe ich mir neue Namen
ausgedacht, aber diese existieren sowieso nur innerhalb der Funktion.
180
Etwas Mathe: Taschen(geld)rechner

Kapitel
6
Wichtig sind weiterhin die geschweiften Klammern, die den Funktionsblock
bilden. Auerdem muss das Ergebnis der Funktion mit return $ergebnis
zurckgegeben werden. Denn unsere Funktion braucht schlielich einen
Rckgabewert.
Blickst du da auf Anhieb durch? Herzlichen Glckwunsch! Dann hast du
schon ein wichtiges Stck fortgeschrittener PHP-Programmierung ver-
standen. Wenn nicht, ist es auch nicht so schlimm. Du kannst fast alle
Programme auch ohne Funktion schreiben.
Im Fortgeschrittenen-Band PHP und MySQL Praxisbuch fr Kids gehe ich
nher auf Funktionen ein und mache dich auch mit den Details zur Klam-
mersetzung vertraut.
Schlussbemerkung
In diesem Kapitel haben wir uns mit Mathematik beschftigt. War es
schwer? Ich hoffe nicht, zumindest nicht am Anfang. Du kennst die Grund-
lagen fr das Rechnen mit PHP und hast dich sogar an die Prozentrech-
nung gewagt. Du kannst Diagramme zeichnen und Auswahlfelder erstellen.
Das Beste: Du hast in das Thema PHP fr Fortgeschrittene hereingeschnup-
pert und weit sogar schon, wie man eigene Funktionen zusammenbaut.
Fr das sechste Kapitel ist das schon nicht schlecht, oder?
Zusammenfassung
0 Du kennst die vier Grundrechenarten und die entsprechenden Operato-
ren +, -, * und /.
0 Du kennst die Operatoren zum Inkrementieren (um 1 erhhen) und De-
krementieren (um 1 erniedrigen), sie lauten ++ und --.
0 Du kennst die Funktion empty(). Damit kannst du testen, ob eine Vari-
able nicht gesetzt ist, ob sie leer ist oder ob sie dem Wert 0 entspricht.
0 Du kennst die Funktion is_numeric(). Sie testet, ob eine Variable eine
Zahl ist und gibt dann true zurck.
0 Du kennst die Server-Variable $_SERVER['PHP_SELF'], die den Pfad
und Dateinamen der aktuellen Datei ausgibt. Du weit jedoch, dass sie
ein Sicherheitsrisiko darstellt und sparsam eingesetzt werden sollte.
181
Ein paar Fragen

0 Du hast dich mit Prozentrechnung beschftigt und weit, wie du mit
unsichtbaren Tabellen ein Sulendiagramm zeichnen kannst.
0 Du kennst die Funktionen round() und sprintf() zum Runden bzw.
Formatieren von Zahlen.
0 Du kennst das Konzept der Funktionen, der Speicherksten fr eine
Abfolge von Befehlen. Neben den vielen in PHP eingebauten Funktionen
weit du nun auch, wie man eigene Funktionen schreibt.
Ein paar Fragen
1. Wie sieht der Rechenoperator aus fr Geteilt durch?
2. Mit welcher Funktion kannst du Zahlen so formatieren, dass stets eine
bestimmte, aber von dir frei whlbare Zahl von Nachkommastellen an-
gezeigt wird?
3. Welche Doppelendung vergibt man gerne an ausgelagerte Include-
Dateien und warum?
4. Wie schreibt man Eineinhalb als Dezimalbruch in PHP? Warum verwen-
det man das von dir gewhlte Trennzeichen?
und ein paar Aufgaben
1. Der Taschenrechner (Datei function.php) hat noch einen Haken.
Whle doch einmal die Division und trage ins Feld 2 eine 0 ein! Eine
Fehlermeldung ist die Folge. Klar, denn eine Division durch 0 ist nicht
definiert! Deine Aufgabe: Sorge dafr, dass die Rechnung zumindest
dann nicht durchgefhrt wird, wenn der Nutzer in Feld 2 eine 0 eingibt.
Speichere das Dokument unter dem Namen taschenrechner.php.
2. Verndere das Diagramm-Skript (diagramm.php) so, dass die Sulen
doppelt so lang sind wie in der bisherigen Variante.
3. Sorge auerdem dafr, dass der Inhalt der Formularfelder fr die Einga-
be der Zahlen nach dem Abschicken nicht gelscht wird.
4. Berechne die Versandkosten fr ein Produkt. Nutze dafr eine Seite, die
du versand.php nennst. Das zu bestellende Produkt soll 20 Euro kos-
ten. Erzeuge auf dieser Bestellseite also ein Formularfeld, in das der
Nutzer die Produktanzahl eintragen kann. Liegt der Bestellwert unter
100 Euro, sollen die Versandkosten 10 Euro betragen. Liegt der Wert je-
doch hher, fallen die Versandkosten auf 5 Euro. Gib den entsprechen-
182
Etwas Mathe: Taschen(geld)rechner

Kapitel
6
den Gesamtpreis in Abhngigkeit von der eingetragenen Bestellmenge
aus. (Wie du die Seite optisch aufbaust, bleibt dir berlassen.)
5. ffne das Dokument mwst.php. Notiere hier eine zweite Funktion, die
diesmal den Nettowert aus dem Bruttowert berechnet. Dazu erkundige
dich, wie hoch die Mehrwertsteuer zur Zeit in Deutschland ist. Beachte,
dass der Bruttowert bei 19 Prozent mit 119% angesetzt werden muss,
wobei der Nettowert dann 100% betrgt. Bekommst du das hin mit
dem Dreisatz?

183



7
Schleifen: Die
Gratulationsmaschine
Wenn mich einer fragt: Was ist das Wichtigste beim Programmieren?
Dann antworte ich ohne zu zgern: Die Schleife. Denn erst mit Schleifen
sorgst du dafr, dass Befehle immer und immer wiederholt werden knnen.
Wie meistens gibt es auch diesmal einen Haken an der Geschichte. Schlei-
fen gehren zu den nicht ganz einfach zu durchschauenden Elementen.
Aus diesem Grund nhern wir uns dem Thema sanft und vorsichtig. Bei-
spiele, Abbildungen und Diagramme sollen dir das Verstndnis erleichtern.
Du lernst in diesem Kapitel, wie du
$ eine while-Schleife erstellst
$ die do-while-Schleife nutzt
$ eine for-Schleife erzeugst
$ mit foreach alle Elemente eines Arrays durchlufst
Und wenn du nach dem Lesen feststellst: Schleifen, Mann: Das ist doch
cool und easy! dann hat das Kapitel seinen Zweck erfllt.

184
Schleifen: Die Gratulationsmaschine

Kapitel
7 Die while-Schleife
Wir fangen ganz gemtlich mit der while-Schleife an, werfen einen Blick
auf do-while und landen dann bei for und foreach. Doch halt, was sind
Schleifen berhaupt?
Schleifen dienen dazu, eine Anweisung in Abhngigkeit von einer oder
mehreren Bedingungen wiederholt ausfhren zu knnen.
Alles unklar? Kein Problem, das ging mir am Anfang auch so! Das Schls-
selwort lautet Wiederholung. Repetitio est mater studiorum, sagte mein
alter Lateinlehrer immer. Frei bersetzt heit das: Wiederholung ist die
Mutter der Porzellankiste. (Zugegeben, das ist etwas zu frei bersetzt, aber
auch Latein hat nie zu meinen Strken gezhlt.)
Zurck zu den Schleifen. Ein Beispiel muss her! Was wiederholt sich in
deinem Leben? Der Tag deiner Geburt! Wie alt bist du? 6, 14 oder gar 42
wie der Schreiber dieser Zeilen? Programmiere doch einmal eine Schleife,
die den Satz wiederholt: Happy Birthday! Und zwar so oft, wie es deinem
Alter entspricht.
Der Quelltext fr die Schleife
Zuerst zeige ich dir den gesamten Quelltext zwischen den Tags
<body></body>. Du kannst das Dokument abschreiben und unter dem
Namen while.php speichern.
<h2>Die while-Schleife</h2>
<form action="while.php" method="post">
Wie alt bist du?
<input type="text" name="anzahl">
<input type="submit" value="Absenden">
</form>
<p>
<?php
if (!empty($_POST['anzahl'])) {
$i = 1;
while ($i <= $_POST['anzahl']) {
echo "Happy Birthday!<br>\n";
$i++;
}
185
Die while-Schleife


echo "Schleife wurde verlassen.\n";
}
?>
</p>

Probiere es aus. Funktioniert das mit der Wiederholung?

Einiges kommt dir sicher schon bekannt vor. Du erzeugst ein Formular zur
Eingabe des Alters. Nach Absenden wird der Inhalt des Feldes anzahl ab-
geschickt und an den PHP-Teil bergeben. Dort kommt wieder unser be-
whrter Test zum Einsatz, der prft, ob die Variable existiert und nicht etwa
leer ist bzw. 0 entspricht.
So weit, so bekannt. Doch was passiert innerhalb der Schleife, die eigent-
lich nur aus folgenden Zeilen besteht?
while ($i <= $_POST['anzahl']) {
echo "Happy Birthday!<br>\n";
$i++;

Hier wird die Wiederholung festgelegt, und zwar in Abhngigkeit von der
eingegebenen Zahl! Was da genau abgeht, klren wir gleich.
Die Grundsyntax der while-Schleife
Schaue dir zuerst die Grundsyntax der while-Schleife an.
while (Bedingung) {
Befehlszeilen immer wieder ausfhren, solange Bedingung
wahr ist;
}
Fortsetzung, wenn Bedingung falsch;
Du gibst eine 6 ein? Dann
schreibt das Skript
sechsmal Happy Birthday!
186
Schleifen: Die Gratulationsmaschine

Kapitel
7
Was fllt dir auf? Richtig: Auch hier dient wieder ein geschweiftes Klam-
mernpaar zum Zusammenhalten des Schleifenblocks. Die erste Zeile bildet
den Schleifenkopf. Hier wird die Bedingung geprft. Zumindest die Struktur
ist nicht neu, die kennst du ja schon von den if-Abfragen. (Wenn nicht,
blttere ganz fix zwei Kapitel zurck!)
Doch im Gegensatz zu if werden die Anweisungen innerhalb des Blocks
stets wiederholt. Und zwar so lange, bis die Bedingung endlich einmal
falsch geworden ist. Daraus folgt
0 Schleifen brauchen eine sinnvolle Bedingung, die sich auf Wahrheit
prfen lsst.
0 Du musst darauf achten, dass die Bedingung irgendwann wieder falsch
wird.
Bist du ein optischer Typ? Dann kannst du versuchen, dir die Wirkungswei-
se von while anhand dieses Diagramms zu veranschaulichen:

Beachte, dass die Befehle innerhalb der Schleife stets wiederholt werden.
Das ist schlielich der Sinn der Sache. Sie werden so lange wiederholt, bis
die Bedingung falsch ist.
Das Beispiel in der Diskussion
Und nun zu unserer Beispiel-Schleife. Schau dir zuerst die Zeilen an, die im
weiteren Sinne zu unserer Geburtstags-Schleife zhlen. Auch wenn sie
nicht innerhalb des Schleifen-Blocks notiert wurden:
Nur wenn die Bedingung
wahr ist, werden die Befehle
der Schleife ausgefhrt.
187
Die while-Schleife

$i = 1;
while ($i <= $_POST['anzahl']) {
echo "Happy Birthday!<br>\n";
$i++;
}
echo "Schleife wurde verlassen.\n";

Zuerst erzeuge ich eine Zhlvariable $i, die ich gleich mit 1 initialisiere.
Solch eine Variable bentigst du in der Regel. Schlielich musst du dafr
sorgen, dass die Bedingung irgendwann wieder falsch wird.
Zhlvariablen werden gerne mit $i bezeichnet. Diese Benennung ist aber
keinesfalls Pflicht. Du kannst deine Variable auch $zaehler, $kaugummi
oder $fliegenschiss nennen.
In der ersten eigentlichen Schleifenzeile wird nun die Bedingung berprft.
Der Test erfolgt also in dem eben erwhnten Schleifenkopf:
while ($i <= $_POST['anzahl']) {

Was wird hier geprft? Es wird geprft, ob $i kleiner gleich
$_POST['anzahl'] ist, also kleiner gleich dem Wert, den du in das For-
mularfeld eingegeben hast.
Nehmen wir einmal an, du hast eine 6 eingegeben! Die 1 ist kleiner gleich
6. Also wird der Code innerhalb der Schleife ausgefhrt. Der Satz Happy
Birthday wird nebst Zeilenumbruch in das Dokument geschrieben.
echo "Happy Birthday!<br>\n";

Als nchstes wird die Zhlvariable um 1 erhht. Dafr kommt der im vori-
gen Kapitel besprochene Inkrementierungs-Operator ++ zum Einsatz: $i++;
bedeutet so viel wie $i = $i + 1. In der Variablen $i ist nun der Wert 2
gespeichert.
Der Schleifenblock ist zwar zu Ende, doch die Schleife prft die Bedingung
erneut auf Wahrheit: Das ganze Spielchen geht also von vorne los: Ist $i
(nunmehr 2) immer noch kleiner gleich 6? Jawohl, das ist der Fall. Die Be-
dingung ist immer noch wahr und die Schleife kann wiederholt werden.
Also wird der Satz Happy Birthday ein zweites Mal ausgegeben usw. usf.
Erst nach dem 6. Durchlauf (ich wiederhole: danach!) gibt die Prfung der
Bedingung in unserem Falle falsch zurck. Warum? Das ist klar: Nach dem
188
Schleifen: Die Gratulationsmaschine

Kapitel
7
6. Durchlauf hat $i den Wert 7 angenommen. Und der Vergleich 7 ist klei-
ner gleich 6 liefert nicht mehr wahr, sondern falsch.
Damit wird die Schleife verlassen, ein siebter Durchlauf findet nicht statt.
Jetzt wird der Satz unterhalb der Schleife angezeigt:
echo "Schleife wurde verlassen.\n";

Ganz wichtig: Achte unbedingt darauf, dass die Bedingung im Schleifen-
kopf irgendwann einmal falsch (false) zurckgibt. Denn sonst erzeugst
du eine der berchtigten Endlosschleifen. Die Endlosschleife luft Amok,
sie wird immer wieder und wieder ausgefhrt, bis dein Rechner oder der
Webserver im schlimmsten Fall nicht mehr reagiert!
Gib auch die Zhlvariable aus!
Du hast das Prinzip verstanden? Sehr gut! Dann hast du in wenigen Stun-
den das geschafft, wofr der Autor dieses Buches Monate gebraucht hat!
Zum Festigen schlage ich vor: Erweitere das eben erstellte Geburtstags-
skript ein wenig. Gib zustzlich die Zhlvariable mit aus.
Wandle den Satz Happy Birthday! einfach um in Happy Birthday, 1. Jahr!
bzw. Happy Birthday, 2. Jahr! usw. usf.

Hast du die Lsung selbstttig gefunden? Es ist ganz einfach! ndere ledig-
lich die echo-Zeile innerhalb der Schleife wie folgt:
echo "Happy Birthday, $i. Jahr!<br>\n";

Du findest das Beispiel auch unter dem Namen whilecount.php im Ord-
ner kapitel07 auf der CD zum Buch.
So verstehst du noch
besser, was mit dem
Zhler geschieht.

189
Prfung zu Fu: do while

Prfung zu Fu: do while
Der Vollstndigkeit halber erwhne ich noch die do-while-Schleife. Der
Unterschied: Bei der while-Schleife wird die Bedingung im Schleifenkopf
getestet, bei der do-while-Schleife dagegen im Schleifenfu.
Die Syntax sieht folgendermaen aus:
do {
Befehlszeilen immer wieder ausfhren, solange Bedingung
wahr ist;
}
while (Bedingung);
Fortsetzung, wenn Bedingung falsch;

Im Klartext: Da die Bedingung erst im Schleifenfu getestet wird, wird die
Schleife mindestens einmal durchlaufen. Auch wenn die Bedingung von
vornherein falsch ist.
Das entsprechende Diagramm sieht folgendermaen aus:

Wenn du die vorige Datei auf do-while umbaust, kommt folgendes her-
aus, ich zeige dir zumindest den PHP-Bereich:
Die Schleife wird
mindestens einmal
ausgefhrt.
190
Schleifen: Die Gratulationsmaschine

Kapitel
7

<?php
if (!empty($_POST['anzahl'])) {
$i = 1;
do {
echo "Happy Birthday, $i. Jahr!<br>\n";
$i++;
}
while ($i <= $_POST['anzahl']);
echo "Schleife wurde verlassen.\n";
}
?>

Prfe, ob meine Aussage stimmt. Gib einmal einen negativen Wert in das
Feld ein. Die Schleife wird zumindest einmal durchlaufen! (Mit der 0 klappt
es in unserem Fall allerdings nicht. Die 0 wird schlielich schon von unserer
if-Abfrage mit empty() herausgefiltert!)
Du findest das Beispiel in der Datei dowhile.php.
Hilfe! Du hattest schon Probleme mit der while-Schleife und magst die
do-while-Konstruktion berhaupt nicht? Ich mag sie auch nicht. Und
ich habe sie in meiner ganzen Praxis wohl nur ein einziges Mal bentigt.
Bleibe bei der while-Schleife. Mache dich jedoch unbedingt mit der
nchsten Schleifengattung vertraut, lerne den Schleifentyp for.
Der Bestseller: for
Kommen wir nun zum Hhepunkt unserer Schleifendiskussion. Die belieb-
teste und wohl am hufigsten eingesetzte Schleife ist die for-Schleife.
Diese Schleife wird gemeinhin als Zhlschleife bezeichnet. Leider ist sie
nicht ganz so einfach zu verstehen. Aber wir nehmen uns Zeit!
Die Syntax von for am Beispiel erklrt
Hier zeige ich dir zuerst die Grundsyntax der for-Schleife:
for (Zhlvariable; Bedingung; Zhlmuster) {
Befehlszeilen immer wieder ausfhren, solange Bedingung
wahr ist;
}
191
Der Bestseller: for

Zhlvariable, Prfung der Bedingung und das Festlegen des Zhlmusters
erfolgen gebndelt im Schleifenkopf. Diese Elemente werden in runden
Klammern zusammengefasst und durch Semikolons voneinander abge-
grenzt. Schau dir diesen besonderen Schleifenkopf etwas genauer an. Dazu
whle ich zur Verdeutlichung eine etwas ausfhrlichere Schreibweise:
for (Zhlvariable initialisieren;
Bedingung abfragen;
Zhlmuster festlegen) {
Befehlszeilen immer wieder ausfhren, solange Bedingung wahr;
}

Soweit die Theorie. Jetzt zur Praxis. Nimm dir doch noch einmal das
while-Beispiel vom Anfang des Kapitels vor! Hier fix der Quelltext, damit
du nicht erst zurckblttern musst:
$i = 1;
while ($i <= $_POST['anzahl']) {
echo "Happy Birthday, $i. Jahr!<br>\n";
$i++;
}
echo "Schleife wurde verlassen.\n";

Dieses while-Beispiel bauen wir jetzt zu einer for-Schleife aus.
Zhlvariable initialisieren
Im while-Beispiel gibt es einen Zhler ($i), den ich mit 1 initialisiert habe.
Dort wird also die Zhlvariable initialisiert. Dafr sorgt die Zeile
$i = 1;

Diese Anweisung hatte ich oberhalb der Schleife notiert. Sie gehrt zwar
nicht direkt zum Schleifenblock dazu, ist aber wichtig.
Bedingung abfragen
Die Bedingung selber wird im Schleifenkopf geprft, sie lautet
$i <= $_POST['anzahl']

Zhlmuster festlegen
Auerdem habe ich ein Zhlmuster festgelegt. Der Zhler wurde innerhalb
der Schleife inkrementiert, also um 1 erhht. Diese Anweisung sieht so aus:
$i++;
192
Schleifen: Die Gratulationsmaschine

Kapitel
7
Soweit also das schon bekannte while-Beispiel. Alles das wird in der for-
Schleife nun im Schleifenkopf zusammengefasst, also an einer zentralen
Stelle. Daraus ergibt sich im Beispiel folgende kompakte Notation.
for ($i = 1; $i < = $_POST['anzahl']; $i++) {
echo "Happy Birthday, $i. Jahr!<br>\n";
}

Zugegeben, bei einer while-Schleife sind alle diese Elemente etwas ver-
streut, aber das Prinzip ist das gleiche.
In den meisten Fllen ist es egal, ob du while oder for verwendest. Ich
empfehle die for-Konstruktion, weil sie so schn aufgerumt ist. Es
gibt jedoch einige seltene Flle, wo du vor allem mit while glcklich
wirst. Beispiele dafr findest du im Datenbankteil, wenn MySQL-Tabellen
abgefragt werden.

Du findest das Beispiel in der Datei for.php auf der CD zum Buch.
Und die Geburtstagskerzen?
Feierst du gerne Geburtstag? Mit Party, Torte und Kerzen? Kerzen das ist
genau das Stichwort. Ich mchte in diesem Kapitel noch mehr Ge-
burtstagsstimmung verbreiten und ein paar Kerzen anznden. Und zwar
fr jedes Jahr eine. Wir stellen die Kerzen schn ordentlich nebeneinander.
Die for-Schleife ist der
komfortabelste
Schleifentyp.
193
Und die Geburtstagskerzen?

Egal, ob dich das Beispiel vom Hocker reit oder nicht. Du lernst, wie du
mit einer Schleife eine Grafik mehrfach einfgen kannst und gleichzeitig
die Zellen einer Tabelle dynamisch erzeugst.

Tabelle dynamisch erzeugen
Nimm das vorhandene for-Schleifen-Beispiel aus der Datei for.php.
Auch hier bentigen wir das Formularfeld fr die Eingabe des Alters. Ich
speichere die Datei unter einem anderen Namen, im Beispiel unter dem
Namen kerzen1.php.
Fr das Beispiel habe ich eine kleine Abbildung vorbereitet, die 12 Pixel
breit und 50 Pixel hoch ist. Sie heit candle.gif. Du findest sie auf der
CD zum Buch, und zwar im Ordner beispiele/kapitel07. Du kannst
aber auch jede andere Grafik verwenden, solange diese nicht zu breit ist
Und hier zeige ich dir nun den gesamten Teil zwischen den Tags
<body></body>:
<h2>Elektronische Geburtstagskerzen</h2>
<form action="kerzen1.php" method="post">
Wie alt bist du?
<input type="text" name="anzahl">
<input type="submit" value="Absenden">
</form>
<?php
if (!empty($_POST['anzahl'])) {
echo "<table><tr>\n";
for ($i = 1; $i <= $_POST['anzahl']; $i++) {
echo "<td><img src='candle.gif' alt='Kerze'></td>\n";
}
echo "</tr></table>\n";
}
?>
Wie alt bist da? Dank
einer Tabelle stellt das
Skript fr jedes Jahr
eine Kerze auf.
194
Schleifen: Die Gratulationsmaschine

Kapitel
7
Das Prinzip ist nicht schwer zu verstehen. Das Grundgerst der Tabelle ent-
steht erst einmal auerhalb der Schleife. Diese Zeile leitet die Tabelle ein:
echo "<table><tr>\n";

und diese Zeile schliet die Tabelle:
echo "</tr></table>\n";

Die Schleife selber macht nun nichts weiter, als die einzelnen Zellen zu
erzeugen. In Abhngigkeit vom eingegebenen Alter wird folgende Passage
mehr oder weniger oft wiederholt:
echo "<td><img src='candle.gif' alt='Kerze'></td>\n";

Fertig ist die Kerzenlinie. So einfach kannst du mit einer Schleife also
auch dynamische Inhalte erstellen!
Das Beispiel eignet sich brigens ganz fabelhaft zum Erstellen eines att-
raktiven Sulendiagramms. Du willst die Verkaufszahlen eines Produktes
darstellen, z. B. deiner selbst gekochten Kaugummis? Dann kannst du die
Sule einfach aus kleinen Abbildungen deiner Produkte zusammenset-
zen!
Hatte es einen tieferen Sinn, dass ich ausgerechnet eine Tabelle schreibe?
Htte ich das Skript nicht verkrzen und den ganzen <table>-<tr>-
<td>-Kram weglassen knnen? Na klar! Aber ich wollte auf jeden Fall ei-
nen Umbruch vermeiden. Mit anderen Worten: Ich wollte verhindern, dass
die Kerzensule auseinandergerissen wird!
Have a break: Abbruchbedingung
einfgen
Reagiere auf Fehleingaben! Gegen die Eingabe von Buchstaben oder nega-
tiven Zahlen ist das Skript von Hause aus immun. Dann wird die Schleife
schlicht und einfach nicht ausgefhrt. Auch eine 0 wird dank !empty()
schon von vornherein abgeblockt.
Doch manchmal kann man gar nicht so dumm denken, wie es kommt. Ein
Spavogel gibt eine irrwitzig hohe Zahl ein, z. B. zehntausend? Dann muss
195
Und noch eine Schleife: foreach

dein Webserver ganz schn arbeiten, um alle diese zehntausend Kerzen an
den Browser zu schicken.
Was hier spaig klingt, hat ernste Hintergrnde. Gerade solche Mglich-
keiten machen dein Skript verwundbar fr Angriffe der Skript-Kids.
Dahinter verbergen sich Amateure die es nur darauf abgesehen haben,
deine Prsenz zu stren. Und schon die wiederholte Durchfhrung sol-
cher Angriffe kann deinen Webserver lahm legen und die Site fr ande-
re nicht mehr erreichbar machen.
Welche Mglichkeit hast du in diesem Fall? Fge eine Abbruchbedingung
ein! Nutze das Schlsselwort break. Das Schlsselwort break fhrt inner-
halb einer Schleife wie do, do-while oder for zu einem Abbruch der
Schleife. Die Schleife wird sofort verlassen und die Programmausfhrung
geht unterhalb der Schleife weiter.
Definiere solch eine Abbruchbedingung! Ab der Zahl 108 soll das Skript mit
dem Erzeugen von Kerzen aufhren. Mit anderen Worten: Es sollen hchs-
tens 108 Kerzen gezeichnet werden, egal wie hoch das angebliche Alter des
Benutzers auch sein mag. Dafr arbeite ich mit einer einfachen if-
Abfrage. Diese prft, ob der Wert grer als 108 ist und setzt im Zweifels-
falle das Schlsselwort break in die Schleife ein.
Da ich im Vergleich zum vorigen Beispiel nur die Schleife verndert habe,
zeige ich dir lediglich die erweiterte Schleifenkonstruktion mit eben dieser
Abbruchbedingung. Du findest das Beispiel in der Datei kerzen2.php.
for ($i = 1; $i <= $_POST['anzahl']; $i++) {
echo "<td><img src='candle.gif' alt='Kerze'>$i</td>\n";
if ($i >= 108) {
break;
}
}

Ich habe die Variable $i (siehe Pfeil) nur deshalb mit eingefgt, damit du
die Zhlung berprfen kannst! Entferne sie einfach, wenn sie dich strt.
Und noch eine Schleife: foreach
Zum Schluss stelle ich dir noch eine wirklich tolle Schleifenkonstruktion
vor. Ich prsentiere dir hier an dieser Stelle ganz exklusiv die foreach-
Schleife!
196
Schleifen: Die Gratulationsmaschine

Kapitel
7
Schleife fr Wertelisten
Die foreach-Schleife durchluft ein Array und gibt die dort gespeicherten
Werte zurck. Auf diese Art und Weise kannst du nacheinander alle Werte
eines Arrays ermitteln.
Zur Erinnerung: Ein Array ist eine Werteliste, bei der mehrere Werte in
einer Variablen gespeichert werden. Zum Ermitteln des einzelnen Wertes
dient der jeweilige key, der Schlssel. Es gibt Arrays mit einem numeri-
schen key. Hier werden die einzelnen Werte mit 0 beginnend hochge-
zhlt. Weiterhin gibt es die assoziativen Arrays mit einer Zeichenfolge
als key. Der key trgt hier meist eine Bedeutung und ist daher im Ge-
gensatz zur Nummer meist viel interessanter.
Probiere es zuerst bei einem herkmmlichen Array, bei dem dich der nu-
merische key nicht so dringend interessiert. Wenn du auf die Ausgabe des
keys verzichtest, sieht die Syntax von foreach so aus:
foreach ($Arrayname as $value) {
echo "$value<br>\n";
}

Das Wort $Arrayname steht hierbei nur als Platzhalter fr den Namen der
Werteliste. Die echo-Zeile dient lediglich als Vorschlag. Du kannst die Aus-
gabe natrlich noch besser verpacken. Wichtig ist jedoch die Zeichenfolge
$value, welche den Wert ausgibt.
Wochentage: Nur den value ausgeben
Zu theoretisch? Ein Beispiel muss her! Erinnerst du dich noch an das Wo-
chentage-Beispiel von Kapitel 4? Mal sehen ob es dir gelingt, alle Werte
aus dem Array $tag fein suberlich auszugeben.
<h2>Wochentage ausgeben mit foreach</h2>
<p>
<?php
$tag[0] = "Sonntag";
$tag[1] = "Montag";
$tag[2] = "Dienstag";
$tag[3] = "Mittwoch";
$tag[4] = "Donnerstag";
$tag[5] = "Freitag";
$tag[6] = "Samstag";
197
Und noch eine Schleife: foreach


foreach ($tag as $value) {
echo "$value<br>\n";
}
?>
</p>

Bei dieser ersten Variante wird der Wert (value) ausgegeben, nicht der
key, der sogenannte Schlssel. Wie schon erwhnt, der key ist im ersten
Fall nicht so umwerfend wichtig, entspricht er doch der Index-Nummer.

Du findest das Beispiel unter dem Namen foreach1.php auf der CD zum
Buch.
Die Zeichenfolge foreach kann mit fr jedes bersetzt werden. Die
Schleife gilt also fr jedes Element im Array, sie liest alle Elemente aus.
Hauptstdte: key und value gemeinsam
ausgeben
Viel interessanter wird die Geschichte bei assoziativen Arrays. Also bei der
Array-Gattung, bei der auch der key eine Bedeutung trgt und nicht nur
eine langweilige Nummer ist. Dann lohnt es sich auch, den key zu ermit-
teln. Die Grundsyntax von foreach wird dafr etwas erweitert:
foreach ($Arrayname as $key => $value) {
echo "$key = $value<br>\n";
}

Auch hier dient die echo-Zeile lediglich als Ausgabe-Vorschlag.
Alle Werte aus dem
Array werden ausge-
geben!
198
Schleifen: Die Gratulationsmaschine

Kapitel
7

Bei dieser Variante wird sowohl der key als auch der value ausgegeben.
Probiere auch diese Variante am Beispiel aus.
<h2>Hauptstdte: key und value ermitteln</h2>
<p>
<?php
$hauptstadt["DE"] = "Berlin";
$hauptstadt["AT"] = "Wien";
$hauptstadt["PL"] = "Warschau";
$hauptstadt["FR"] = "Paris";
foreach ($hauptstadt as $key => $value) {
echo "$key = $value<br>\n";
}
?>
</p>

Fabelhaft! Das Array liefert dir alle Schlssel-Werte-Paare aus dem Array.
Vergleiche mit der Datei foreach2.php von der CD zum Buch.
brigens bist du nicht auf die Bezeichnungen $key und $value festgelegt
das ist nur ein Vorschlag. Du kannst auch $schluessel und $wert oder
etwas anderes einsetzen. Vergleiche mit der Datei foreach3.php, wo ich
diese individuelle Variante verwendet habe.
Natrlich kannst du die Ausgabe bei echo stets an deinen Geschmack
anpassen. Kleide die Variablen $key und $value und $schluessel und
$wert beispielsweise in Stze ein. Gib die Daten in Tabellenzellen aus
usw. usf. Besonders wichtig ist diese Technik bei der Auswertung von
Formularen, denn Formulare sind ein assoziatives Array, welches aus Att-
ribut-Werte-Paaren (key-value-Paaren) besteht. Das Array selber heit
$_POST. Der Wert (key) ist der Name des Formularfeldes. Genau dieses
Wissen brauchst du im nchsten Kapitel!
199
Schlussbemerkung

Schlussbemerkung
In diesem Kapitel hast du die Schleifen kennengelernt, die praktischen
Wiederholmodule einer Programmiersprache. Egal ob while, for oder
foreach: Vielleicht hast du ja die Erfahrung gemacht, dass Schleifen gar
nicht so kompliziert sind, wie der Autor behauptet hatte?
Wie auch immer, mit diesem Kapitel ist der Grundlagenteil des Buches ab-
geschlossen. Fortgeschrittene Programmieraufgaben sowie kleine als auch
grere Projekte warten auf dich!
Zusammenfassung
0 Du kennst das Konzept von Schleifen. Hier werden Befehlszeilen in Ab-
hngigkeit von einer oder mehreren Bedingungen wiederholt.
0 Die while-Schleife wird ausgefhrt, solange die Bedingung wahr ist.
Die Prfung findet im Schleifenkopf statt.
0 Bei der do-while-Schleife findet die Prfung erst im Schleifenfu
statt. Deshalb wird die Schleife auch dann einmal durchlaufen, wenn
die Bedingung von Anfang an falsch ist.
0 Du weit, dass du bei Schleifen immer eine Abbruchbedingung vorsehen
musst, damit es nicht zu einer Endlosschleife kommt.
0 Du kennst die for-Schleife (Zhlschleife). Hier erfolgen Initialisierung
der Zhlvariable, Test der Bedingung und Festlegen des Zhlmusters di-
rekt im Schleifenkopf.
0 Du kennst das Schlsselwort break, welches zum Abbruch einer Schlei-
fe fhrt.
0 Du kennst die foreach-Schleife, die ein Array durchluft und auf
Wunsch key und value zurckgibt.
Ein paar Fragen
1. Bei welchem Schleifentyp erfolgt der Test der Bedingung im Schleifen-
fu?
2. Mit welchem Schlsselwort erreichst du, dass eine Schleife abgebro-
chen wird?
200
Schleifen: Die Gratulationsmaschine

Kapitel
7
3. Wie heit der Schleifentyp, mit dem man ein Array durchlaufen und
key und value zurckgeben kann?
4. Was bedeutet $i++ und wie nennt man diese Operation?
und ein paar Aufgaben
1. Erstelle eine for-Schleife, die alle ungeraden Zahlen zwischen 2 und 16
nebeneinander ausgibt. Nenne die Datei ungerade1.php.

2. Versuche, das Gleiche mit einer while-Schleife zu erreichen. Nenne die
Datei ungerade2.php.
3. Erstelle ein Dokument namens anzeigen.php. Hier sollen per Formular
folgende Besucherdaten erfragt werden: Vorname, Name, Str, PLZ, Ort
und Email. Nutze diese Bezeichnungen fr die Bennennung der For-
mularfelder. Nach Klick auf ABSENDEN sollen alle Benutzerdaten auf der
gleichen Seite noch einmal eingeblendet werden. Verwende dafr eine
foreach-Schleife. Tipp: Denke daran, dass das Array eines mit
method="post" erzeugten Formulars $_POST heit!


So soll es aussehen:
Die ungeraden
Zahlen stehen
nebeneinander.
201



8
Frs Feedback: Form-
mailer selbst gestrickt
Feedback! Danach sehnen sich wohl die meisten Betreiber einer Webseite.
Du lernst in diesem Kapitel, wie du
$ die Funktion mail() zum Versenden von E-Mails einsetzt
$ der Botschaft einen Datums- und Zeitstempel aufdrckst
$ ein Feedback-Formular programmierst
$ die Daten vor dem Absenden berprfst (validierst)
$ einen Universal-Formmailer erstellst, der praktisch jedes Formular ver-
sendet
Im gesamten Kapitel mssen wir die Zeichensatzkodierung der HTML-
Datei ausnahmsweise auf ISO-8859-1 ndern! UTF-8 bereitet Probleme,
Umlaute und Sonderzeichen kommen beim Empfnger mglicherweise
verstmmelt an! Ersetze utf-8 stets durch iso-8859-1 Whle dann in
PSPad FORMAT|ANSI. Auerdem gilt: Die Skripte dieses Kapitels funktio-
nieren nur richtig, wenn du sie online testest! Zumindest der Sende-Teil
wird nur auf dem Webserver deines Dienstleisters funktionieren! Dein
lokaler Computer kann mit der Funktion mail() in der Regel nicht um-
gehen und produziert eine Fehlermeldung!
202
Frs Feedback: Formmailer selbst gestrickt

Kapitel
8 Die Funktion mail()
Sicher kennst du die klassische Feedback-Lsung den E-Mail-Link. Erstel-
le einen mailto-Verweis, auf den man klicken und dir eine Mail schreiben
kann. Die Syntax ist dir sicher vertraut:
<a href="mailto:deine@mail.de">Schreibe mir!</a>

Genauso vertraut sind dir sicher auch die groen Nachteile dieser Methode.
Damit es funktioniert, muss der Benutzer ein korrekt installiertes Mail-
programm verwenden. Das ist aber nicht immer der Fall, vor allem nicht
in Internetcafs! Ein weiterer Nachteil wiegt viel schwerer: Die interna-
tionale Spam-Mafia ergaunert solche Adressen und mllt dich in Folge
mit unsinnigen Werbemails zu. Ich rate deshalb inzwischen von der
mailto-Variante ab. (Eine E-Mail-Adresse solltest du auf deiner Websei-
te mglichst nur noch als verschlsselten Text mit Leerzeichen, fehlen-
den Zeichen bzw. Fllzeichen oder sogar als Text-Grafik ablegen!)
Lsung mit PHP
Wir lernen etwas Besseres: nutze PHP! Denn so kannst du Daten per E-Mail
verschicken, ohne dass deine E-Mail-Adresse im Klartext bermittelt wird.
Dabei wird ein Mailprogramm verwendet, welches dein Dienstleister fr
dich bereithlt.
0 Beachte allerdings, dass alle Skripte dieses Kapitels nur dann vollstndig
funktionieren, wenn du sie online testest! Zumindest der Sende-Teil
wird nur auf dem Webserver deines Dienstleisters funktionieren. Dein
lokaler Computer kann mit der Funktion mail() in der Regel nicht um-
gehen und produziert eine Fehlermeldung!
Zuerst zeige ich dir, wie simpel das Versenden einer E-Mail in PHP eigent-
lich ist. Dafr bentigst du lediglich die Funktion mail(). Diese Funktion
verschickt nomen est omen eine E-Mail an die angegebene Adresse.
Diese Funktion besitzt folgende Grundsyntax:
mail("Empfngeradresse", "Betrefftext", "Botschaft",
"From: Absenderadresse")

Du kannst alle Argumente direkt in die Funktion eintragen oder aber durch
Variablen darstellen. Wichtig: Diese Werte mssen dem Datentyp String
203
Die Funktion mail()

entsprechen. Setze sie also im Zweifelsfalle in Gnsefchen! Oder achte
darauf, dass die entsprechende Variable fr das jeweilige Argument dem
Datentyp String entspricht.
Bei Aufruf der Seite: E-Mail!
Wie wre es mit dem ersten Beispiel? Das nun folgende PHP-Dokument
verschickt immer dann eine E-Mail, wenn der Surfer die entsprechende
Seite aufruft. Weil es so simpel ist, zeige ich dir den gesamten Quelltext.
Du findest das Dokument unter dem Namen infomail.php auf der CD
zum Buch.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN">
<html lang="de">
<head>
<title>Info-Mail verschicken</title>
<meta http-equiv="content-type" content="text/html;
charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="phpkid.css">
</head>
<body>
<h2>Diese Seite verschickt eine Info-Mail</h2>
<?php
$Email = "absender@mail.de";
$mailbody = "Soeben hat jemand deine Seite angeklickt!";
mail("test@lexi.de", "Ein Besucher", $mailbody,
"From: $Email");
?>
</body>
</html>

Schaue dir die Funktion mail() etwas genauer an. Als erstes Argument
gibst du natrlich statt test@lexi.de deine eigene E-Mail-Adresse an.
Der Wert der Variablen $Email wiederum ist nur ein Platzhalter. Schlie-
lich kannst du bei diesem Skript die E-Mail-Adresse des Surfers nicht er-
mitteln. Trotzdem verlangt die Funktion irgendeine Absenderadresse.
In der Variablen $mailbody speicherst du den Text, welchen die E-Mail an
dich schickt. Es ist der Body der E-Mail, wenn du so willst.
Lade die Seite auf den Server und probiere es aus. Bei jedem Hit bekommst
du nun eine E-Mail geschickt mit dem Text Soeben hat jemand deine Seite
angeklickt.
Achtung! Ersetze utf-8
durch iso-8859-1!
Whle in PSPad auer-
dem FORMAT|ANSI!
204
Frs Feedback: Formmailer selbst gestrickt

Kapitel
8 Hilfe, bei dir funktioniert das Skript nicht, es gibt nur Fehlermeldungen?
Bitte vergiss nicht, dass alle Beispiele dieses Kapitels nur dann funktio-
nieren, wenn du die Datei vorher auf den Server ldst. Dein Dienstleister
sollte auerdem das serverseitige Mailen untersttzen. Auf deinem loka-
len System funktioniert mail() in aller Regel nicht und gibt daher einen
Fehler zurck!

E-Mail mit Datums- und
Zeitstempel
Eine simple E-Mail pro Besuch reicht dir nicht? Du wnschst mehr Infor-
mationen? Kein Problem! Ermittle zum Beispiel Datum und Uhrzeit des
Besuches. Dazu erzeugst du zustzlich einen Datums- und Zeitstempel. So
weit du auch ganz exakt, wann der Besucher bei dir vorbeigeschaut hat.
Erinnerst du dich? Zum Ausgeben von Datum und Uhrzeit verwendest du
die Funktion date() mit den entsprechenden Argumenten. Du mchtest
das Datum nach dem Motto ausgeben Tag (1-31), Monat (1-12) und
Jahreszahl (vierstellig)? Dann verwendest du die folgende Syntax: echo
date("j.n.Y"). Einen Zeitstempel mit Stunden (24 h-Format), Minu-
ten und Sekunden erzeugst du dagegen mit echo date("H:i:s").
Der Quelltext im berblick
Das nun folgende Beispiel verschickt die E-Mail mit Datums- und Zeit-
stempel. Ich zeige dir den PHP-Teil der Datei mailstempel.php:
<?php
$datum = date("j.n.y");
$zeit = date("H:i:s");
$Email = "absender@mail.de";
mail() luft nicht auf
dem lokalen System, es
gibt eine Fehlermel-
dung!
205
Das Feedback-Formular


$mailbody = "Am $datum um $zeit Uhr hat jemand deine
Seite angeklickt!";
mail("test@lexi.de", "Ein Besucher", $mailbody,
"From: $Email");
?>

Probiere es aus: Lade das Dokument auf den Server und rufe es auf. Schaue
dann in deinen Posteingang.

Hat es funktioniert? Wunderbar. Das war nur eine bung. Zeit fr ein etwas
fortgeschritteneres Beispiel!
Das Feedback-Formular
Jetzt kommt der erste Hhepunkt dieses Kapitels. Du erstellst ein Feed-
back-Formular. Der Besucher kann seine E-Mail-Adresse und einen Kom-
mentartext eingeben. Auf Knopfdruck wird der Inhalt an dich abgeschickt.

TEXTAREA: Ideal fr Kommentare
Ich zeige dir zuerst den kompletten HTML-Quelltext des PHP-Dokuments
mitsamt Formular. Den PHP-Teil fgen wir hinterher gemeinsam ein. Nenne
das Dokument feedback.php und ergnze es Schritt fr Schritt. So erzeu-
gen wir ein sicheres Formular, das auch fr das Web geeignet ist!
Warum nicht: E-Mail
mit Datums- und
Zeitstempel.
Erzeuge ein Formular
zur Entgegennahme
von Feedback.
206
Frs Feedback: Formmailer selbst gestrickt

Kapitel
8

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="de">
<head>
<title>Feedback-Formular</title>
<meta http-equiv="content-type" content="text/html;
charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="phpkid.css">
</head>
<body>
<h3>Feedbackformular</h3>
<form action="feedback.php" method="post">
E-Mail-Adresse: <input type="text" name="Email"><br>
Kommentar: <br>
<textarea name="botschaft" cols="50" rows="5">
</textarea><br>
<input type="submit" value="Absenden">
</form>

</body>
</html>

Dieses Dokument enthlt neben zwei INPUT-Feldern eine Besonderheit.
Beachte das groe Kommentarfeld. Dieses Feld wird vom Tag-Paar
<textarea></textarea> umschlossen. Es ist wie geschaffen fr groe
Texteingabebereiche. Apropos Gre: Mit dem Attribut cols (Spalten) legst
du die Breite des Feldes in Zeichen fest. Ich habe mich fr 50 Zeichen ent-
schieden. rows (Zeilen) steuert dagegen die Zeilenzahl, im Beispiel 5.
Denkst du an iso-8859-1 statt utf-8? Hast du die Kodierung der Datei
auch von UTF-8 auf ANSI gendert (PSPad: FORMAT|ANSI)?
Der PHP-Teil
Nun baust du den Formmailer zusammen. Schlielich fehlt der PHP-Teil
zum Versenden! Fge folgende Zeilen ein, und zwar zwischen dem abschal-
tenden </form>-Tag und dem Tag </body>:
<?php
if (!empty($_POST['Email'])) {
mail("test@lexi.de", "Feedback", $_POST['botschaft'],
"From: $_POST[Email]");
}
?>

Hier kommt der PHP-Teil hin
iso-8859-1 statt utf-8
207
Professionell mailen: Fehler unterdrcken

Das gengt. Zuerst prfst du mit if, ob das Feld Email zurckgeschickt
wurde und nicht leer geblieben ist. Dann schickst du den Formularinhalt
mit mail() auf die Reise.
Da die einzelnen Argumente von mail() Strings sein mssen, wird z. B.
die Zeichenfolge From: $_POST[Email] in Gnsefchen eingekleidet.
Deshalb darfst du den key des Array-Eintrags aus $_POST ausnahms-
weise nicht in Gnsefchen schreiben! Schreibe also $_POST[Email]
statt $_POST['Email']. Diese gnsefchenfreie Schreibweise ist im-
mer dann notwendig (und zulssig), wenn die Array-Variable selber in-
nerhalb eines Gnsefchen-Paars steht. Ansonsten solltest du den key
je nach Geschmack stets mit einfachen bzw. doppelten Gnsefchen
umkleiden, wie ich es z. B. bei $_POST['botschaft'] getan habe.
Meine Version findest du unter dem Namen feedback1.php auf der CD
zum Buch es ist der erste Stand. Lade das Skript doch einmal auf den
Server und probiere es aus. Klappt die Formularauswertung?
Professionell mailen: Fehler
unterdrcken
Das Skript besitzt bisher etliche Schnheitsfehler! Den ersten Schnheits-
fehler merkst du, wenn du das Beispiel offline ausprobierst, also auf dei-
nem heimischen Rechner. Da das Mailen hier nicht funktioniert, hagelt es
eine kryptische Fehlermeldung. Solch eine Fehlermeldung kann aber auch
auftreten, wenn der Mailer deines Dienstleisters gerade berlastet ist.
Zeichen @ zur Fehlerunterdrckung
Vielen Funktionen kannst du das Zeichen @ voranstellen. Dadurch werden
Fehler unterdrckt. Notiere statt mail() einfach @mail().
Stelle der mail()-Funktion im Beispiel nun das @-Zeichen voran. Probiere
das Skript offline aus.
Wunderbar, die Fehlermeldung ist weg. Aber der Nutzer wiegt sich in dem
Glauben, sein Kommentar wre abgeschickt worden. Offenbar war diese
eine Manahme doch noch nicht der Weisheit letzter Schluss. Und tatsch-
lich gibt es einen weiteren Trick.
208
Frs Feedback: Formmailer selbst gestrickt

Kapitel
8
Rckgabewert der Funktion mail() testen
Viele Funktionen geben einen Wahrheitswert zurck. Bei Erfolg ist es der
Wert true, bei Misserfolg der Wert false. So auch bei unserem Star des
Kapitels, der Funktion mail().
Die Funktion mail() gibt bei erfolgreichem Versand den Wert true zu-
rck. Wenn der Versand fehlschlgt, wird der Wahrheitswert false zu-
rckgegeben. Diese Eigenschaft solltest du nutzen, um Fehler abzufan-
gen! Zeige dem Besucher eine Besttigung an, wenn der Versand ge-
glckt ist. Informiere im Gegenzug auch ber einen Misserfolg!
Der derart erweiterte PHP-Teil sieht so aus:
<?php
if (!empty($_POST['Email'])) {
if (@mail("test@lexi.de", "Feedback",
$_POST['botschaft'], "From: $_POST[Email]")) {
echo "<p>Danke! Die Botschaft wurde
weitergeleitet!</p>\n";
}
else {
echo "<p>Leider gab es einen Sendefehler!</p>\n";
}
}
?>



Wie du siehst, werden hier zwei if-Abfragen ineinander geschachtelt. Die
innere if-Abfrage testet, ob mail() erfolgreich war. Wenn ja, sieht der
Nutzer die Meldung Danke! Die Botschaft wurde weitergeleitet. Bei Misser-
folg greift der else-Zweig und informiert ber den Sendefehler. Diese Ver-
sion des Feedback-Formulars findest du in der Datei feedback2.php.
Die kryptische Fehler-
meldung wird unter-
drckt und durch eine
sinnvolle ersetzt.
209
Professionell mailen: Fehler unterdrcken

Mehr Variablen fr eine klarere Struktur!
Ich frchte, dass uns an dieser Stelle der Hund Buffi noch etwas zu sagen
hat. Er scheint mit der bisherigen Fassung des Skripts noch nicht zufrieden
zu sein.
Der Autor versucht, das Skript kurz zu fassen. Das scheint das Problem
vieler sogenannter genialer Programmierer zu sein: Sie krzen wo es
geht, und zwar auf Kosten der Klarheit. Ich schlage dir vor, das Skript auf
mehr Zeilen aufzuteilen. Fge fr E-Mail-Adresse und den Kommentar
zustzliche Variablen ein. Das erzeugt zwar etwas lngeren Code, schafft
aber eine klarere Struktur! Ich zeige dir meine Version des PHP-Teils, da-
mit du siehst, was ich meine.
<?php
if (!empty($_POST['Email'])) {
$mailbody = $_POST['botschaft'];
$Email = $_POST['Email'];
if (@mail("test@lexi.de", "Feedback", $mailbody,
"From: $Email")) {
echo "<p>Danke! Die Botschaft wurde
weitergeleitet!</p>\n";
}
else {
echo "<p>Leider gab es einen Sendefehler!</p>\n";
}
}
?>

Hinzugekommen sind die Variablen $mailbody und $Email. In diesen
speichere ich zuerst den Inhalt aus den zwei Formularfeldern ab. Dann
brauche ich innerhalb der Funktion mail() nicht mehr mit den Mons-
tern $_POST['Email'] und $_POST['botschaft'] zu arbeiten. Au-
erdem kannst du den Inhalt der Formularfelder einfacher bearbeiten
und ergnzen. Beispielsweise, wenn du weitere Daten in der Variable
$mailbody sichern mchtest, und nicht nur den Inhalt des Kommentar-
feldes namens botschaft.
Diese Version findest du in der Datei feedback3.php.
210
Frs Feedback: Formmailer selbst gestrickt

Kapitel
8 Formular um ein Name-Feld
erweitern
Einverstanden, der Hund hat Recht. Mehr Klarheit kann nicht schaden. Ich
habe seinen Tipp beherzigt und mein Skript um die beiden Variablen erwei-
tert. Damit bin ich tatschlich viel flexibler. So kann ich nun das Formular
problemlos z. B. um ein Name-Feld erweitern!

Das ist ganz einfach. Mach mit! Ergnze im Formularbereich folgende Zeile:
Name: <input type="text" name="Name"><br>

Gehe nun in den PHP-Bereich. Ersetze diese eine Zeile:
$mailbody = $_POST['botschaft'];

durch folgende zwei Zeilen:
$mailbody = $_POST['Name'] . " schrieb\n\n";
$mailbody .= $_POST['botschaft'];

Die Zeichen \n\n sind sicher klar. Sie sorgen fr zwei zustzliche Zeilen-
umbrche im Text der E-Mail. So bleibt in der Mail zwischen Name und
dem Kommentartext eine Leerzeile. Doch was bedeutet das Zeichen .=?
Kurzform fr das Verketten
Es handelt sich um eine Kurzform fr das Verketten. Diese Zeile entspricht
eigentlich folgender Zeile
$mailbody = $mailbody . $_POST['botschaft'];

Fge ein Feld fr den
Namen ein!
211
Backslashes entfernen mit stripslashes()

Mit diesem raffinierten Verkrzungsoperator ersparen sich die schreib-
faulen Programmierer das doppelte Schreiben einer Variablen:
$mailbody .= $_POST['botschaft'];

Wenn man sich an diesen praktischen Operator einmal gewhnt hat,
mchte man ihn bald nicht mehr missen! (Allerdings dauert es eine Weile,
ehe man sich daran gewhnt hat.) Die bisherige Fassung findest du in der
Datei feedback4.php.
Backslashes entfernen mit
stripslashes()
Das Skript besitzt trotzdem noch einen Schnheitsfehler. Dieser ist jedoch
nicht gleich offensichtlich: Gib zur Probe einmal einen Kommentartext ein,
der einfache oder doppelte Gnsefchen enthlt. Schlielich soll es vor-
kommen, dass der Besucher derartige Zeichen einsetzt. Auch bei einem
Namen kann z. B. das einfache Gnsefchen vorkommen. Denke an den
schnen irischen Namen OHara.

Wie du der abgebildeten Mail entnehmen kannst, werden diese Zeichen
automatisch maskiert zumindest bei einigen Webhostern. Sie werden
escaped, es wird ein Backslash vorangestellt. Aus dem Eingabetext
Ich wnsche dir "viel Glck"!

wird in der E-Mail z. B.:
Ich wnsche dir \"viel Glck\"!

Ist das bei dir auch der Fall? Wenn nicht, hast du Glck mit deinem Hoster!
Falls doch kein Problem dank der Funktion stripslashes().
Gnsefchen werden
manchmal automa-
tisch durch einen
Backslash maskiert.
212
Frs Feedback: Formmailer selbst gestrickt

Kapitel
8 Die Funktion stripslashes(($Variable) entfernt alle Backslashs
aus einem String und gibt den bereinigten String zurck.
Ich ergnze unterhalb dieser Zeilen:
$mailbody = $_POST['Name'] . "schrieb\n\n";
$mailbody .= $_POST['botschaft'];

einfach folgende Zeile:
$mailbody = stripslashes($mailbody);

Und schon wird in $mailbody der bereinigte String gespeichert und
kann an die mail()-Funktion bergeben werden. Probiere es aus! Die
Backslash-Zeichen sind weg! Ich zeige es dir in der Datei feedback5.php.
Das eben gezeigte Problem hat etwas mit einer PHP-Einstellung namens
magic_quotes_gpc zu tun. Frher stand dieser magische Schalter bei
den meisten Dienstleistern auf On, die Backslashes wurden also stets
automatisch hinzugefgt. Inzwischen wird dieser Schalter meist auf
Off geschaltet, auch XAMPP macht das so. Nicht ohne Grund, denn die
magic quotes sind ein Auslaufmodell! Zum Glck! Mehr zu den Vor-
und Nachteilen der magic quotes verrate ich dir auf Seite 351.
Prfen! Sind alle Felder ausgefllt?
Wnschst du dir ein Feedback-Formular mit allen Schikanen? Prfe, ob alle
Felder ausgefllt sind. Gib bei jedem einzelnen Feld eine gezielte Fehler-
meldung aus nach dem Motto Die E-Mail-Adresse fehlt.
Ich zeige es dir wieder Schritt fr Schritt:
>
Ergnze den SUBMIT-Button im Formularfeld. Notiere im Tag zustz-
lich das Attribut-Werte-Paar name="submit". Damit verpasst du
auch diesem Knopf einen Namen, den du im PHP-Teil auswerten
kannst. Ich habe die Ergnzung fett hervorgehoben
<input type="submit" value="Absenden" name="submit">

>
Schaue nun in den PHP-Teil. Bisher findest du dort innerhalb von
<?php ... ?> folgende Codezeilen:
213
Prfen! Sind alle Felder ausgefllt?

if (!empty($_POST['Email'])) {
$mailbody = $_POST['Name'] . "schrieb\n\n";
... usw. ...;
echo "<p>Leider gab es einen Sendefehler!</p>\n";
}
}

>
Entferne die erste und die letzte Zeile (siehe Pfeil). Diese auf das
E-Mail-Feld bezogene if-Abfrage brauchst du fr die nchste Version
nicht mehr. Sie wird ersetzt durch eine if-Abfrage, die sich auf den
SUBMIT-Button bezieht. Schlielich soll die Namensgebung
name="submit" nicht umsonst gewesen sein.
>
Erweitere nun den Bereich innerhalb von <?php ... ?> wie folgt.
Fr die eben um zwei Zeilen gestutzten Mailer-Zeilen habe ich Aus-
lassungszeichen ... notiert:
if (isset($_POST['submit'])) {

$fehler = false;
$fehlertext = "";

if (empty($_POST['Name'])) {
$fehler = true;
$fehlertext .= "Der Name fehlt!<br>\n";
}
if (empty($_POST['Email'])) {
$fehler = true;
$fehlertext .= "Die E-Mail-Adresse fehlt!<br>\n";
}
if (empty($_POST['botschaft'])) {
$fehler = true;
$fehlertext .= "Das Kommentar-Feld muss
ausgefllt werden!<br>\n";
}

if ($fehler) {
echo "<p>$fehlertext</p>";
} else {
... hier steht der Mailbereich ...
}
}

214
Frs Feedback: Formmailer selbst gestrickt

Kapitel
8
Probiere das Skript aus, indem du mal das eine, mal das andere Feld frei
lsst.

Der Nutzer wird gezielt auf fehlende Felder hingewiesen!
Der Quelltext im berblick
Ich frchte, dass hier einiger Erklrungsbedarf besteht. Gut, fangen wir
auen an. Der gesamte PHP-Teil wird nun von folgender if-Abfrage um-
spannt:
if (isset($_POST['submit'])) {
...
}

Hier prft das Skript, ob das Formular berhaupt abgeschickt wurde. Nur
dann ist die Variable $_POST['submit'] gesetzt. Zur Erinnerung: Diese
Variable entsteht, da der SUBMIT-Button einen Namen bekommen hat.
Doch was passiert in diesen zwei Zeilen?
$fehler = false;
$fehlertext = "";

Hier werden zwei Variablen deklariert und gleich initialisiert, also mit Wer-
ten gefttert. Die erste Variable namens $fehler ist eine sogenannte
Flag-Variable. Es ist tatschlich ein kleines Fhnchen (Flag wie Flagge),
welches im Erfolgsfalle also wenn ein Fehler auftaucht gehisst wird.
Doch zuerst hisse ich noch gar nichts. Ich gehe davon aus, dass dem Benut-
zer kein Ausfll-Fehler unterlaufen ist und initialisiere die Variable deshalb
mit dem Wahrheitswert false.
215
Prfen! Sind alle Felder ausgefllt?

Die zweite Variable $fehlertext wird einfach mit einem Leerstring ge-
fttert. Spter soll in dieser Variablen der Fehlertext gespeichert werden.
Dieser wird je nach Anzahl der falsch oder gar nicht ausgefllten Felder
krzer oder lnger.
Nun erfolgt der erste Test:
if (empty($_POST['Name'])) {
$fehler = true;
$fehlertext .= "Der Name fehlt!<br>\n";
}

Hier prft das Skript, ob das Feld Name leer gelassen wurde. Wenn ja, ist
das ein Fehler. Die Flag-Variable $fehler wird deshalb auf true geschal-
tet. Es ist wahr, dass ein Fehler vorgekommen ist, unser Fhnlein flattert
im Wind. Auerdem wird die Variable $fehlertext mit einem Fehlertext
nebst Zeilenumbruch gespeist.
Wie du siehst, verwende ich hier wieder die Kurzform fr das Verketten.
Diese Zeile entspricht eigentlich folgender Zeile:
$fehlertext = $fehlertext . "Der Name fehlt!<br>\n";

Jetzt wird auch klar, warum ich die Variable $fehlertext am Anfang
schon mit einem Leerstring initialisiert hatte. Es muss schon etwas da sein,
wenn ich eine Variable mit sich selbst verketten mchte. Die nchsten bei-
den if-Blcke prfen nun, ob das E-Mail-Feld oder das Feld fr den Kom-
mentar nicht etwa leer geblieben sind. Falls das so ist, wird auch hier wie-
der die Fehlerflagge gehisst und ein Fehlertext notiert.
if (empty($_POST['Email'])) {
$fehler = true;
$fehlertext .= "Die E-Mail-Adresse fehlt!<br>\n";
}
if (empty($_POST['botschaft'])) {
$fehler = true;
$fehlertext .= "Das Kommentar-Feld muss ausgefllt
werden!<br>\n";
}

Und sptestens an dieser Stelle macht die Verkettung Sinn. Bei mehreren
fehlenden Feldern werden alle Fehlermeldungen in dieser einen Variable
gespeichert. Das ist gerade bei mehreren Feldern wirklich sehr praktisch!
216
Frs Feedback: Formmailer selbst gestrickt

Kapitel
8
(Ich habe absichtlich nur drei Felder verwendet, um das Skript nicht zu sehr
zu verkomplizieren. In der Praxis knnen noch viel mehr Felder vorkommen,
die der Nutzer ausfllen muss!)
Fehlertext ausgeben
Nun folgt eine weitere if-Abfrage. Hier wird der Status unserer Flag-
Variablen getestet. Wurde die Flagge gehisst? Gab es einen Fehler? Dann ist
der Wert von $fehler true. Dann wird die Variable $fehlertext ausge-
geben und der Nutzer sieht, welche Felder sie oder er vergessen hatte:
if ($fehler) {
echo "<p>$fehlertext</p>";
}

Sollte alles okay gewesen sein, kann die Mail dagegen endlich auf die Reise
gehen:
else {
... hier steht der Mailbereich ...
}

Ich hoffe, dass du durch diesen Wust von verschachtelten if-Abfragen
durchgestiegen bist. Immerhin hast du damit ein gutes Stck Praxis-
Know-how mitbekommen.
Vergleiche mit der Datei feedback6.php von der CD zum Buch.
Inhalt in die Formularfelder
schreiben
Die Sache mit den fehlenden Feldern ist ja ganz gut und schn. Und trotz-
dem ist das Skript bisher doch die reinste Veralberung! Dein Besucher hat
mhsam seinen Namen notiert und einen meterlangen Kommentar einge-
tragen, vor lauter Aufregung jedoch die E-Mail-Adresse vergessen? Das
kommt vor! Dann wird sie oder er darauf hingewiesen, dass die E-Mail-
Adresse fehlt. Wie zum Hohn werden beim nchsten Aufruf der Seite Name
und Kommentarfeld gelscht. Das prickelt!
Warum speicherst du die Daten nicht in den Feldern, wie schon zwei Kapi-
tel zuvor gezeigt?
217
Inhalt in die Formularfelder schreiben

Das Feld Name sichern
Du willst die Eingabe aus dem Feld Name sichern? Dann musst du lediglich
den value dynamisch in das Feld schreiben. Ergnze also das Feld:
<input type="text" name="Name">

um das Attribut value und zwar vor der schlieenden spitzen Klammer.
Schreibe dort, nach einem Leerzeichen, Folgendes:
value="<?php
if (isset($_POST['Name'])) {
echo stripslashes($_POST['Name']);
}
?>"

Bevor du den Inhalt der Variablen mit echo ausgibst, solltest du stets
mit isset($_POST['...']) testen, ob das Formular abgesendet wur-
de! Nur wenn das jeweilige Formularfeld existiert, kannst du den Wert
dieser Variablen auch in das Formularfeld schreiben. Sonst erzeugt PHP
den schon erwhnten (normalerweise unsichtbaren) Fehlerhinweis.
Die Funktion stripslashes() bentigst du, damit Gnsefchen demas-
kiert werden. Doch das gengt noch nicht! Wie meistens gibt es auch
diesmal noch einen Haken an der Sache. Probiere es aus und gib einen
Namen mit doppeltem Gnsefchen ein. Schreibe zum Beispiel: Hans "Ot-
tokar" Meier. Was stellst du fest? Der Name wird bis zum Gnsefchen
ausgelesen, dann ist Feierabend.

Der Blick in den Quelltext zeigt das Problem.
218
Frs Feedback: Formmailer selbst gestrickt

Kapitel
8
Das Problem: Hier wurden gleichrangige Gnsefchen ineinander ver-
schachtelt, und das geht nicht. Denn das nchste Gnsefchen ist fr
HTML das Zeichen, mit dem Auslesen des values wieder aufzuhren.
Doch du kannst dem Nutzer schlielich nicht verbieten, doppelte Gnse-
fchen zu schreiben. Ich habe zwei Anstze fr dieses Problem.
Funktion strtr()
Zum einen kannst du die Funktion strtr() verwenden. Die Funktion
strtr() tauscht bestimmte Zeichen aus. Die Syntax lautet
strtr(String, "Zeichen", "Ersatzzeichen");

Der String ist das Element, das durchsucht werden soll. Das kann auch
der Rckgabewert einer Funktion sein, wie im Beispiel gleich zu sehen sein
wird. Bei Zeichen gibst du das auszutauschende Zeichen an. Bei
Ersatzzeichen notierst du dagegen das Austauschzeichen. Im Beispiel
wrdest du statt
stripslashes($_POST['Name']);

einfach schreiben:
strtr(stripslashes($_POST['Name']), "\"", "'");

Dabei wickle ich einfach zwei Funktionen umeinander. Ersetzt wird das
Zeichen " durch das '. Beachte, dass du dem Zeichen " einen Maskier-
Backslash voranstellen musst. Denn auch hier gilt: Gleichrangige Gnse-
fchen drfen nicht ineinander verschachtelt werden.

Die Wirkungsweise dieses Funktionsdoppels ist klar? Zuerst wird der String
von seinen Backslashes befreit. Vom derart befreiten String werden nun
alle doppelten in einfache Gnsefchen umgewandelt.
Trotzdem ist strtr() in diesem Fall nicht meine Wahl. Ich entscheide
mich lieber fr die nchste Funktion!
Die Funktion strtr()
ersetzt ein Zeichen
durch ein anderes.
219
Inhalt in die Formularfelder schreiben

Funktion htmlspecialchars()
Besprechen wir nun eine im Zusammenhang mit Formulardesign ungeheuer
wichtige Funktion, die Funktion htmlspecialchars(). Sie ist wirklich
sehr special, denn sie dient zum Entschrfen aller in HTML mit beson-
derer Bedeutung ausgestatteten Zeichen! Auch das doppelte und einfache
Gnsefchen werden dabei bercksichtigt. Die Syntax lautet:
htmlspecialchars($variable)

Was macht htmlspecialchars() nun? Diese Funktion wandelt die vier
hier aufgezhlten Zeichen in ihre HTML-Entitten um:
Zeichen wird zu (steht fr)
< &lt; lower than
> &gt; greater than
& &amp; Ampersand
" &quot; quotation mark

Hier wird das doppelte Gnsefchen also nicht durch ein anderes Zeichen
ersetzt, sondern in sein HTML-Pendant &quot; umgewandelt. Dadurch
bleibt es auch optisch erhalten. Das Name-Feld wird also folgendermaen
erweitert:
value="<?php
if (isset($_POST['Name'])) {
echo htmlspecialchars(stripslashes($_POST['Name']));
}
?>"


Die gleiche Behandlung solltest du auch dem E-Mail-Feld gnnen:
value="<?php
if (isset($_POST['Email'])) {
echo htmlspecialchars(stripslashes($_POST['Email']));
}
?>"
Die Funktion
htmlspecialchars()
wandelt das Gnsef-
chen in &quot; um.
220
Frs Feedback: Formmailer selbst gestrickt

Kapitel
8
Der Kommentarbereich
Beim Kommentarbereich kannst du ausnahmsweise nicht mit dem Attribut
value arbeiten. Fr den Bereich <textarea></textarea> ist ein beson-
derer Trick ntig. Ergnze das Feld
<textarea name="botschaft" cols="50" rows="5">
</textarea>

wie folgt:
<textarea name="botschaft" cols="50" rows="5">
<?php
if (isset($_POST['botschaft'])) {
echo htmlspecialchars(stripslashes($_POST['botschaft']));
}
?>
</textarea>

Der Trick besteht darin, den Inhalt direkt zwischen den Tags zu notieren.
Das ist die Besonderheit bei <textarea></textarea>!
Auch hier darfst du nicht vergessen, die Backslashs mit der entsprechenden
Funktion zu entfernen. Das Maskieren der Sonderzeichen ist zwar nicht
unbedingt erforderlich, da es zumindest hier keine Gnsefchenkonflikte
geben wird. Ich habe es aus Sicherheitsgrnden jedoch trotzdem gemacht!
Merke dir die wichtige Funktion htmlspecialchars() unbedingt
schon einmal vor! Du wirst sie fr das eigene Gstebuch aus Kapitel 12
noch bentigen! Hier ist es besonders wichtig, alle Zeichen zu maskieren,
mit denen man HTML-Tags zusammensetzen kann. Die Skript-Kids
schummeln dir sonst eigene HTML- oder JavaScript-Bereiche in dein Ta-
gebuch und verndern damit das Aussehen deiner Seite!
Vergiss jedoch nicht, auch hier vorher mit einer if-Abfrage zu prfen, ob
die Variable $_POST['botschaft'] existiert. Denn wenn das Formular
noch gar nicht abgesendet wurde, muss auch kein Inhalt in das Formular-
feld eingetragen werden. Ohne if-Abfrage wrde das Skript zwar auch
funktionieren, wrde jedoch sofort alle Fehlermeldungen wie Der Name
fehlt, Die E-Mail-Adresse fehlt usw. anzeigen. Doch das wre Unsinn! Feh-
lermeldungen drfen erst nach Absenden des Formularinhalts erscheinen.
Den bisherigen Sachstand findest du in der Datei feedback7.php.
221
Erweiterter Fehlertest: Mindestlnge und E-Mail-Check

Erweiterter Fehlertest:
Mindestlnge und E-Mail-Check
Damit ist das Skript aber noch keinesfalls perfekt. Bisher prfen wir, ob die
Felder nicht leer gelassen wurden. Doch wenn der Benutzer nur ein Platz-
halter-Zeichen eingegeben hat? Einen Buchstaben oder eine Zahl? Spa-
Ausfller sind gar nicht so selten! Vor allem das Feld mit der Absender-
Mailadresse ist gefhrdet. Ohne grndliche Prfung der Eingabe knnten
Hacker dein Formular zum Versenden von Spammails missbrauchen!
In diesem Kapitel zeige ich dir deshalb weitere wichtige Fehlerbehand-
lungs-Techniken. Schreibe eine bestimmte Mindestlnge vor. Prfe vor al-
lem, ob die E-Mail-Adresse den gltigen Regeln entspricht!
Mindestlnge erzwingen mit strlen()
Zuerst unternimmst du etwas gegen zu kurze Namen. Mit weniger als drei
Zeichen solltest du dich keinesfalls zufrieden geben!
Nutze die talentierte Funktion strlen() fr diesen Zweck. Die Funktion
gibt die Lnge eines Strings zurck. (Dahinter verbirgt sich die Abkrzung
fr string length.)
>
Suche den Bereich
if (empty($_POST['Name'])) {
$fehler = true;
$fehlertext .= "Der Name fehlt!<br>\n";
}

>
Notiere darunter und ber if (empty($_POST['Email'])) {
bitte Folgendes:
elseif (strlen($_POST['Name']) < 3) {
$fehler = true;
$fehlertext .= "Der Name ist zu kurz!<br>\n";
}


Durch die Angabe elseif sicherst du, dass der zweite Test erst dann aus-
gefhrt wird, wenn der erste nicht erfolgreich war. Wenn das Feld schon
von Anfang an leer ist, macht eine Prfung auf Lnge auch keinen Sinn.
222
Frs Feedback: Formmailer selbst gestrickt

Kapitel
8
Und wie wird nun auf Lnge geprft? Ganz einfach: Mit einem Vergleich
stellst du fest, ob deine Wunschlnge unterschritten wurde. Wenn ja, setzt
du die $fehler-Flagge auf true und fgst einen sinnvollen Fehlertext
hinzu.
Das gleiche kannst du fr das Kommentarfeld (botschaft) erledigen. Er-
gnze zum Beispiel folgenden elseif-Zweig:
elseif (strlen($_POST['botschaft']) < 3) {
$fehler = true;
$fehlertext .= "Der Kommentar ist zu kurz!<br>\n";
}

Welche Zahlen du fr die Lnge einsetzt, bleibt natrlich dir berlassen.
E-Mail-Check mit regulrem Ausdruck
Hast du Lust, auch den E-Mail-Check zu verbessern? Soviel schon vorweg:
Prfen, ob eine E-Mail-Adresse wirklich existiert, kannst du nicht. Du
kannst dich aber davor schtzen, dass dir der Ausfllende unsinnige Zei-
chenfolgen als E-Mail-Adresse verkauft. Schlielich folgt der Aufbau
solch einer Adresse ganz bestimmten Regeln.
Solch ein Test gelingt dir mit den sogenannten regulren Ausdrcken, kurz
RegExp. Mit diesen entsprechend vorbereiteten Suchmustern kannst du
Strings auf das Vorhandensein bestimmter Zeichenfolgen prfen.
0 Ist das Zeichen @ vorhanden?
0 Ist die sogenannte Toplevel-Domain (eine Endung wie .de, .org oder
.museum) nicht krzer als zwei und nicht lnger als sechs Zeichen?
0 Wurde ein Punkt notiert?
0 Besitzt die Adresse etwa verbotene Zeichen wie Leerzeichen, Umlaute
oder Sonderzeichen?
Betrachte diese mysterisen regulren Ausdrcke einfach als eine Art uni-
versale Musterschablone. Also eine Schablone, die du dir fr jeden Zweck
zurechtbiegen kannst. Du testest auf das Vorhandensein oder Nichtvorhan-
densein bestimmter Zeichen- und Zeichenfolgen. Unsere Musterschablo-
ne fr die E-Mail-Adresse sieht folgendermaen aus, notiere bitte eine
lange Zeile ohne Umbruch:
$muster = "/^[a-zA-Z0-9-_.]+@[a-zA-Z0-9-_.]+\.
[a-zA-Z]{2,6}$/";
223
Erweiterter Fehlertest: Mindestlnge und E-Mail-Check

In dieser Zeile wird der regulre Ausdruck definiert und in der Variablen
$muster abgelegt. Nimm einfach hin, dass dieser Ausdruck die Schablone
fr eine E-Mail-Adresse darstellt und lass dich von dieser Zeichenwste fr
den Anfang nicht allzu sehr beeindrucken.
Testen auf bereinstimmung mit
preg_match()
Und wie testest du nun auf bereinstimmung? Verwende die Funktion
preg_match()! Die Syntax sieht so aus:
preg_match(Suchmuster, Zeichenkette)

Das Suchmuster ist unser eben festgelegter regulrer Ausdruck. Also die
Musterschablone fr die E-Mail-Adresse. Die Zeichenkette ist der Prfling,
im Beispiel die zu testende E-Mail-Adresse.
Wenn es keine bereinstimmung mit dem Suchmuster gibt, wird eine 0
zurckgegeben, ansonsten liefert die Funktion mindestens 1. Das knnen
wir uns in der if-Abfrage zunutze machen.
Hier zeige ich dir die gesamte umgebaute if-elseif-Struktur fr den
Test der E-Mail-Adresse. Beachte, dass du die Variable $muster am Anfang
dieser Passage initialisieren musst, damit der if-elseif-Ablauf nicht
gestrt wird. Es ist eine lange Zeile ohne Umbruch!
Den alten Teil habe ich hervorgehoben.
$muster = "/^[a-zA-Z0-9-_.]+@[a-zA-Z0-9-_.]+\.
[a-zA-Z]{2,6}$/";
if (empty($_POST['Email'])) {
$fehler = true;
$fehlertext .= "Die E-Mail-Adresse fehlt!<br>\n";
} elseif (preg_match($muster, $_POST['Email']) == 0) {
$fehler = true;
$fehlertext .= "Die E-Mail-Adresse ist ungltig!<br>\n";
}

Probiere deinen Fehlertest bisher ruhig einmal aus. Gib absichtlich ein paar
falsche E-Mail-Adressen ein, z. B. mit Umlauten, Leerzeichen, fehlendem
Zeichen @ usw. usf.
Mit diesem regulren Ausdruck verhindern wir brigens auch den Miss-
brauch unseres Mailformulars zu Spamzwecken. Angreifer schaffen es nun
nicht mehr, die mail()-Funktion auszutricksen!
224
Frs Feedback: Formmailer selbst gestrickt

Kapitel
8

Das ist keine gltige E-Mail-Adresse. Es fehlt der Klammeraffe!
Mit diesem Test bist du professionellem Formdesign ein ganzes Stck
nher gerckt. Das Beispiel findest du in der Datei feedback8.php.
RegExp: Der Aufbau des Such-Musters
Zurck zum Such-Ausdruck aus der Variablen $muster. Interessiert dich,
was dahinter steckt? Der gesamte Ausdruck wird zuerst einmal eingehllt
von zwei gleichen frei whlbaren Zeichen, hier ein Slash: / /. Das Dach ^
signalisiert den Beginn der Zeichenfolge, ein Dollar-Zeichen $ das Ende.
Die Zeichenfolge a-zA-Z0-9-_. steht als Platzhalter fr ein beliebiges
alphanumerisches Zeichen, also fr a-z, A-Z, 0-9, auerdem fr den Binde-
strich , den Unterstrich _ und den Punkt .. Dadurch kann man Umlaute,
Leer- und andere Sonderzeichen von vornherein ausschlieen! Warum Un-
terstrich und Bindestrich? Diese Zeichen sind deshalb wichtig, da sie eben-
falls in E-Mail-Adressen vorkommen knnen. Auch der Punkt ist gelufig,
deshalb musst du dieses Zeichen ebenfalls bercksichtigen.
Das ganze fasst du in eckige Klammern ein und versiehst es mit einem
Plus-Zeichen: [a-zA-Z0-9-_.]+ Das Plus-Zeichen verdeutlicht, dass
dieses entsprechende Zeichen mindestens einmal vorkommen muss und
beliebig oft vorkommen kann. Auch eine beliebige Kombination aller dieser
Zeichen ist also erlaubt. Leerzeichen, Umlaute oder Sonderzeichen sind
jedoch ausgeschlossen.
Das Zeichen @ habe ich nicht innerhalb von Klammern notiert. Wa-
rum? Das bedeutet, dass dieses Zeichen genau einmal vorkommen muss,
und zwar an dieser Position (in der Mitte der E-Mail-Adresse)! Danach
notierst du wieder den Platzhalter fr ein beliebiges alphanumerisches
Zeichen. Der ebenfalls nicht eingeklammerte Ausdruck \. steht fr dem
Pflicht-Punkt an dieser einen Stelle.
225
Erweiterter Fehlertest: Mindestlnge und E-Mail-Check

Ganz am Schluss der E-Mail-Adresse drfen nur alphanumerische Zeichen
vorkommen. Hier geht es um die Top-Level-Domains wie .de, .info oder
.museum. Das wird durch folgende Zeichen symbolisiert:
[a-zA-Z]{2,6}

Mindestens zwei, hchstens jedoch sechs Zeichen sind erlaubt. Das symbo-
lisiert die Zeichenfolge {2,6}. Uff! Schon in diesem einen Suchmuster
steckt ziemlich viel Komplexitt.
Schon aus diesem kurzen Beispiel merkst du, wie schwierig der Umgang
mit diesen regulren Ausdrcken ist. Es gibt umfangreiche Kapitel in
Fachbchern, die sich allein diesem Thema widmen. Bei Stefan Mnz auf
http://de.selfhtml.org findest du ebenfalls eine ziemlich umfangreiche
Einfhrung in dieses Thema. Und es gibt sogar mehrere Spielarten die-
ser regulren Ausdrcke. Der Autor hat z. B. mit den modernen Perl-
kompatiblen regulren Ausdrcken gearbeitet (Perl ist eine mit PHP ver-
gleichbare Server-Programmiersprache!). Der Name der Funktion
preg_match (Perl-kompatible regulre Ausdrcke, match wie berein-
stimmung) weist darauf hin. Falls du ltere PHP-Einfhrungen liest,
stt du mglicherweise auf die veraltete Funktion ereg(). Diese Funk-
tion bietet zu wenige Mglichkeiten. Im zweiten Buch werden wir uns
noch intensiver mit diesen regulren Ausdrcken beschftigen!
Schutz gegen Flooding?
Ist das Skript damit schon perfekt? Nein! Es ist noch nicht gegen Flooding
(Fluten) geschtzt. Also dagegen, dass ein Scherzbold immer wieder und
wieder auf den ABSENDEN-Button klickt und damit das erneute Versenden
auslst. Denn alle Formulardaten bleiben in den Formularfeldern erhalten.
Man msste den Inhalt der Formularfelder irgendwie lschen, damit es
nicht zu einem erneuten Versand kommt.
Und hier greife ich eine Idee von Falk auf, die er in meinem Forum gepostet
hat. (Danke, Falk!) Mache einmal Folgendes:
>
Vertausche die Position von Formular (alles zwischen den Tags
<form></form>) und PHP-Skript. Bisher beginnt das Formular ja di-
rekt unterhalb der <h3> und endet ber dem einschaltenden PHP-Tag
<?php. Fge es zwischen dem schlieenden PHP-Tag ?> und dem
schlieenden Body-Tag </body> ein. (Ausschneiden und Einfgen
kannst du hoffentlich?)
226
Frs Feedback: Formmailer selbst gestrickt

Kapitel
8
Wenn du das Skript jetzt ausprobierst, sollte es weiterhin funktionieren.
Der einzige Unterschied: Die Statusmeldungen erscheinen jetzt ber und
nicht mehr unter dem Formular und das ist ja nicht das Schlechteste. (So
fallen sie besser ins Auge.)
>
Die ersten drei Zeilen des Skripts unterhalb von <body> sehen nun
wie folgt aus. Setze doch einmal die Zeile $fehler = false; vor die
if-Abfrage.
<h3>Feedbackformular</h3>

<?php
if (isset($_POST['submit'])) {

$fehler = false;

Dadurch wird die $fehler-Variable gleich von Anfang an mit false ini-
tialisiert. Sie ist daher gleich im gesamten Skript sichtbar.
>
Und nun ahnst du schon was? gehst du in den unteren Quellcode-
Teil, ins Formular. Und zwar zu den drei Stellen, wo der value dyna-
misch in das Feld geschrieben wird. Erweitere die jeweilige if-Abfrage
um && $fehler, ich zeige es dir am Beispiel des ersten Felds, des
Name-Felds:
Name: <input type="text" name="Name" value="<?php
if (isset($_POST['Name']) && $fehler) {
echo htmlspecialchars(stripslashes($_POST['Name']));
}
?>"><br>

Das bedeutet: Der Wert soll also nur dann in das Feld geschrieben werden,
wenn die entsprechende Variable existiert also wenn das Formular abge-
schickt wurde und wenn es einen Fehler gegeben hat. Einen Fehler, der
dafr sorgt, dass die Daten noch nicht abgeschickt werden konnten.
Wenn sie dagegen verarbeitet wurden, ist der Wert von $fehler schlicht
und ergreifend false. Die Werte werden dann nach Klick auf ABSENDEN aus
den Feldern gelscht! Die Lsung findest du in der Datei feedback9.php.
Okay, das ist schon eine gute Lsung, perfekt ist sie noch nicht. Die Gefahr
von Flooding ist damit noch nicht gebannt. Die Daten befinden sich trotz-
dem noch im sogenannten Browsercache (Zwischenspeicher). Der Scherz-
keks braucht nur auf Reload des Browsers zu drcken schon geht die
E-Mail noch einmal auf die Reise. Auch der Klick auf den ZURCK-Button
227
Krnender Abschluss: Universal-Formmailer

des Browsers ist sehr aufschlussreich. Pltzlich stehen die Daten wieder in
den Formularfeldern und lassen sich erneut versenden!
Fr einen wirksamen Flooding-Schutz haben wir an dieser Stelle aber
einfach noch nicht genug Wissen!
In Kapitel 12 erstellst du die Funktion isDouble(), um Doppeleintrge bei
Gstebchern zu verhindern. Dabei erzeugt das Formular zustzlich einen
Zeitstempel. Dieser wird in einer Textdatei gespeichert und bei erneutem
Versand verglichen. Beide Zeitstempel mssen voneinander abweichen,
sonst handelt es sich um alte Formulardaten aus dem Browsercache. Auf
diese Weise lsst sich der Doppelversand wirksam unterdrcken.
Vergleiche mit meiner Lsung unter kapitel08/feedback (und lies Kapi-
tel 12)! Diese Lsung luft jedoch an dieser Stelle auer Konkurrenz und
wird nicht mit in die Aufgaben am Ende des Kapitels einbezogen!
Krnender Abschluss: Universal-
Formmailer
Wie wre es mit einem Skript, welches alle deine Formulare verschickt?
Egal wie diese aufgebaut sind? Ideal fr Feedback, fr Bestellungen aus
einem Onlineshop, fr Umfragen usw. Dieses Skript gibt es. Nutze meinen
berhmten Universal-Formmailer, den ich extra fr dieses Buch erweitert
und nochmals entscheidend verbessert habe.
Das Skript kannst du praktisch zum Auswerten aller deiner Formulare
verwenden, ganz egal, wie viele und welche Felder in diesen auftreten.
Einzige Bedingung: Das Formular muss auf jeden Fall ein Feld besitzen,
welches Email benannt wurde! Auerdem muss jedes Formularelement
einen anderen Namen erhalten, aber das versteht sich sicher von selber!
Der Quelltext im berblick
Und hier zeige ich dir nun den kompletten Quelltext der Datei
unimailer.php. Beachte meine Kommentare, die dir die Wirkungsweise
des Skriptes erklren. Eine Einbauerklrung nebst kurzer Erluterung der
Besonderheiten bekommst du im Anschluss.
228
Frs Feedback: Formmailer selbst gestrickt

Kapitel
8

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN">
<html lang="de">
<head>
<title>Formularinhalt versenden</title>
<meta http-equiv="content-type" content="text/html;
charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="phpkid.css">
</head>
<body>
<?php
/* Unimailer Version 5, bhv-edition, (c) JCHANKE.de */
/* DIE NCHSTEN WERTE DARFST DU EDITIEREN */
$empfaenger = "deinemail@lexi.de";
$betreff = "Betrefftext der Mail hier eintragen";
$mailbody = "Folgende Daten wurden eingegeben:\n\n";
/* EDITIEREN ENDE */
/* foreach liest Attribut-Werte-Paare aus: */
foreach($_POST as $name => $value) {
/* Formular-Daten werden in $mailbody gespeichert: */
$mailbody .= "$name = $value\n"; // Kurzform Verkettung
$mailbody = stripslashes($mailbody);
}
$muster = "/^[a-zA-Z0-9-_.]+@[a-zA-Z0-9-_.]+\.[a-zA-Z]{2,6}$/";
/* Versenden! Email-Feld im Formular vorsehen! */
// Ist das Email-Feld nicht leer und gltig?
if (!empty($_POST['Email']) && preg_match($muster,
$_POST['Email']) > 0) {
/* Dann wird Versenden-Funktion mail() aktiv */
$absender = $_POST['Email'];
if (@mail($empfaenger, $betreff, $mailbody, "From:
$absender")) {
/* mail() erfolgreich? Dann sieht Nutzer Folgendes */
echo "<h3>Herzlichen Dank!</h3>\n";
echo "<p>Die Daten wurden weitergeleitet!</p>\n";
}
/* Sonst gibt es eine Fehlermeldung: */
else {
echo "<h3>Leider konnte die Botschaft nicht
verschickt werden.</h3>\n";
}
} // uere if-Funktion schlieen
229
Krnender Abschluss: Universal-Formmailer

/* else-Zweig uere if bei nicht gesetzter Email: */
else {
echo "<h3>Die E-Mail-Adresse muss angegeben werden
und gltig sein!</h3>\n";
echo "<p><a href='javascript:history.back()'>zurck
zum Formular</a></p>\n";
}

?>
</body>
</html>

Keine Lust zum Abschreiben? Du findest das Beispiel natrlich auch auf der
CD zum Buch, und zwar unter dem Namen unimailer.php.
Auer Konkurrenz biete ich dir noch eine zweite Version meines Unimailers.
Du findest sie unter kapitel08 im Ordner unimailer_deluxe. Dort habe
ich zustzlich eine Flooding-Sperre eingebaut. Da ich diese Sperre aber erst
in Kapitel 12 erlutere, gehe ich hier nicht weiter auf diesen Zusatz ein.
Du mchtest den Inhalt deiner Formulare ber diesen Unimailer versen-
den? Nichts leichter als das. Lege die unimailer.php (und die
phpkid.css) auf deinen PHP-fhigen Server. Merke dir die Adresse gut,
z. B. http://www.deinserver.de/unimailer.php. Schaue nun in die Datei mit
dem Formular, es kann eine normale HTML-Datei sein. Gehe in das ein-
leitende <form>-Tag. Achte darauf, dass hier folgendes steht:
0 action="http://www.deinserver.de/unimailer.php"
0 method="post"
Das war schon alles. Du kannst gerne alle deine Formulare ber diesen
Unimailer versenden. Dabei macht es nichts, wenn diese Dateien auf ei-
nem ganz anderen Server liegen zumindest gilt diese Aussage fr die
meisten kostenpflichtigen Dienstleister mit PHP-Untersttzung. Haupt-
sache, du vergisst nicht die eben genannten Angaben.
Besonderheiten im Skript
Damit du sofort durchblickst, habe ich das Skript ausfhrlich kommentiert.
Und wenn du das Kapitel bis hierher aufmerksam studiert hast, msstest du
eigentlich alles ohne Probleme verstehen.
230
Frs Feedback: Formmailer selbst gestrickt

Kapitel
8
Ich verwende eine foreach-Schleife. Diese gibt alle Schlssel-Werte-Paare
des Arrays $_POST und damit alle Felder und ihren Inhalt zurck:
/* foreach liest Attribut-Werte-Paare aus: */
foreach($_POST as $name => $value) {
/* Formular-Daten werden in $mailbody gespeichert: */
$mailbody .= "$name = $value\n"; // Kurzform Verkettung
$mailbody = stripslashes($mailbody);
}

Auerdem findest du im Skript auch wieder die Kurzform fr das Verketten.
So entspricht die folgende Zeile
$mailbody .= "$name = $value\n"; // Kurzform Verkettung

praktisch dieser Anweisung:
$mailbody = $mailbody . "$name = $value\n";

Der Rest ist sicher leicht verstndlich. Passe die entsprechenden Variablen
deinen Wnschen an.
Das Skript testet auch, ob die E-Mail-Adresse eingegeben wurde und gltig
ist. Dafr kommt wieder unser regulrer Ausdruck zum Einsatz. Ist irgend-
etwas faul mit der E-Mail-Adresse? Dann wird der Besucher darber aufge-
klrt:
echo "<h3>Die E-Mail-Adresse muss angegeben werden
und gltig sein!</h3>\n";

Ein JavaScript-Link fhrt mit dem Schlsselwort history.back() wieder
zurck zur vorherigen Seite:
echo "<p><a href='javascript:history.back()'>zurck
zum Formular</a></p>\n";

Bis auf diesen Test der E-Mail-Adresse findet keine Formularvalidierung
statt, also kein Test auf Gltigkeit des restlichen Formularinhalts. Das
Skript bleibt dadurch flexibel: Schlielich weit du nicht, wie viele und
welche Felder es gibt.
231
Schlussbemerkung

Arbeitsteilung JavaScript und PHP
Apropos Formvalidierung: In vielen Fllen macht es Sinn, deine Formula-
re mit JavaScript zu testen. Erst die korrekten Daten werden dann an
PHP weitergegeben. Das hat Vorteile, denn die beiden Skriptsprachen
knnen sich die Aufgaben ganz wunderbar teilen. Schlielich wurde
JavaScript extra fr die Formularvalidierung erschaffen! JavaScript wird
vom Client ausgefhrt, also von deinem Rechner. PHP luft dagegen auf
dem Server und belastet den Rechner des Anbieters! Fr dich als Formu-
laranbieter macht es deshalb Sinn, mglichst viele Programmaktionen an
den Client zu delegieren. Besonders, wenn du viele Kunden hast und
bei der Serverkapazitt sparen musst. Bei einem zu groen Besucheran-
sturm kann die Serverkapazitt sonst sehr schnell in die Knie gehen. Im
Endeffekt reagieren deine Seiten immer langsamer und langsamer und
sind im Zweifelsfalle nicht mehr erreichbar. Deinen Rechner als Kunde
belastet die eine kleine Validierung mit JavaScript jedoch kaum.
Als kleines Praxisbeispiel fr diese Aufgabenteilung hat dir der Buchau-
tor ein Skript fr einen Onlineshop mit auf die CD gepackt. Es handelt
sich um sein Programm Shopmichel Version 2.3. Es ist ein experimentel-
les Bestellsystem mit Warenkorb und Bestellbesttigung. Der Kufer be-
kommt nach Handelsabschluss eine Besttigungs-Mail geschickt.
Das Interessante dabei: Formularauswertung und Erzeugung des Waren-
korbs erfolgt ausschlielich mit HTML und JavaScript. Dein Server wird
dadurch kaum belastet, denn der wird dafr praktisch nicht bentigt.
Erst ganz am Schluss leitet das Skript die Bestellung an einen PHP-
Formmailer weiter. Schau dir ruhig den Quelltext an. Du findest auch ei-
ne ausfhrliche Erklrung mit Einbauanleitung.
Schlussbemerkung
In diesem Kapitel hast du dich ausgiebig mit Formularauswertung und
Formularversand beschftigt. Du kennst die wichtigsten Tricks und Kniffe,
um professionell aufgebaute Feedback-Formulare zu erstellen!
Auerdem hast du gelernt, dass der Zeichensatz UTF-8 auch Probleme be-
reiten kann. Wir mussten alle Skripte als ISO-8859-1 kodieren, damit es
beim Empfnger keine verstmmelten Umlaute und Sonderzeichen gibt.
(Andere Lsungen wren aber an dieser Stelle zu kompliziert gewesen!)
232
Frs Feedback: Formmailer selbst gestrickt

Kapitel
8 Zusammenfassung
0 Du kennst die Funktion mail(), mit der du ber den Webserver eine
E-Mail verschicken kannst.
0 Du weit, dass du Formmailer-Dateien als ISO-8859-1 (PSPad: ANSI)
speichern solltest, damit es keine Umlaut-Probleme gibt.
0 Du weit, dass du mit dem Zeichen @ vor mail() die Ausgabe von
Fehlermeldungen unterdrckst.
0 Du weit, dass die Funktion mail() je nach Erfolg true oder false
zurckgibt und dass du diesen Wert abfangen und zur Fehlerausgabe
nutzen kannst.
0 Du kennst die Kurzform fr das Verketten einer Variablen mit sich selbst
(.=).
0 Du kennst die Funktion stripslashes() zum Entfernen der Maskie-
rungs-Backslashes und die Funktion strtr() zum Ersetzen von Zei-
chen.
0 Du weit, dass du mit der Funktion htmlspecialchars() die fr
HTML wichtigen Zeichen in ihre Entitten (Umschreibungen) umwan-
deln und damit entschrfen kannst.
0 Du kennst die Funktion strlen() zum Ermitteln der Lnge eines
Strings und damit zum Prfen von Formulareingaben.
0 Du hast das Konzept der regulren Ausdrcke kennengelernt, der Such-
muster fr bestimmte Zeichenfolgen. Du weit, dass du mit
preg_match() und dem entsprechenden Suchmuster z. B. den korrek-
ten Aufbau der E-Mail-Adresse berprfen kannst.
Ein paar Fragen
1. Mit welchem Zeichen kannst du bei vielen Funktionen die Ausgabe von
Fehlermeldungen unterdrcken?
2. Welche Werte gibt die Funktion mail() zurck und wie kann man die-
se Tatsache ausnutzen?
3. Welche Funktion gibt die Lnge eines Strings zurck?
4. Welche im Browser lauffhige Programmiersprache wurde speziell dazu
entwickelt, Formulare zu validieren (zu berprfen)?
233
und ein paar Aufgaben

und ein paar Aufgaben
1. Fge ein weiteres Formularfeld in das Feedback-Formular (Datei
feedback.php) ein, um den Wohnort zu ermitteln. Nenne das Feld Ort.
2. berprfe, ob das Wohnort-Feld ausgefllt wurde. Gib eine Mindestln-
ge von 3 Zeichen vor.
3. Speichere den Ort dynamisch im Formularfeld und vergiss nicht, ihn
auch zum $mailbody hinzuzufgen.
4. Erweitere das Feedback-Formular, schicke dem Feedback-Schreiber au-
tomatisch eine Besttigungsmail, in der du dich fr die Angaben be-
dankst!
5. Schaue dir das Umfrage-Formular aus Kapitel 1 an. Baue es so um, das
der Formularinhalt ber den Universal-Formmailer abgeschickt werden
kann. Welches Feld musst du noch einbauen, damit der Universal-
Formmailer arbeiten kann?
6. Erstelle eine Formtester-Seite. Eine Seite, die dir alle Attribut-Werte-
Paare eines Formulars untereinander anzeigt, ohne irgendein Feld vor-
auszusetzen oder zu testen. Nenne die Seite formtester.php.
235



9
Surfer wiedererkennen
mit Cookies
Keine Angst vorm Krmelmonster! In diesem Kapitel backen wir Kekse, zu
Englisch Cookies.
Du lernst in diesem Kapitel, wie du
$ Informationen auf dem Rechner des Besuchers speicherst
$ Cookies mit PHP setzt, verwaltest und ausliest
$ Cookies mit einem Mindesthaltbarkeitsdatum versiehst
$ Cookies lschst
Dabei reden wir ganz ausfhrlich auch ber die Nachteile dieser Technolo-
gie und schauen uns an, welche Browsereinstellungen fr die Arbeit mit
Cookies wichtig sind. Denn als Surfer musst du dir nicht alle Kekse gefallen
lassen.
Doch was sind Cookies berhaupt?

236
Surfer wiedererkennen mit Cookies

Kapitel
9 Was sind Cookies?
Kennst du das auch? Du surfst zu einer Website und liest: Schn, dass Sie
uns wieder besuchen!. Und tatschlich es ist nicht dein erster Besuch.
Noch nach Wochen erinnert sich ein Onlineshop an die Produkte, die du
irgendwann mal zur Probe in den Warenkorb gelegt und nie gekauft hat-
test. Du hattest das lngst vergessen, der Shop wusste offenbar Bescheid.
Manche Websites erinnern sich sogar nach Monaten an deinen Namen. So
wirst du bei eBay (www.ebay.de) selbst dann noch mit deinem Benutzer-
namen begrt, wenn du dich als Benutzer lngst wieder ausgeloggt hast.
Was steckt dahinter? Ist das Hexerei? Fauler Web-Zauber? Ein Protokoll-
und berwachungsprogramm des Bundesnachrichtendienstes? Nein! Hier
handelt es sich aller Wahrscheinlichkeit nach um Cookies.
Cookies sind Informationskrmel, die eine Webseite auf dem Rechner des
Besuchers speichert. Eine Webseite merkt sich dadurch, dass du sie be-
sucht hast. Ein Onlineshop wei, welche Produkte noch in deinem Wa-
renkorb stecken. Denn bei einem neuerlichen Besuch liest diese Webseite
die Datei einfach wieder aus und reagiert darauf.
Cookies werden vom Browser verwaltet, der sie empfngt.
Sind Cookies ein Sicherheitsrisiko?
Eigentlich nicht. Es kommt immer darauf an, wie der Seitenersteller diese
Technologie einsetzt. (Damit bist auch du als Seitenersteller gemeint!)
Doch zuerst die harten Fakten:
0 Cookies sind kleine Textdateien, die eine Webseite auf der Festplatte
des Surfers ablegt. Programme oder Viren lassen sich so nicht sichern.
0 Cookies werden in Abhngigkeit vom Browser stets an einer bestimm-
ten Stelle abgelegt. (Wo, klren wir gleich!)
0 Du kannst Cookies einsehen und bedenkenlos wieder lschen. Wie das
geht, hngt vom Browser ab.
0 Du kannst deinen Browser so konfigurieren, dass er Cookies gar nicht
erst annimmt.
0 Ein Cookie ist in aller Regel nicht grer als 4 KB. (Schon das sorgt da-
fr, dass Programme und Viren keine Chance haben!)
237
Was sind Cookies?

0 Cookies sind normalerweise eine Privatsache zwischen der Webseite des
Cookie-Produzenten, deinem Browser und dir als Surfer. In der Regel
bekommt der Seitenbetreiber nicht einmal mit, dass eine Seite ein
Cookie bei dir gesetzt hat. (Cookies knnen unter bestimmten Voraus-
setzungen allerdings doch zum Ausspionieren verwendet werden, dazu
gleich mehr!)
0 Cookies knnen normalerweise nur von der Seite wieder ausgelesen
werden, die sie gesetzt hat. Oder, um prziser zu sein, von Webdoku-
menten aus dem gleichen Ordner bzw. Webseiten aus Unterordnern. Im
Normalfall nicht von einer anderen Domne! (Wenn also
www.phpkid.de/index.html ein Cookie setzt, kann dieses nur von
www.phpkid.de/index.html oder www.phpkid.de/weblog/index.html,
aber nicht von www.shopmichel.de ausgelesen werden! Eine Aus-
nahme spielen die Cookies von Drittanbietern, die du auf jeden Fall de-
aktivieren solltest. Auch dazu gleich mehr!)
Nachdem du die technischen Daten kennst, interessiert dich sicher die Fra-
ge: Wo liegen die Biester?
Wo speichert der Browser die Cookies?
Jeder Browser verwaltet die Cookies auf unterschiedliche Art und Weise.
Der Internet Explorer unter Windows XP legt die Kekse in der Regel ab un-
ter C:\Dokumente und Einstellungen\Benutzername\Cookies. An
Stelle von Benutzername setzt du natrlich den Benutzernamen ein, den
du als Windows-Nutzer unter Windows XP besitzt. Bei lteren Windows-
Versionen ohne Nutzerprofile liegen die Cookies hufig aber auch unter
C:\Windows\Cookies. In diesem Ordner findest du lauter kurze Textda-
teien vor, in denen der Browser die entsprechenden Cookie-Daten lagert.

Der Internet Explorer legt die Cookies im gleichnamigen Ordner ab.
238
Surfer wiedererkennen mit Cookies

Kapitel
9 Du mchtest diesen Cookie-Ordner blitzschnell aufrufen, um die dort lie-
genden Textdateien einsehen zu knnen? Du arbeitest mit dem Win-
dows-Explorer unter Windows XP oder 98? Dann probiere meinen Super-
trick: Whle einfach START|AUSFHREN. Tippe die Zeichenfolge cookies in
das Dialogfenster ein und klicke auf OK. Schon steckst du mitten drin im
Cookie-Ordner. Wie zeigst du diese Dateien bersichtlich an? Whle am
besten ANSICHT|DETAILS. Achte auf die Spalte mit dem Speicherdatum!
Klicke auf den Spaltenkopf GENDERT AM, bis du die neuesten Cookies zu-
oberst siehst. Das eigentliche Aufrufen der entsprechenden Cookie-
Textdateien gelingt jetzt ganz einfach durch Doppelklick auf die entspre-
chende Textdatei.
Der Inhalt der Cookies besteht oft aus kryptischen Namen, Zeichen und
Nummern. Der Sinn erschliet sich oft nur dem Betreiber der Seite, der das
Cookie setzt. Hufig findest du in dieser Textdatei auch die Domain, von
der du den Keks erhalten hast. Das Haltbarkeitsdatum ist in einer langen
Nummer verschlsselt.
Du mchtest eine dieser Cookie-Dateien lschen? Nichts leichter als das.
Rechtsklicke auf die Datei. Befrdere Sie per LSCHEN-Befehl in den Papier-
korb! Bis auf die Verwaltungsdatei index.dat (die kannst du nicht l-
schen!) lassen sich alle Cookie-Dateien auf diese Weise eliminieren.
Der Firefox-Browser macht das Verwalten und Lschen der Cookies beson-
ders einfach. Whle EXTRAS|EINSTELLUNGEN. Klicke links auf den Bereich
DATENSCHUTZ und falls vorhanden auf das Register COOKIES. Klicke auf
die Schaltflche COOKIES ANZEIGEN. Du siehst nicht die nackte Textdatei,
sondern eine bersichtliche Maske. Hier kannst du alle Cookies nacheinan-
der einsehen. Wie du siehst, sind es nur kurze, oftmals kryptische Informa-
tionen. Du mchtest ein Cookie lschen? Klicke dazu einfach auf die
Schaltflche COOKIE ENTFERNEN. Whle ALLE COOKIES ENTFERNEN, wenn du dich
komplett von allen Cookies trennen mchtest.
Wann werden Cookies problematisch?
Eigentlich sind und waren Cookies als sinnvolle Komfortmanahme ge-
dacht! Und zwar als Komfortmanahme fr den Surfer. Inzwischen hat sich
die Welt jedoch weitergedreht und das Web wurde immer kommerzieller.
Solange du nur auf einer Seite herumsurfst, knnen dir die Cookies noch
nichts anhaben. Sie sind zwar da, doch der Betreiber der Webseite erfhrt
nichts von deiner Existenz.
239
Grundeinstellungen im Browser


Mit Hilfe von Cookies gehen kommerzielle Anbieter auf deine Bedrfnisse ein.
Das ndert sich sptestens dann, wenn du Daten von dir preisgibst. Du
fllst ein Formular aus? Du meldest dich mit einem Benutzernamen an? Du
bestellst in einem Onlineshop? Dann kann dich der Webseitenbetreiber
beim nchsten Besuch dank des Cookies namentlich zuordnen. Doch damit
nicht genug.
Dein Verhalten auf einer Webseite wird hufig sogar ganz genau ver-
folgt. Viele Seitenbetreiber erstellen regelrechte Nutzerprofile. Der On-
linehndler www.amazon.de zum Beispiel merkt sich deine Vorlieben
ganz genau. Du bist Amazon-Kunde und hattest beim vorigen Besuch
Sciencefiction-Literatur betrachtet? Dann bekommst du beim nchsten
Besuch mit groer Wahrscheinlichkeit Empfehlungen genau zu diesem
Thema. Der Surfer wird zum glsernen Konsumenten. Das geht sogar so
weit, dass dir manche Seitenbetreiber speziell auf deine Interessen zie-
lende Werbebanner einblenden.
Hier ist mir der Verlag Zweitausendeins (www.zweitausendeins.com) sehr
positiv aufgefallen. In einem ausfhrlichen Infotext erklrt der Verlag auf
seiner Webseite ganz genau, wozu die Cookies bentigt werden. Man versi-
chert dir, dass diese Textschnipsel nicht zum Tracking deines Nutzerver-
haltens verwendet werden. Eine sehr lbliche Ausnahme.
Grundeinstellungen im Browser
Wie du merkst, stehe ich diesen kleinen Informationskrmeln durchaus
kritisch gegenber, obwohl sie an und fr sich harmlos sind. Das ist auch
der Grund, warum viele aufgeklrte Surfer Cookies abschalten. Schade ei-
gentlich, denn Cookies erfll(t)en eine wichtige Funktion. Und wir brauchen
sie noch.
240
Surfer wiedererkennen mit Cookies

Kapitel
9
Was soll dein Browser nun mit den Keksen anfangen? Lass dir nicht alles
gefallen sortiere sie aus: die guten ins Tpfchen, die schlechten ins
Krpfchen. Richte dein Surfbrett wunschgem ein!
Einstellungen beim Internet Explorer
Du arbeitest mit dem Internet Explorer ab Version 6? Du mchtest ent-
scheiden, was mit Cookies passieren soll? So gehst du vor:
>
Whle EXTRAS|INTERNETOPTIONEN und gehe ins Register DATENSCHUTZ.
>
Schaue in den unteren Bereich. Klicke auf die Schaltflche ERWEITERT.
>
Setze das Hkchen vor der Option AUTOMATISCHE COOKIEBEHANDLUNG
AUFHEBEN.
>
Im Bereich COOKIES VON ERSTANBIETERN kannst du dich fr ANNEHMEN,
SPERREN oder EINGABEAUFFORDERUNG entscheiden.
Fr unsere Experimente empfehle ich dir diese Option namens
EINGABEAUFFORDERUNG. Dann erscheint bei jedem Cookie erst ein Dialog-
fenster mit den entsprechenden Cookie-Daten. Klicke dort auf die
Schaltflche DETAILS, wenn du mehr Informationen wnschst. Auf diese
Weise siehst du sofort, ob es mit dem Erstellen und Annehmen der Coo-
kies klappt, wie es soll!
>
Im Bereich COOKIES VON DRITTANBIETERN empfehle ich dir die Einstellung
SPERREN. Es handelt sich bei dieser Sorte von Cookies meist um Pltz-
chen irgendwelcher Werbeanbieter. Genau das ist auch mit Drittan-
bieter gemeint: Du besuchst z. B. www.phpkid.de und bekommst ein
Cookie von www.addcom.com serviert!
Beachte, dass die Einstellungen erst dann wirken, wenn du den Internet
Explorer schliet und wieder neu startest!
Du kannst im Internet Explorer sogar Cookies von bestimmten Seiten
blockieren. Whle EXTRAS|INTERNETOPTIONEN und gehe ins Register
DATENSCHUTZ. Klicke im Internet Explorer 6 auf die Schaltflche
BEARBEITEN, in Version 7 dagegen auf SITES. Gib die Domain ein, von der
du keine Cookies serviert bekommen mchtest. Tippe z. B. msn.de und
whle SPERREN. Damit blockierst du Cookies von der Microsoft-eigenen
Suchmaschine.
241
Krmelmonsters Keksfabrik: Cookies backen

Einstellungen fr Firefox
Der Firefox-Browser bietet auch recht umfangreiche Optionen zur Behand-
lung von Cookies.
>
Whle EXTRAS|EINSTELLUNGEN. Whle das Register DATENSCHUTZ und
schaue zum Pull-down-Men COOKIES BEHALTEN bzw. BEHALTEN BIS.
>
Whle fr unsere Experimente am besten die Option JEDES MAL
NACHFRAGEN.
>
Sehr ntzlich ist auch die Option BIS FIREFOX GESCHLOSSEN WIRD. Dann
berlebt kein Cookie lnger als einen Tag auch wenn dir die Anbie-
ter dauerhafte Cookies andrehen wollen!
Krmelmonsters Keksfabrik:
Cookies backen
Genug Vorbemerkungen ran an die Keksdose! Jetzt bist du derjenige, der
Pltzchen serviert. Es handelt sich um einen ganz harmlosen Keks: Begre
deine Besucher mal auf die persnliche Art. Das Prinzip ist einfach:
0 Deine Webseite setzt beim Besucher ein Cookie (sofern der Browser des
Besuchers Cookies akzeptiert)
0 Deine Webseite liest das Cookie falls vorhanden beim nchsten
Besuch wieder aus
Wichtig zu wissen: Ein Cookie besteht im einfachsten Fall aus einem Na-
me-Wert-Paar. Wir nennen unser Cookie visit und vergeben den Wert
yes. Doch wie?
Die Funktion setcookie()
Zum Setzen eines Cookies verwendest du die Funktion setcookie(). Der
Name dieser Funktion ist also Programm. Fehlen noch die Argumente, und
zwar der Cookiename und der Cookiewert. Bitte sehr, hier ist die komplette
Funktion:
setcookie("Cookiename", "Cookiewert")
Es handelt sich um eine ziemlich anwenderfreundliche, genial einfache
Funktion. Eine Sache musst du dir jedoch unbedingt merken! Und da sie so
wichtig ist, habe ich sie in einen Kasten gesetzt.
242
Surfer wiedererkennen mit Cookies

Kapitel
9 Ganz wichtig: Die Funktion funktioniert nur dann, wenn du sie ganz zu
Beginn der HTML-Seite einsetzt. Platziere sie noch vor dem einleitenden
HTML-Tag! Das Cookie muss im sogenannten Header der
HTML-Seite verschickt werden.

Wie wird das Cookie eigentlich ausgelesen? Dafr gibt es ein Array na-
mens $_COOKIE. Hier handelt es sich, brigens genau wie beim Array
$_POST zur Entgegennahme von Formulardaten, um ein assoziatives Ar-
ray. Der Name des Cookies wird automatisch zum Key des Arrays. Um auf
den Wert des Cookies visit zugreifen zu knnen, schreibst du einfach
$_COOKIE["visit"]. Ist das nicht fantastisch einfach?
Das Beispiel
Und nun zum Beispiel. Die folgende Datei setzt ein Cookie (vor dem einlei-
tenden HTML-Tag!) und liest es in einem zweiten PHP-Block wieder aus.
<?php
// Cookie wird gesetzt
setcookie("visit", "yes");
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="de">
<head>
<title>Cookie setzen und auslesen</title>
<meta http-equiv="content-type" content="text/html;
charset=utf-8">
<link rel="stylesheet" type="text/css" href="phpkid.css">
</head>
<body>
<h2>Cookie setzen und auslesen</h2>
<p>
<?php
// Ist das Cookie vorhanden und lautet der Wert yes?
if (isset($_COOKIE["visit"]) && $_COOKIE["visit"] == "yes") {
echo "Schn, dass du <b>wieder</b> da bist!\n";
} else {
echo "Schn, dass du da bist!\n";
}
?>
243
Der Keks bekommt ein MHD

</p>
</body>
</html>

Du findest das Beispiel auch unter dem Namen cookie1.php im Ordner
kapitel09. Probiere das Skript einfach aus.

Nach dem ersten Aufruf wirst du begrt mit Schn, dass du da bist!. Sp-
testens nach dem zweiten Aufruf steht jedoch Schn, dass du wieder da
bist! in der Seite.
Der Keks bekommt ein MHD
Unser Cookie besitzt einen Haken. Beim nchsten Aufruf der Seite hat der
Browser alles vergessen. Man knnte es auch als Cookie-Alzheimer be-
zeichnen.
Und tatschlich: Nach Schlieen des Browsers wird das Cookie normaler-
weise gelscht. Logisch, schlielich gilt es nur fr die aktuelle Sitzung. Fr
den Besucher ist das vielleicht ganz vorteilhaft. Doch fr dich als Cookie-
Ersteller? Schlielich wrdest du deine Besucher auch noch nach 30 Tagen
gerne persnlich begren drfen, oder?
Solange du dem Cookie kein Enddatum mit auf den Weg gibst, handelt es
sich um ein Sitzungscookie, um ein temporres Cookie. Im Klartext: Das
Cookie bleibt fr eine Sitzung aktiv, bestenfalls vielleicht noch fr ein paar
Stunden.
Wie wre es, wenn das Cookie fr 30 Tage gespeichert bliebe? Kein Pro-
blem! Verpasse deinem Keks eine Lebensdauergarantie.
Die gleiche Seite nach
dem ersten Aufruf und
bei einem Reload.
244
Surfer wiedererkennen mit Cookies

Kapitel
9
Ablaufdatum angeben
Die erweiterte Funktion mit Lebensdauergarantie sieht folgendermaen
aus:
setcookie("Cookiename", "Cookiewert", Ablaufdatum)
Interessant ist hierbei der neue Parameter Ablaufdatum. Es ist ein Zeitwert,
der in Sekunden gemessen wird. Ausgangspunkt ist die Zahl der Sekunden,
die seit Beginn der sogenannten Unix-Epoche vergangen sind. Addiere nun
die Zahl der Sekunden hinzu, die du in die Zukunft denkst.
Die Unix-Epoche ist ein festgelegter Wert. Die Unix-Epoche begann am
1.1.1970 um 0:00 Uhr.
Wie bekommst du diese mysterise Sekundenzahl heraus? Wie ermittelst
du die Zahl der Sekunden, die seit Beginn der Unix-Epoche vergangen sind?
Dieser Wert ndert sich doch stndig?! Du brauchst eine Funktion. Eine
Funktion, die die genaue Sekundenzahl der Unix-Epoche ausgibt. Diese
begabte Funktion heit time() verwende sie ohne alle Argumente! Diese
Funktion ermittelt die Anzahl der Sekunden seit Beginn der Unix-Epoche.
Wenn du dem Cookie eine Lebensdauergarantie mit auf den Weg geben
willst, addierst du zu time() einfach die Zahl der Sekunden, die du in die
Zukunft denkst. Das Cookie soll 30 Tage aktiv sein? Dann musst du
2592000 Sekunden in die Zukunft denken. bersichtlich ausgeschrieben
sieht das so aus: time() + 86400 * 30. (Die 86400 steht dabei fr die
Sekunden eines Tages, also 60 * 60 * 24.)
Herumkrmeln:
Cookies verspeisen
Ran an die Praxis. In unserem Beispiel musst du also nichts weiter tun als
die Zeile
setcookie("visit", "yes");
wie folgt zu ndern:
setcookie("visit", "yes", time() + 86400 * 30);
Wie kannst du dich davon berzeugen, ob das klappt? Hier hilft der Inter-
net Explorer! Achte darauf, dass die Option EINGABEAUFFORDERUNG einge-
schaltet ist, wie einige Seiten zuvor gezeigt.
245
Aufgegessen: Cookies lschen

Lade dein Dokument nun auf den Webserver. (Offline klappt es in der Regel
leider nicht mit der Eingabeaufforderung.) Nun erscheint das Dialogfenster
DATENSCHUTZHINWEIS. Du wirst ber die bevorstehende Cookiebergabe in-
formiert. Klicke in diesem Dialogfenster auf die Schaltflche DETAILS:

Das so angepasste Skript mit Lebensdauergarantie findest du unter dem
Namen cookie2.php.
Aufgegessen: Cookies lschen
Wie lscht man eigentlich ein Cookie? Diese Technik so scheint es mir
ist vielen Cookie-Produzenten unbekannt. Sie wollen es nicht wissen. Da
musst du als Konsument also von Zeit zu Zeit selber einmal aufrumen!
Du arbeitest mit dem Internet Explorer, Version 6? Du mchtest alle dei-
ne Cookies auf einen Schlag loswerden? Whle EXTRAS|INTERNETOPTIONEN.
Gehe ins Register ALLGEMEIN. Klicke auf die Schaltflche COOKIES LSCHEN.
So einfach ist das! In Version 7 klickst du erst auf LSCHEN danach er-
scheint dann die Schaltflche COOKIES LSCHEN. Im Firefox kannst du dei-
ne Cookies ber EXTRAS|PRIVATE DATEN LSCHEN loswerden.
Aber auch fr dich als Produzenten von Cookies gilt: Das Lschen ist sehr
simpel. bermittle dem Nutzer exakt das gleiche Cookie noch einmal.
bergib lediglich ein Enddatum, das in der Vergangenheit liegt. Die Zeile
knnte zum Beispiel so aussehen:
setcookie("visit", "yes", time() - 86400);
Das Cookie bekommt
eine Haltbarkeitsdauer
mit auf den Weg.
246
Surfer wiedererkennen mit Cookies

Kapitel
9 Schlussbemerkung
In diesem kurzen Kapitel hast du einen kleinen Einblick in die Cookie-
Technologie bekommen. Du kannst selber Cookies setzen, auslesen und
lschen. Du kennst die Vor- und Nachteile von Cookies.
Zusammenfassung
0 Du weit, dass Cookies an sich harmlos sind. Es handelt sich um einfa-
che Textdateien, in denen eine Webseite Informationen auf deinem
Rechner speichert.
0 Du weit, wie du mit der Funktion setcookie() Cookies setzen
kannst, die Argumente dieser Funktion lauten:
setcookie("Cookiename", "Cookiewert", Ablaufdatum).
0 Du weit, dass du Cookies lschst, indem du ein Ablaufdatum angibst,
das in der Vergangenheit liegt.
Ein paar Fragen
1. Wann begann die Unix-Epoche?
2. Darfst du die Funktion setcookie() an allen Stellen des HTML-
Dokuments angeben?
und ein paar Aufgaben
1. Erweitere das Skript so, dass das Cookie nicht nur fr 30 Tage, sondern
ungefhr fr ein ganzes Jahr gltig bleibt. Nenne die Seite
cookie3.php.
2. Erstelle eine Seite, die nichts weiter macht, als das Cookie zu lschen.
Nenne sie delete.php.
3. Platziere auf der Seite cookie3.php einen Link zu delete.php. Wh-
le als Linkbeschreibung einfach Gedchnis lschen. Erstelle auf der Seite
delete.php einen Link namens Zurck zur Gedchtnisseite.
4. Probiere die beiden Seiten aus.

247



10
Besucherzhler selbst
gebaut
Es lebe die Eitelkeit! Wie wrs mit einem Zhler fr die Homepage? Klar
willst du wissen, wie viele Besucher sich auf deiner Homepage tummeln.
Wer will das nicht? Bei dieser Gelegenheit zeige ich dir, wie du
$ Daten in Textdateien schreibst
$ Daten aus Textdateien wieder ausliest
$ eine Textdatei mit Schreibrechten im Unix-Dateisystem versiehst
$ das knstliche Hochpuschen des Zhlers durch Reloads unterbindest

Damit du durch das Beispiel gut durchsteigst, habe ich es so einfach wie
mglich gehalten. Aber es funktioniert!
Alles in allem ist dieses Kapitel ein sehr wichtiges Kapitel. Du lernst das
erste Mal, wie du Daten in Dateien ablegen kannst. Denn gerade dieses
Thema zeichnet eine Serverprogrammiersprache aus. Du sicherst Infor-
mationen auf dem Webserver und liest sie wieder aus.

248
Besucherzhler selbst gebaut

Kapitel
10 Zwei Dateien: So funktioniert das
Beispiel
Unser Besucherzhler arbeitet mit zwei Dateien. Zum einen ist das die
Hauptdatei also die Datei, in die wir einen Zhler einbauen. Diese nennen
wir im Beispiel
0 index.php
Auerdem bentigen wir eine zweite Datei, eine einfache Textdatei. Hier
soll der aktuelle Zhlstand gespeichert werden. Ich schlage folgenden Na-
men vor:
0 count.txt
Textdatei anlegen
Lege zuerst die Textdatei count.txt an. Mit PSPad geht das ganz fantas-
tisch schnell:
>
Klicke auf die Schaltflche NEUE DATEI ERSTELLEN, also direkt auf das
weie Blatt. Ein leeres Dokument erscheint.
>
Tippe eine 0 fr den Zhlstand und whle den Befehl SPEICHERN.
>
Speichere die Datei im gleichen Ordner wie die index.php und nen-
ne sie count.txt.
So funktioniert das Beispiel
Unser Skript macht Folgendes: Die PHP-Datei index.php ffnet die
count.txt, liest den Wert aus und zeigt ihn an. Das ist die Zahl, die der
Besucher sieht.
Gleichzeitig erhht das Skript diesen Wert um 1. Der neue Wert wird sofort
zurckgeschrieben und somit in der aktualisierten count.txt gespeichert.
Bei einem erneuten Aufruf der index.php geht das Spielchen von vorne
los. Diesmal jedoch mit dem neuen Wert aus der count.txt.
Hitmaschine: Ein Textcounter
Im Beispiel geht es also um einen Textcounter, um eine Hitmaschine. Sie
zhlt jeden Hit, also auch jeden Druck auf den RELOAD-Button.
249
Datei zum Lesen ffnen

Zum Verstndnis zeige ich dir diesmal den kompletten Quelltext vorab. Es
ist der Bereich zwischen den Tags <body> und </body>. Danach gehen wir
alle Codezeilen Schritt fr Schritt durch!
<h2>Ein Textcounter</h2>
<p>Die Seite wurde
<b><?php
$fp = fopen("count.txt", "r+");
$counter = fgets($fp, 10);
echo $counter;
$counter++;
rewind($fp);
fputs($fp, $counter);
fclose($fp);
?></b>-mal aufgerufen.</p>

Wenn du mchtest, kannst du das Beispiel ruhig schon einmal ausprobie-
ren. Oder du schlgst im Ordner kapitel10 auf der CD nach.

Datei zum Lesen ffnen
Zuerst musst du wissen, wie man eine Datei zum Lesen ffnet.
Die Funktion fopen()
Das gelingt mit Hilfe der Funktion
fopen()
Die Funktion wird meist in folgender Syntax verwendet:
fopen("Dateiname", "Modus")
Die Argumente der Funktion (das Zeugs in runden Klammern) sehen auf
den ersten Blick ziemlich kriminell aus. Einverstanden, zumindest den Da-
Bei jedem Neuladen der
Seite wird der Zhler
um 1 erhht.
250
Besucherzhler selbst gebaut

Kapitel
10
teinamen kannst du leicht entschlsseln. Trage innerhalb der Gnsefchen
den Namen der zu lesenden Datei ein. Im Beispiel ist das count.txt.
Doch was hat es mit diesem merkwrdigen Modus auf sich? Ganz einfach:
Der Modus drckt aus, was du mit der Datei machen kannst. Folgende Modi
gibt es:
Modus Erklrung
r Nur-Lesemodus (r wie read only), die Datei kann nur gelesen werden.
r+ Lese- und Schreibmodus (r+ wie read and write), die Datei kann gelesen
und beschrieben werden.
w Nur-Schreibmodus (w wie write only), die Datei kann nur beschrieben
werden. Sie wird dabei stets auf 0 Byte gesetzt. Falls die Datei nicht
vorhanden ist, wird versucht, sie anzulegen.
w+ Lese- und Schreibmodus (w+ wie write and read), die Datei kann gele-
sen und beschrieben werden. Sie wird dabei stets auf 0 Byte gesetzt.
Falls die Datei nicht vorhanden ist, wird versucht, sie anzulegen.
a Anhnge-Schreib-Modus (a wie append), ffnet die Datei zum Schrei-
ben, alle neuen Werte werden unten ans Dateiende angehngt. Der
Dateizeiger steht daher ausnahmsweise nicht am Anfang, sondern am
Ende der Datei. Falls die Datei nicht vorhanden ist, wird versucht, sie
anzulegen.
a+ Anhnge-Lese- und Schreib-Modus (a+ wie append and read), ffnet
die Datei nur zum Lesen und Schreiben, alle neuen Werte werden unten
ans Dateiende angehngt. Der Dateizeiger steht daher ausnahmswei-
se nicht am Anfang, sondern am Ende der Datei. Falls die Datei nicht
vorhanden ist, wird versucht, sie anzulegen.

Keine Sorge, du brauchst diese Modi nicht auswendig zu lernen! Wir ben-
tigen lediglich den Modus r+ fr read and write. Wir lesen aus einer Datei
und schreiben wieder hinein. (Abgesehen davon halte ich noch die Modi r,
a und a+ fr halbwegs brauchbar, eingesetzt habe ich sie ganz persnlich
jedoch bisher noch nicht.)
Zurck zum Modus r+: Das Lesen und Schreiben beginnt bei diesem Modus
am Anfang der Datei. Anders ausgedrckt: Bei diesem Modus steht der
geheimnisvolle Dateizeiger stets am Anfang der Datei.
Der geheimnisvolle Dateizeiger
Was ist das fr ein komisches Ding, dieser Dateizeiger? Und was machst du
damit? Das schauen wir uns jetzt etwas genauer an!
251
Der geheimnisvolle Dateizeiger

Die Funktion fopen() positioniert stets einen Dateizeiger in der Datei.
Entweder am Anfang oder am Ende. Wo genau, hngt vom eben bespro-
chenen Modus ab. Beim Modus r+ wird der Zeiger am Anfang platziert.
Wenn die Datei einmal geffnet ist, arbeitet man mit diesem Dateizeiger
weiter. Aus diesem Grund wird der Status dieses Dateizeigers zuerst in
einer Variablen gesichert. Diese Variable heit im Beispiel $fp wie file
pointer. Diese Bezeichnung ist schn kurz und bedeutet nichts weiter
als Dateizeiger. Du knntest diese Variable aber auch $zeiger oder
$dateizeiger nennen. Die Namenswahl bleibt dir berlassen!
Mit Dateizeiger sieht die Zeile folgendermaen aus:
$fp = fopen("Dateiname", "Modus");
Du hast Probleme, dir etwas unter diesem Dateizeiger vorzustellen? Stel-
le es dir wie einen unsichtbaren Cursor vor! Am Anfang steht der Cursor
am Beginn der Textdatei. Diesen Stand sicherst du in der Variablen $fp.
Im Laufe des Skripts bewegst du diesen unsichtbaren Cursor hin und her!
Die Funktion fgets()
Damit haben wir die erste Zeile des Skripts abgearbeitet. Doch was passiert
danach?
$counter = fgets($fp, 10);
Hier kommt die neue Funktion fgets() ins Spiel. Diese Funktion liest Da-
ten aus einer Datei. Der Lesevorgang endet, wenn die Zeile bzw. Datei zu
Ende ist. Oder wenn die maximale Zahl an Bytes erreicht ist.
Die Grundsyntax dieser Funktion mit diesen gerade erwhnten Argumenten
sieht folgendermaen aus:
fgets($fp, Lnge_in_Byte)
Zuerst bentigt die Funktion also den eben ermittelten Dateizeiger. Kein
Problem, dafr steht schlielich die Variable $fp bereit. Auch das zweite
Argument ist kein Rtsel: Hier muss eine Hchstlnge angegeben werden,
und zwar in Byte. Schlielich heit es nicht umsonst: Der Lesevorgang
endet auch dann, wenn die maximale Zahl an Bytes erreicht ist!
252
Besucherzhler selbst gebaut

Kapitel
10
Im Beispiel habe ich mich fr die 10 entschieden. Im Klartext: Dein Counter
kann bis zu neun Stellen besitzen. Sollte die Zahl lnger sein, werden die
restlichen Stellen einfach beim Lesen und Schreiben ignoriert, abgeschnit-
ten! (Probiere es ruhig aus. Schreibe eine sehr lange Zahl in die Datei
count.txt. Prfe, wie viele Stellen angezeigt werden!)
Zurck zu unserer Funktion: Sie liest die Daten aus der Datei, beim alle-
rersten Aufruf ist das die Zahl 0. Diese Zahl wird nun in der Variablen
$counter gesichert.
Beachte: Der geheimnisvolle Dateizeiger ist bei dieser Aktion schnur-
stracks ans Ende der Zeile gewandert! Diese Position musst du dir mer-
ken!
Daten in eine Textdatei schreiben
Die nchsten beiden Zeilen erschlieen sich sicher sofort:
echo $counter;
$counter++;

Der aus der Textdatei ausgelesene Wert wird angezeigt und um 1 erhht.
Dateizeiger zurcksetzen per rewind()
Doch was passiert in der nchsten Zeile? Hier wird der Dateizeiger zuerst
an den Anfang der Datei zurckgesetzt. Denn bisher blinkt unser unsicht-
barer Cursor immer noch am Dateiende und dort ntzt er uns nichts.
Das Zurcksetzen an den Anfang gelingt mit Hilfe der Funktion rewind().
rewind($fp);
Da es sich hier nur um eine Zeile handelt, bewirkt rewind() das Gleiche,
als ob du in deiner Textverarbeitung auf die Tastenkombination (Strg) +
(Pos1) drcken wrdest. Auch da springt der Cursor an den Anfang der
Datei.
(Da es nur eine Zeile ist, htte ich auf dem Wort Datei gar nicht so herum-
reiten mssen. Htte die Datei jedoch mehrere Zeilen, wrde rewind() an
den Anfang der allerersten Zeile springen.)
253
Rechtevergabe mit chmod

Die Funktion fputs()
So, und nun packst du den erhhten Wert aus der Variablen $counter
zurck in die Textdatei count.txt. Dabei hilft dir die Funktion fputs().
Diese Funktion schreibt Daten in eine Datei, und zwar zeilenweise. Die
Grundsyntax sieht so aus:
fputs($fp, Daten)
Die Funktion schreibt also ab der Position des Dateizeigers los. Sie trgt im
Beispiel also den neuen Zhlerstand aus $counter in die Datei ein:
fputs($fp, $counter);
Was passiert dabei eigentlich mit dem alten Wert? Der wird einfach
berschrieben, da sich der Dateizeiger vor Ausfhrung der Funktion am
Anfang befand! Schlielich hatten wir die Funktion fgets() nicht um-
sonst eingesetzt.
Datei schlieen mit fclose()
Am Ende der Schreiberei sollte eine Datei stets wieder geschlossen werden.
Das gelingt mit der Funktion fclose(), wie file close. Als Argument wird
dabei wieder der Dateizeiger bergeben:
fclose($fp);
So einfach ist das also mit dem Zhler!
Rechtevergabe mit chmod
Auf deiner lokalen Festplatte funktioniert sicher alles ganz fantastisch.
Du mchtest das Beispiel auf den Webserver laden und online ausprobie-
ren? Mit FTP, wie im Anhang erklrt?
Dann beachte unbedingt eine Besonderheit im Zusammenhang mit der
Textdatei count.txt! Schlielich wird in diese Datei geschrieben. Was auf
dem lokalen Computer prima funktioniert, bereitet auf dem Webserver
unter Umstnden einige Schwierigkeiten. Du musst bei vielen Dienstleistern
erst die entsprechenden Rechte vergeben, damit in diese Datei geschrieben
werden kann.
254
Besucherzhler selbst gebaut

Kapitel
10

Wenn du die Rechtevergabe vergisst, hagelt es unter Umstnden Fehlermeldungen!
Die Besucher besitzen normalerweise nur Leserechte. Nach dem ber-
spielen auf den Webserver gilt die Datei als schreibgeschtzt. Wie hebt
man den Schreibschutz in einem Unix/Linux-System auf dem Webserver
auf? Das gelingt mit dem Befehl chmod.
chmod 777
Die Radikallsung: Gib die Datei komplett zum Lesen, Schreiben und Aus-
fhren frei. Das entsprche dem Befehl chmod 777.
Du arbeitest mit dem von mir empfohlenen Programm FileZilla? Verbinde
dich mit dem Server, wie im Anhang gezeigt. Achte darauf, dass die Datei
count.txt zu sehen ist. Klicke im rechten Bereich mit der rechten
Maustaste auf diese Datei. Whle nun den Befehl DATEIATTRIBUTE. Das
Fenster DATEIATTRIBUTE NDERN erscheint. Hake alle Optionen ab (das sind
3 x 3 Hkchen je bei LESEN/SCHREIBEN/AUSFHREN) und klicke auf OK. Jetzt
wird die Datei komplett freigegeben, im Hintergrund wird der Befehl
chmod 777 ausgefhrt.
Mit diesen Einstellungen gibst du die Datei komplett frei. Das funktioniert
zwar, ist aus Sicherheitsgrnden aber keinesfalls die beste Lsung!
chmod 666 oder 644
Bei vielen Dienstleistern gengt aber auch der Befehl chmod 666 oder gar
chmod 644 vollkommen. Das bedeutet, dass du beim Wert 666 allen drei
Gruppen (Besitzer, Gruppe, ffentlich) immerhin Lese- und Schreibberech-
tigung erteilst. Beim noch restriktiveren Wert 644 bekommt nur der Besit-
zer die zustzliche Schreibberechtigung.
Je restriktiver die Berechtigung, desto besser. Probiere also auf jeden Fall,
ob bei dir auch eine schwchere Berechtigung noch funktioniert!
255
Rechtevergabe mit chmod


Probiere es aus: Hufig reicht auch schon chmod 666.
Schaue in FileZilla auch mal in die Spalte Berechtigung. Suche in der nun
angezeigten Textdatei die entsprechende Zeile fr die count.txt. Die
Zeichenfolge -rwxrwxrwx entsprche der zuerst zugewiesenen Vollbe-
rechtigung mit chmod 777. Fr chmod 666 sieht das Ganze so aus:
-rw-rw-rw-. Interessant zu wissen: Das r steht fr read, das w fr
write und x fr execute. Die Berechtigungsreihenfolge lautet: Owner,
Group, Other.
Geht es gar ganz ohne?
Experimentiere, ob dein Counter bei dir auch bei weiteren Einschrnkungen
der Benutzerrechte noch funktioniert. Zumindest beim Dienstleister
1 und 1 GmbH (www.puretec.de) klappt es auch dann, wenn nur dem Be-
sitzer (Owner) Lese- und Schreibrechte eingerumt wurden. Das entsprche
einem chmod 600 und damit bei der DIRINFO-Anzeige folgender Zeichen-
folge: -rw-------. Im Klartext: Du brauchst zumindest bei diesem Dienst-
leister (und inzwischen auch bei vielen anderen) gar nichts mit der Datei
count.txt zu machen.
Beim Dienstleister Neue Medien Mnnich (www.all-inkl.com) dagegen
klappte es nicht von Hause aus, aber mit einem Trick! Lege eine Datei na-
mens .htaccess (mit Punkt beginnend und ohne Endung!) in das Wurzel-
verzeichnis deiner Prsenz und notiere dort Folgendes:
AddHandler php-cgi .php .php5
256
Besucherzhler selbst gebaut

Kapitel
10
Dadurch wird PHP als CGI-Version ausgefhrt, nicht mehr als Modul viele
Restriktionen fallen dadurch weg.
Die Hinweise aus diesem Abschnitt gelten brigens auch fr das Gste-
buch und fr die Umfrage. Denn auch bei diesen Beispielen schreibst du
in und liest aus Dateien. Behalte das am besten gut im Hinterkopf!
Counter de luxe mit Cookies
Der Counter hat bisher einen groen Haken: Es handelt sich um einen Hit-
Counter. Wenn du 100-mal auf den RELOAD-Button klickst, simulierst du
damit 100 Hits. Das macht sicher ganz schn etwas her, doch damit be-
lgst du dich nur selber.
Ich schlage eine Lsung vor, die etwas nher an der Wahrheit ist. Sie funk-
tioniert mit den im vorigen Kapitel kennengelernten Cookies.
Ran an den neuen Quelltext: Diesmal zeige ich dir die gesamte PHP-Datei.
Hinweis zur CD: Ich habe das Projekt in einem separaten Unterordner na-
mens realcount gespeichert:
<?php
// Cookie wird gesetzt
setcookie("count", "yes");
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN">
<html lang="de">
<head>
<title>Ein Cookie-Textcounter</title>
<meta http-equiv="content-type" content="text/html;
charset=utf-8">
<link rel="stylesheet" type="text/css" href="phpkid.css">
</head>
<body>
<h2>Ein Textcounter</h2>
<p>Die Seite wurde
<b><?php
$fp = fopen("count.txt", "r+");
$counter = fgets($fp, 10);
257
So funktioniert das Skript

echo $counter;
if (empty($_COOKIE["count"])) {
$counter++;
}
rewind($fp);
fputs($fp, $counter);
fclose($fp);
?></b>-mal aufgerufen.</p>
</body>
</html>
So funktioniert das Skript
Die Wirkungsweise des Skripts ist eigentlich ganz einfach. Zuerst erzeugst
du mit der Zeile setcookie("count", "yes"); ein Cookie. Der Name
lautet count, der Wert yes. (Der Wert spielt im Beispiel aber nur eine un-
tergeordnete Rolle.) Da kein Enddatum angegeben wurde, handelt es sich
um ein Sitzungscookie. Es verfllt nach Schlieen des Browsers.
Zur Erinnerung: Die Cookievergabe muss ganz am Anfang der Datei ge-
schehen, noch vor dem einleitenden HTML-Tag. So wird das Cookie gleich
im Header an den Browser geschickt (und von diesem hoffentlich akzep-
tiert).
Die folgenden Zeilen prfen nun, ob das Cookie mit dem Namen count leer
ist, also noch nicht existiert. Beim ersten Aufruf der Seite stimmt die Be-
dingung, denn dann existiert das Cookie tatschlich noch nicht. (Ein vom
Browser akzeptiertes Cookie kommt erst nach einem Reload zur Geltung!)
if (empty($_COOKIE["count"])) {
$counter++;
}

Nur dann wird der Zhler erhht und das ist gut so.
Sobald das Cookie nach einem Neuladen existiert, bleibt der Zhler unan-
getastet. Er wird erst wieder erhht, wenn der Benutzer den Browser
schliet, wieder ffnet und deine Seite erneut besucht!
Einen Haken gibt es bei der Sache: Dieser Zhlstopp funktioniert nur dann,
wenn der Benutzer Cookies akzeptiert. Da das in den meisten Fllen jedoch
der Fall ist, handelt es sich um eine funktionierende Zhlsperre.
258
Besucherzhler selbst gebaut

Kapitel
10 Schlussbemerkung
Endlich kannst du einen eigenen Counter schreiben. Zhle entweder nur die
Hits. Oder erstelle einen Counter de luxe mit Cookie-Zhlstopp. Wie auch
immer: Du weit, wie du Daten in Dateien ablegen kannst. Du sicherst In-
formationen auf dem Webserver und liest sie wieder aus!
Zusammenfassung
0 Du kennst die Funktion fopen() zum Lesen einer Datei. Dabei wird ein
Dateizeiger in der Datei positioniert, dessen Status du in einer Variablen
festhltst: $fp = fopen("Dateiname", "Modus").
0 Du kennst die Funktion fgets() zum zeilenweisen Auslesen der in
einer Datei enthaltenen Daten: fgets($fp, Lnge_in_Byte).
0 Du weit, dass du mit der Funktion rewind() den Dateizeiger an den
Anfang der Datei setzen kannst: rewind($fp).
0 Du kennst die Funktion fputs(), die ab der Position des Dateizeigers
Daten in eine Datei schreibt: fputs($fp, Daten).
0 Mit fclose() wird eine Datei wieder geschlossen: fclose($fp).
0 Du weit, dass du einer per FTP auf den Webserver geladenen Textdatei
in der Regel die entsprechenden Rechte erteilen musst. Dafr nutzt du
den Befehl chmod 666, der dem Owner, der Group und der ffentlich-
keit Lese- und Schreibberechtigung erteilt!
Ein paar Fragen
1. Mit welcher Funktion kannst du eine Datei ffnen?
2. Welcher Modus sorgt dafr, dass eine Datei im Lese- und Schreibmodus
geffnet wird und dass gleichzeitig der Dateizeiger am Anfang steht?
3. Mit welcher Funktion setzt du den Dateizeiger an den Anfang der Datei
zurck?
4. Mit welcher Funktion schreibst du Daten in eine Datei, beginnend mit
der Position des Dateizeigers?
5. Mit welcher Funktion wird eine Datei wieder geschlossen?
259
und ein paar Aufgaben

6. Was musst du mit einer Textdatei in der Regel machen, nachdem du sie
auf den Webserver geladen hast? Wie erreichst du, dass Schreibzugriff
besteht?
und ein paar Aufgaben
1. Bisher handelt es sich um ein Sitzungscookie. Wandle das Beispiel so
um, dass der Zhlstopp eine Stunde lang gilt!
2. Wandle das Beispiel so um, dass der Zhlstopp 24 Stunden lang gilt!

261



11
Eine Umfrage mit
grafischer Auswertung
Was hltst du von Matheklausuren? Wie erfolgreich ist die Klimapolitik der
Bundesregierung? Schafft es Hansa Rostock wieder zurck in die
1. Bundesliga? Wie findest du meine Homepage? Egal welches Thema dich
interessiert finde heraus, was andere darber denken!
In diesem spannenden Kapitel programmierst du eine richtig gehende Web-
Umfrage. Dabei lernst du, wie man
$ Strings anhand von Trennzeichen in Arrays umwandelt
$ durch Trennzeichen separierte Textdateien einliest
$ ein Sulendiagramm fr die grafische Darstellung erstellt
$ Radiobuttons in einem Formular ausliest

Damit du durch das Beispiel gut durchsteigst, habe ich es wieder mglichst
einfach gehalten. Trotzdem kommt hier schon einiges auf dich zu!
262
Eine Umfrage mit grafischer Auswertung

Kapitel
11 So sieht das Beispiel aus
Nun zum Beispiel! Erinnerst du dich noch an die Umfrage aus Kapitel 1?
Richtig, es ging um die Meinung zu deiner Homepage. Am Anfang des
Buchs musstest du dich noch mit einer statischen Lsung begngen.
Im diesem Kapitel hast du gengend Know-how beisammen, um das Bei-
spiel mit Leben zu fllen!

Der Unterschied zu Kapitel 1: Statt mit einer statischen HTML-Datei arbei-
test du von Anfang an mit PHP. Die Umfrage selber erfolgt in der Datei
0 umfrage.php
Fr die attraktive grafische Auswertung sehen wir folgende Datei vor:
0 ergebnis.php
Zume das Pferd diesmal von hinten auf: Fange mit dieser attraktiven gra-
fischen Auswertung an!
Umfrage und Auswer-
tung werden auf
getrennten Seiten
gefhrt.
263
Durch Komma separierte Textdatei

Durch Komma separierte
Textdatei
Die groe Frage lautet: Wie speicherst du die Daten? In welcher Form? Kein
Problem. Natrlich in einer Textdatei! Im Beispiel heit diese Datei
0 result.txt
Bei unserer Beispiel-Umfrage mssen drei Werte gesichert werden. Zum
einen der Wert fr die OPTION 1 (hier: echt super), fr die OPTION 2 (hier:
ziemlich gut) und fr die OPTION 3 (hier: geht so). Jeder Wert besteht aus
einer Ziffer, die die Anzahl der entsprechenden Stimmen reprsentiert.
Meine Idee: Trenne diese drei Werte jeweils durch ein Komma, und zwar
ohne irgendwelche Leerzeichen zwischendrin:
0 Wert_1,Wert_2,Wert_3
Und schon handelt es sich um eine der berhmten kommaseparierten Text-
dateien.
Datei result.txt anlegen
Jetzt kommt dein Part: Bereite diese Datei result.txt einfach schon
einmal vor. Gehe dabei so vor, wie am Beispiel der count.txt aus dem
vorigen Kapitel gezeigt. Dabei vergibst du gleichzeitig deine Stimme, denn
das Skript geht davon aus, dass mindestens ein Wert vergeben wurde.
Die Datei soll im Beispiel also folgendermaen aussehen:
0,1,0

Das bedeutet: Bisher wurde eine Stimme abgegeben, und zwar fr die mitt-
lere Option.
Du willst diese Datei auf den Webserver laden? Beachte auch hier die
ausfhrlichen Hinweise zum Schreibschutz aus dem vorigen Kapitel. Da-
mit das Beispiel auch online funktioniert, musst du bei einigen Dienst-
leistern den Befehl chmod 666 ausfhren!
264
Eine Umfrage mit grafischer Auswertung

Kapitel
11
Quelltext der Datei ergebnis.php
Die Textdatei result.txt hast du angelegt? Wunderbar! Dann zeige ich
dir nun den Quelltext der Auswertungsdatei ergebnis.php. Du siehst
alles, was zwischen den Tags <body> und </body> steckt.
Schreibe das Beispiel ab oder schaue auf die CD zum Buch, Ordner
kapitel11:
<h2>Die Umfrage-Ergebnisse:</h2>
<?php
$datei = "result.txt";
$fp = fopen($datei, "r");
$vote = fread($fp, filesize($datei));
fclose($fp);
// String zerlegen, Array entsteht
$vote = explode(",",$vote);
// Gesamtzahl aller Wahlvorgnge
$gesamt = $vote[0] + $vote[1] + $vote[2];
// Hchstlnge der Balken angeben
$laenge = 400;
// Anteil von Balken 1 (Indexwert 0!)
$laenge0 = $vote[0] * $laenge / $gesamt;
// Anteil von Balken 2 (Indexwert 1!)
$laenge1 = $vote[1] * $laenge / $gesamt;
// Anteil von Balken 3 (Indexwert 2!)
$laenge2 = $vote[2] * $laenge / $gesamt;
// Werte auf ganze Zahlen runden
$laenge0 = round($laenge0);
$laenge1 = round($laenge1);
$laenge2 = round($laenge2);
?>
<p>Anzahl der Stimmen: <b><?php echo $gesamt;?></b></p>
<table border="0">
<tr>
<td width="100">echt super</td>
<td>&nbsp;</td><td width="<?php echo $laenge0;?>"
bgcolor="red">&nbsp;</td>
<td>&nbsp;<i><?php echo $vote[0];?></i></td>
</tr></table>
<table border="0">
<tr>
<td width="100">ziemlich gut</td>
265
Durch Komma separierte Textdatei

<td>&nbsp;</td><td width="<?php echo $laenge1;?>"
bgcolor="green">&nbsp;</td>
<td>&nbsp;<i><?php echo $vote[1];?></i></td>
</tr></table>
<table border="0">
<tr>
<td width="100">geht so</td>
<td>&nbsp;</td><td width="<?php echo $laenge2;?>"
bgcolor="black">&nbsp;</td>
<td>&nbsp;<i><?php echo $vote[2];?></i></td>
</tr></table>
Die ersten Zeilen im berblick
Schritt fr Schritt weihe ich dich nun in die Geheimnisse dieses Skripts ein.
Was steckt hinter den folgenden Zeilen?
$datei = "result.txt";
$fp = fopen($datei, "r");
$vote = fread($fp, filesize($datei));
fclose($fp);

Zuerst speicherst du den Namen der Textdatei in der Variablen $datei,
und zwar aus reiner Bequemlichkeit. Als Nchstes ffnest du diese Datei.
Da wir an dieser Stelle nichts mehr in die Datei hineinschreiben mssen,
gengt der Nur-Lesemodus r.
Auch hier wird brigens wieder mit dem unsichtbaren Dateizeiger gearbei-
tet (Variable $fp).
Die Funktionen fread() und filesize()
Nun zur dritten Zeile: Hier liest du den Dateiinhalt aus und speicherst ihn
in der Variablen $vote. Im Beispiel handelt es sich um die Zeichenfolge
0,1,0. Zum Auslesen bentigst du die Funktion fread(). Du bergibst der
Funktion fread() zwei Argumente, einmal den Dateizeiger $fp und zum
anderen die Maximalgre in Byte. Die Funktion liest den Dateiinhalt bis zu
dieser Gre oder aber bis zum Ende.
Als Argument fr die Maximalgre kommt zum ersten Mal die Funktion
filesize() zum Einsatz.
266
Eine Umfrage mit grafischer Auswertung

Kapitel
11 Die Funktion filesize() ermittelt die Gre einer Datei. Die Syntax
lautet ganz einfach filesize("Dateiname"), wobei ich statt des Na-
mens natrlich auch eine Variable bergeben kann, wie im Beispiel. Der
Vorteil dieser Funktion liegt auf der Hand: Statt eine Hchstlnge in Byte
angeben zu mssen, ermittle ich einfach die exakte Lnge der Datei. So
kommt es weder zum Verschwenden von Speicherplatz noch zum verse-
hentlichen Abschneiden zu langer Strings.
Nun steht dir der auszuwertende String zur Verfgung und die Datei kann
mit der letzten der vier Zeilen seelenruhig wieder geschlossen werden.
Doch wie machst du aus der Zeichenfolge 0,1,0 oder 24,15,6 ein schi-
ckes Diagramm? Lies weiter, dann verrate ich es dir!
Text am Trennzeichen zerlegen
Schau dir nun folgende Passage an:
// String zerlegen, Array entsteht
$vote = explode(",", $vote);

In der ersten Zeile handelt es sich um einen beschreibenden Kommentar.
Wie du siehst, arbeite ich in meinen Skripts viel mit dieser Technik. Die
zweite und eigentlich wichtige Zeile beherbergt eine neue und ziemlich
geniale Funktion.
Die Funktion explode()
Es handelt sich um die Funktion explode(). Die Syntax lautet:
explode("Trennzeichen", "Zu_trennender_String")
Die Funktion explode() zerteilt einen String anhand eines Trennzeichens.
Im Beispiel verwende ich das Komma, aber du knntest auch ein anderes
Zeichen als Trenner festlegen. Der String wird dabei in ein Array umgewan-
delt, also in eine dieser schon hufig besprochenen Wertelisten. Die einzel-
nen Zahlen (bisher zwei Nullen und eine Eins) werden so zu den Elementen
des Arrays.
Stelle es dir so vor, als ob an jedem Komma ein klitzekleiner Sprengsatz
hngt. Dieser sorgt dafr, dass die einzelnen Werte auseinander explodie-
ren.
267
Die unsichtbare Tabelle fr das Diagramm

Die drei auf diese Art getrennten Ziffern 0, 1 und 0 werden jetzt als erster,
zweiter bzw. dritter Wert des Arrays angesprochen. Halt, das ist nicht ganz
korrekt: Eigentlich mssen sie als nullter, erster und zweiter Wert angese-
hen werden, denn die Zhlung beginnt bei numerischen Arrays schlielich
bei null!
Genau dieses Technik kommt im Beispiel zum Einsatz: Die Daten werden
zuerst in einer kommaseparierten Textdatei gespeichert. Die einzelnen
Zahlen werden dann zu den Elementen eines Arrays. Die erste Zahl lsst
sich z. B. ber Arrayname[0] ansprechen, also ber $vote[0], die
zweite Zahl ber $vote[1] und die dritte ber $vote[2].
Gesamtzahl aller Wahlvorgnge
Die nchste Passage ist nicht weiter kompliziert. Sie ermittelt die Gesamt-
zahl aller Wahlvorgnge und legt diesen Wert in der Variablen $gesamt ab.
// Gesamtzahl aller Wahlvorgnge
$gesamt = $vote[0] + $vote[1] + $vote[2];

Im Beispiel ergibt die Gesamtzahl den Wert 1, es handelt sich bisher um
deine eigene wunderbare Stimme.
Die unsichtbare Tabelle fr das
Diagramm
So weit, so gut, doch wie entsteht das Sulendiagramm? Ganz einfach
erinnerst du dich an das Diagramm aus Kapitel 6? Auch hier verwende ich
den gleichen Trick: Das Sulendiagramm entsteht durch unterschiedlich
lange Zellen dreier unsichtbarer Tabellen!
Durch verschiedene Farben gelingt auch die optische Unterscheidung.
berzeuge dich: berspringe einfach die nchsten Zeilen und schaue nun
zum Beginn der ersten Tabelle. Oberhalb der Tabelle wird erst einmal die
Gesamtstimmenzahl ausgegeben:
<p>Anzahl der Stimmen: <b><?php echo $gesamt;?></b></p>

268
Eine Umfrage mit grafischer Auswertung

Kapitel
11
Doch danach geht es los mit den Sulen. Die erste unsichtbare Tabelle
(border="0") entsteht:
<table border="0">
<tr>
<td width="100">echt super</td>
<td>&nbsp;</td><td width="<?php echo $laenge0;?>"
bgcolor="red">&nbsp;</td>
<td>&nbsp;<i><?php echo $vote[0];?></i></td>
</tr></table>

Die erste Zelle ist 100 Pixel lang und beherbergt den Text echt super. Inte-
ressant ist die zweite Zelle: Wie erreiche ich hier, dass die Lnge der Sule
variiert? Ich gebe dem Attribut width der zweiten Zelle einen dynamischen
Wert mit auf den Weg. Diesen entnehme ich der Variablen laenge0. (Wie
wir auf diese Variable kommen, erfhrst du gleich!)
Die dritte Zelle gibt lediglich die Anzahl der Stimmen aus und damit ist die
erste Sule auch schon fertig!
und wieder etwas Mathe:
Dreisatz
Wie du siehst das Diagramm selber ist dank des Tabellentricks kein
Problem. Fr die Lnge der einzelnen Zellen knnten wir eigentlich auch
die Werte aus vote[0], vote[1] oder vote[2] verwenden. Fr jede
Stimme ein Pixel. Wre das nicht das Einfachste?
Zugegeben, das stimmt. Doch wo bleibt die Attraktivitt? Wenige Pixel
Lngenunterschied machen optisch kaum etwas her. Ein anderes Problem
besteht in der Hchstlnge: Was machst du bei Zehntausenden von Votern?
Dann wren manche Sulen im Zweifelsfalle tausende Pixel breit? So breite
Bildschirme gibt es doch gar nicht!
Alles in allem musst du die Werte aus $vote[0], $vote[1] oder
$vote[2] noch irgendwie umwandeln, damit alles hbsch wohlgeformt
aussieht und auf den Bildschirm passt. Das machen wir gleich: Wir zaubern
und speichern dann die neuen Werte in laenge0, laenge1, laenge2.
269
und wieder etwas Mathe: Dreisatz

Verhltnisgleichung
Hokuspokus, Zauberei: Du gibst die Breite der Sulen einfach im Verhltnis
zueinander an. Du sorgst gleichzeitig dafr, dass eine bestimmte Hchst-
breite nie berschritten werden kann!
Und nun schau bitte zu folgender Passage weiter oben im Skript, dort
hpft das Kaninchen aus dem Zylinder:
// Hchstlnge der Balken angeben
$laenge = 400;

Die Hchst-Balkenlnge gebe ich im Beispiel mit 400 (wie 400 Pixel) vor.
(Du kannst diesen Wert gerne variieren!)
Nun sollen die Anteile der drei Balken gemessen werden, und zwar im
Verhltnis zueinander. Arbeite mit einer Verhltnisgleichung, mit einem
Dreisatz. Setze die Votes fr jede einzelne der drei Optionen einfach zur
Gesamtlnge (hier 400) ins Verhltnis! Ich hoffe, dass dir das Prinzip
noch aus dem Matheunterricht gelufig ist. Htte ich das mit dem Ma-
theunterricht jetzt nicht erwhnen sollen?
Wie auch immer: Auf diese Weise kannst du die Lnge fr den ersten Bal-
ken (Variable $laenge1) folgendermaen berechnen:
// Anteil von Balken 1 (Indexwert 0!)
$laenge0 = $vote[0] * $laenge / $gesamt;

Alles klar? Genau das gleiche Spielchen fhrst du auch fr die beiden ande-
ren Werte durch. Einen Haken hat die Geschichte: Die Ergebnisse sind
meist nicht glatt, es handelt sich um Bruchzahlen. Fr das Attribut width
einer Tabellenzelle bentigst du jedoch Ganzzahlen!
Aus diesem Grund mssen die drei Werte noch auf Ganzzahlen gerundet
werden. Dazu dient die allseits bekannte und beliebte Funktion round().
$laenge0 = round($laenge0);
$laenge1 = round($laenge1);
$laenge2 = round($laenge2);

Damit haben wir das fehlende Puzzlesteinchen eingefgt und du msstest
das Skript nun hoffentlich gut durchschauen!
270
Eine Umfrage mit grafischer Auswertung

Kapitel
11

Die Anteile aller Stimmen werden gleichmig verteilt.
Tipp: Verndere doch einmal die Textdatei result.txt. Tippe statt 0,1,0
einmal 24,15,6! Sofort verndern sich die Sulen!
Nanu, was ist denn da passiert? Du verwendest die Werte 0,0,0 als
Ausgangspunkt in der result.txt? Dann gibt es gleich mehrere dicke
Fehlermeldungen. Kunststck, eine Division durch 0 ist nicht gestattet!
Damit hast du den Pferdefu dieses Skripts entdeckt. Deshalb sollte min-
destens eine der drei Ziffern von Beginn an auf 1 gesetzt werden.
Die Umfrageseite: So funktioniert
das Skript
Nun kommt der schwerste Teil. Programmiere die eigentliche Umfrageseite.
Hier soll der Nutzer seine Stimme abgeben. Dabei wollen wir auerdem
versuchen, Mehrfachvotes mglichst zu unterdrcken.
Der Quelltext der Datei umfrage.php
Zuerst zeige ich dir den Quelltext im berblick. Es handelt sich um die
komplette Seite umfrage.php. Sie besteht aus einem Formular, das den
Inhalt an sich selbst schickt. Auerdem gibt es einen Link zur noch zu er-
stellenden Seite ergebnis.php und natrlich sehr viel PHP-Code, den wir
auf den nchsten Seiten ausfhrlich besprechen mssen. Das Beispiel fin-
dest du auch in der Datei umfrage.php aus dem Ordner kapitel11:
<?php
if (isset($_POST["ergebnis"])) {
setcookie("voted", "ja");
}
?>
271
Die Umfrageseite: So funktioniert das Skript

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="de">
<head>
<title>Unsere Web-Umfrage</title>
<meta http-equiv="content-type" content="text/html;
charset=utf-8">
<link rel="stylesheet" type="text/css" href="phpkid.css">
</head>
<body>
<h2>Wie findest du meine Page?</h2>
<form action="umfrage.php" method="post">
<p>
<input type="radio" name="ergebnis" value="0"> echt
super<br>
<input type="radio" name="ergebnis" value="1"> ziemlich
gut<br>
<input type="radio" name="ergebnis" value="2"> geht so
</p>
<?php
/* Submit nur zeigen, wenn Formular noch nicht
abgeschickt/gevoted */
if (empty($_COOKIE["voted"]) && !isset($_POST["ergebnis"])) {
echo "<input type=\"submit\" value=\"Daten senden\">\n";
} else {
// Formular abgeschickt? Aber bisher noch nicht gevoted?
if (empty($_COOKIE["voted"]) && isset($_POST["ergebnis"])) {
$ergebnis = $_POST["ergebnis"];
// Wert aus Formular berprfen
$muster = "/^[0-2]$/"; // regulrer Ausdruck fr 0-2
if (preg_match($muster, $ergebnis) == 0) {
die("<p>Abbruch wegen Manipulation!</p></form>
</body></html>");
}
// Dateiname in Variable speichern
$datei = "result.txt";
$fp = fopen($datei, "r+");
$vote = fread($fp, filesize($datei));
// String mit Komma als Trenner in Array zerlegen
$vote = explode(",", $vote);
// Welcher Wert wurde im Formular ausgewhlt?
// Diese Position wird um 1 erhht!
$vote[$ergebnis]++;
272
Eine Umfrage mit grafischer Auswertung

Kapitel
11

// String neu zusammensetzen
$vote = $vote[0].",".$vote[1].",".$vote[2];
rewind($fp);
// neuen String in Datei schreiben
fputs($fp,$vote);
fclose($fp);
echo "<p>Danke fr die bermittlung der Daten!</p>\n";
}
}
?>
</form>
<p>
[ <a href="ergebnis.php" target="_blank">
Umfrageergebnisse ansehen</a> ]
</p>
</body>
</html>
Ein paar erste Erklrungen
Ganz zu Beginn der Datei erzeuge ich ein Cookie namens voted. Dieses
wird nach einem Neuladen der Seite zur Verfgung stehen. Das Prinzip ist
dir schon aus dem vorigen Kapitel bekannt.
Besonders wichtig ist auch das Attribut action. Das Formular schickt den
Inhalt praktisch an sich selbst. Aus Sicherheitsgrnden setzen wir aller-
dings nicht die Servervariable $_SERVER['PHP_SELF'] ein, sondern wie-
der direkt den Dateinamen umfrage.php. Denn auch Servervariablen kn-
nen manipuliert werden.
action="umfrage.php"

Auch das Formular selber kennst du schon, und zwar aus Kapitel 1. Es ar-
beitet mit Radiobuttons. Interessant sind die Werte, denn hier gibt es eine
kleine Vernderung im Gegensatz zur Urvariante. Die Felder besitzen statt
1, 2 und 3 einfach die Werte 0, 1 und 2. Das ist Absicht, ich will diese Zah-
len mit den ersten Werten eines numerischen Arrays in Einklang bringen.
Die 0 steht schlielich fr den Array-Eintrag Nummer 1. Dazu gleich mehr.
Auch die Versendemethode des Formulars (method="post") habe im Ver-
gleich zur Urfassung przisiert. Schlielich wollen wir die Werte im Array
$_POST und nicht im Array $_GET empfangen.
273
Schummeln verboten: Mehrfachvotes unterdrcken

Schummeln verboten:
Mehrfachvotes unterdrcken
Das Besondere an unserem Beispiel ist aber der Schummelschutz. Schaue
dir nun die nchsten Zeilen an:
/* Submit nur zeigen, wenn Formular noch nicht
abgeschickt/gevoted */
if (empty($_COOKIE["voted"]) && !isset($_POST["ergebnis"])) {
echo "<input type=\"submit\" value=\"Daten senden\">\n";
} else {

Im Klartext: Der SUBMIT-Button zum Absenden des Formulars soll nur dann
angezeigt werden, wenn folgende Bedingungen zutreffen:
0 empty($_COOKIE["voted"]): Es ist noch kein Cookie namens voted
vorhanden.
0 !isset($_POST["ergebnis"]): Der Formularinhalt wurde noch
nicht abgeschickt, die Variable $_POST["ergebnis"] ist noch nicht
gesetzt.
Das sorgt fr einen gewissen Schutz vor Doppelvotes, denn nach dem Ab-
senden der Ergebnisse ist der SUBMIT-Button erst einmal unsichtbar.
So viel schon vorweg: Einen absolute Schummelschutz bei Web-
Umfragen kann und wird es nie geben! Welche Tricks du dir auch immer
ausdenkst: Der Benutzer kann alles umgehen: Sie oder er braucht ja nur
mit einem anderen Browser vorbeizusurfen, Cookies auszuschalten, von
einem anderen Computer noch einmal zu voten usw. usf. Erst wenn sich
jeder mit Benutzernamen und Passwort bei dir genau identifizieren kann,
ist eine halbwegs zuverlssige Abstimmung mglich. Doch wer voted
dann noch, wenn es solchen Aufwand macht? Lassen wir uns von diesen
Schummelmglichkeiten nicht entmutigen. Spa soll es machen. Und
solange niemand versucht, mit diesem Skript die Bundeskanzlerin zu
whlen, ist alles in Ordnung.
(Im Kapitel 12 erfhrst du, wie du eine Reload-Sperre erzeugst. Im bungs-
teil von Kapitel 12 auf Seite 293 baust du diese Reload-Sperre dann auch
zustzlich in das Umfrageskript ein).
274
Eine Umfrage mit grafischer Auswertung

Kapitel
11
Der else-Zweig
Unser Schummelschutz wird auch im else-Zweig verwendet:
} else {
// Formular abgeschickt? Aber bisher noch nicht gevoted?
if (empty($_COOKIE["voted"]) && isset($_POST["ergebnis"])) {

Das Eintragen der Daten soll nur dann geschehen, wenn folgende Bedin-
gungen zutreffen:
0 empty($_COOKIE["voted"]): Es ist noch kein Cookie namens voted
vorhanden. Diese Bedingung verndert sich nicht.
0 isset($_POST["ergebnis"]): Der Formularinhalt wurde schon ab-
geschickt und die Variable $_POST["ergebnis"] ist also gesetzt. Das
ist der wichtige Unterschied zur vorherigen if-Abfrage!
Unser Cookie schtzt z. B. vor einem Doppelvote bei Druck auf RELOAD. Au-
erdem soll nur dann ein Eintrag in die Datei result.txt erfolgen, wenn
der Voter berhaupt eine Auswahl getroffen hat.

Nach erfolgreicher Stimmenabgabe wird der SUBMIT-Button ausgeblendet.
und wieder entsteht ein Array
Schauen wir uns den eigentlichen Akt des Eintragens an. Die Befehle dafr
stecken in folgenden Zeilen:
$ergebnis = $_POST["ergebnis"];
// Wert aus Formular berprfen
$muster = "/^[0-2]$/"; // regulrer Ausdruck fr 0-2
if (preg_match($muster, $ergebnis) == 0) {
die("<p>Abbruch wegen Manipulation!</p></form>
</body></html>");
}
275
und wieder entsteht ein Array

// Dateiname in Variable speichern
$datei = "result.txt";
$fp = fopen($datei, "r+");
$vote = fread($fp, filesize($datei));
// String mit Komma als Trenner in Array zerlegen
$vote = explode(",", $vote);
// Welcher Wert wurde im Formular ausgewhlt?
// Diese Position wird um 1 erhht!
$vote[$ergebnis]++;
// String neu zusammensetzen
$vote = $vote[0].",".$vote[1].",".$vote[2];
rewind($fp);
// neuen String in Datei schreiben
fputs($fp,$vote);
fclose($fp);
echo "<p>Danke fr die bermittlung der Daten!</p>\n";

Mit dem vorhandenen Wissen kannst du dir die Wirkungsweise eigentlich
schon erklren. Es ist praktisch genau so wie in den ersten drei PHP-Zeilen
der ergebnis.php.
Test mit regulrem Ausdruck
Doch was ist das fr eine komische Konstruktion unterhalb des Kommen-
tars // Wert aus Formular berprfen? Das ist eine reine Sicher-
heitsmanahme! Ich berprfe per regulrem Ausdruck, ob die Formu-
larwerte fr das Ergebnis genau zwischen 0 und 2 liegen. Wenn das
nicht der Fall ist, wurde das Formular mit groer Wahrscheinlichkeit ma-
nipuliert. In diesem Fall sorgt das Sprachkonstrukt die() dafr, dass das
Skript an dieser Stelle stirbt. Im Beispiel gebe ich zustzlich innerhalb
der runden Klammern einen in Gnsefchen notierten Abbruchtext aus
und beende die HTML-Datei mit den entsprechenden Abschlusstags.
Sind dir die regulren Ausdrcke noch vertraut, diese praktischen Muster-
schablonen? Wenn nicht, studiere noch einmal den Abschnitt ab Sei-
te 222. In diesem Fall haben wir es mit dem Gebilde [0-2] zu tun. Diese
Zeichenfolge steht als Platzhalter fr die Zahlen 0, 1 und 2. Andere Werte
werden auf diese Weise zuverlssig abgeblockt!
Zugegeben das Skript wrde auch ohne diesen Sicherheitscheck arbeiten.
Trotzdem solltest du es dir zur Gewohnheit machen: berprfe mglichst
alle Werte, die aus Formularfeldern bernommen werden und die du im
Skript weiterverarbeitest. Denn Hacker knnten deine Formulare manipulie-
276
Eine Umfrage mit grafischer Auswertung

Kapitel
11
ren, deren Rckgabewerte verndern und so im Zweifelsfalle Schaden an-
richten. (Auch wenn der Schaden in diesem Fall noch nicht dramatisch ist.)
Du merkst: Sicherheit fngt schon bei kleinen Beispielen an!
So arbeitet der Eintrageteil des Skripts
Zuerst wird die Datei result.txt wieder geffnet, und zwar diesmal im
Lese- und Schreibmodus (r+). Der String aus der result.txt wird wieder
in der Variablen $vote gespeichert. Auch diesmal bentigst du die Funkti-
on explode(), damit der String am Komma zerlegt und in ein Array um-
gewandelt werden kann.
Zur Erinnerung: Der erste Wert ist nun ber vote[0] abrufbar!
Ich erinnere dich noch einmal daran: Das Formular gibt eine Variable
namens $_POST["ergebnis"] zurck. Als Werte stehen die drei Ziffern
0, 1 oder 2 zur Verfgung; je nachdem, welche Option der Surfer ausge-
whlt hat. Ich wiederhole: 0, 1 oder 2. Hier hat der Autor ausnahmsweise
mal eine gewisse Einfachheit gepaart mit Genialitt an den Tag gelegt.
Denn auch der 1. Wert eines Arrays beginnt ganz zufllig mit 0.
Nun kommt die Zeile, in der ich zu einem kleinen Kunstkniff gegriffen
habe:
$vote[$ergebnis]++;

Diese Zeile erhht exakt den Wert um 1, der mit der Eingabe des Benutzers
korrespondiert. Ein Beispiel: Wenn der Benutzer die dritte Option auswhlt,
ist in $_POST["ergebnis"] und damit auch in $ergebnis eine 2 gespei-
chert. Und $vote[2] bezieht sich schlielich auf die letzte Zahl unserer
result.txt. Somit wird auch nur die letzte Zahl erhht.
Die restlichen Zeilen sind dann nur noch Pillepalle. Der String wird unter
Bercksichtigung des erhhten Wertes neu zusammengesetzt
$vote = $vote[0].",".$vote[1].",".$vote[2];

und mit Hilfe der schon bekannten Funktionen rewind() und fputs()
wieder zurck in die Datei geschrieben.
Mit fclose() beenden wir das Spielchen, geben danach einen Dankestext
aus und die neue Stimme zhlt. Alles klar wie Klobrhe?
277
Schlussbemerkung

Schlussbemerkung
Nicht schlecht, Herr Specht! Du weit nun, wie du eine Web-Umfrage pro-
grammierst. Nutze kommaseparierte Textdateien fr die Sicherung mehre-
rer Daten. Bei dieser Gelegenheit hast du die Cookie-Technologie und das
Speichern in bzw. Lesen aus Dateien wiederholt.
Gerne kannst du das Skript erweitern und auf deine Bedrfnisse anpassen.
Zusammenfassung
0 Du kennst die Technik, Daten in kommaseparierten Textdateien zu si-
chern. Die einzelnen Werte werden einfach durch ein Komma voneinan-
der getrennt.
0 Du kennst die Funktion explode(), die einen String anhand eines
Trennzeichens zerlegt und in ein Array umwandelt:
explode("Trennzeichen","Zu_trennender_String")
0 Du weit, dass du mit der Funktion filesize() die Gre einer Datei
ermittelst. Die Syntax lautet ganz einfach filesize("Dateiname").
0 Du kennst das Sprachkonstrukt die() zum Abbruch von Skripten.
0 Du hast die Cookie-Technologie und das Lesen aus und Schreiben in
Dateien wiederholt.
Ein paar Fragen
1. Mit welcher Funktion ermittelst du die Gre einer Datei?
2. Ist es mglich, ohne Benutzeranmeldung Umfragen zu erstellen, die zu
100% schummelsicher sind?
3. Welche Funktion zerteilt einen String anhand eines Trennzeichens?
4. Bei welchem Wert beginnt die Zhlung in numerischen Arrays?
5. Schaue in die Datei umfrage.php. Es geht um die beiden if-Abfragen
zur Ermittlung, ob die Variable $_POST["ergebnis"] vorhanden ist
oder nicht. Warum habe ich die Funktion isset() verwendet? Warum
geht die Funktion empty() in diesem Fall nicht? (Tipp: Probiere es ruhig
einmal aus, ich mache dich besonders auf die erste Option mit dem In-
dexwert 0 aufmerksam!)
278
Eine Umfrage mit grafischer Auswertung

Kapitel
11 und ein paar Aufgaben
1. Bei nicht abgegebenen Stimmen gibt es eine Fehlermeldung in der Da-
tei ergebnis.php. Unterdrcke die Fehlermeldung. Solange noch keine
Stimmen abgegeben wurden, soll statt des Diagramms die Meldung er-
scheinen: Bisher wurden noch keine Stimmen abgegeben! Tipp: Nutze
eine weit umspannende if-Abfrage in Zusammenarbeit mit der Variab-
len $gesamt!

2. Baue das Umfrageskript aus ergebnis.php weiter um! Bisher werden
hinter den einzelnen Sulen nur die absoluten Werte angezeigt. Sorge
dafr, dass die Verteilung auerdem in Prozent eingeblendet wird, wie
in der Abbildung gezeigt. Tipp: Arbeite mit einer zustzlichen Verhlt-
nisgleichung. Ermittle die Prozentwerte und runde diese wieder, so dass
keine Nachkommastellen angezeigt werden. Vergiss nicht das Prozent-
zeichen.

3. Versuche einmal, das Formular aus der Datei umfrage.php zu manipu-
lieren. Vergib fr einen der Radiobuttons einen ungltigen Wert, schrei-
be statt value="0" einfach value="3" oder gar value="". Und,
zhlt die Umfrage noch?
4. Erstelle eine Umfrage zur Beliebtheit deines Klassenlehrers. (Zu dieser
Aufgabe findest du ausnahmsweise keine Lsung auf der CD, ich kenne
ja deinen Klassenlehrer nicht.)

Erklrungstext statt
Fehlermeldung: if-
else-Struktur im
Einsatz.
Auch das gelingt mit
einer Verhltnisglei-
chung: Angabe der pro-
zentualen Verteilung.
279



12
Das eigene Gstebuch
Natrlich! Jeder mchte ein Gstebuch auf seiner Homepage haben. Du
bist da keine Ausnahme. Und da du inzwischen weit, wie du mit Dateien
umgehst, steht unserem Beispiel nichts mehr im Wege.
Du lernst in diesem Kapitel:
$ wie du Formulardaten in eine Textdatei schreibst
$ wie du eine gesamte Textdatei auf einen Schlag ausliest
$ wie du Hacking-Versuche und Doppeleingaben verhinderst

Wir fangen wie immer ganz bescheiden an und steigern uns im Laufe
des Kapitels. Trotzdem bleibt das Beispiel einfach und durchschaubar.
Falls du spter in die Gstebuch-Oberliga aufsteigen mchtest, lege ich
dir das Kapitel 14 ans Herz. Dort geht es um eine echte Datenbankl-
sung, die natrlich noch mehr Mglichkeiten bietet.
280
Das eigene Gstebuch

Kapitel
12 (Zu) simpel gestrickt: Version 1
Das Motto lautet: Einfach aber attraktiv! Unser Gstebuch sichert Kom-
mentar, Namen und E-Mail-Adresse. Auf Knopfdruck werden diese Daten in
einer Textdatei gespeichert und sofort auf der Seite angezeigt.

Lege zuerst also wieder eine Textdatei an. Im Beispiel heit sie
0 comment.txt
Vergiss nicht, den Schreibschutz aufzuheben, wenn du diese Datei auf den
Server ldst. Das Stichwort heit chmod 666, siehe auch Seite 254.
Das Beispiel im berblick
Und nun wirfst du zuerst einen Blick auf den Quelltext. Ich zeige dir wieder
den Bereich zwischen den Tags <body></body>. Das meiste davon kommt
dir bestimmt schon bekannt vor!
Den Beispielcode findest du auf der CD im Ordner kapitel12/version1.

Das eigene Gste-
buch: Der Kommen-
tar wird in ein For-
mular eingetragen.
281
(Zu) simpel gestrickt: Version 1

<div style="width: 600px">
<h1>Einfaches Gstebuch</h1>
<form action="guestbook.php" method="post">
Dein Kommentar:<br>
<textarea cols="55" rows="4" name="comment">
</textarea><br>
Dein Name:<br>
<input type="text" name="name"><br>
Deine E-Mail-Adresse:<br>
<input type="text" name="Email">
<input type="submit" value="Eintragen"></form>
<h3>Bisherige Meinungen:</h3>
<?php
// Dateiname in Variable speichern
$datei = "comment.txt";
// Variable Kommentar gesetzt? Name und E-Mail nicht leer?
if (!empty($_POST["comment"]) && !empty($_POST["name"])
&& !empty($_POST["Email"])) {
// HTML-Zeichen maskieren, Slashes weg
$comment = htmlspecialchars(stripslashes($_POST["comment"]));
// Umbrche erhalten
$comment = nl2br($comment);
$name = htmlspecialchars(stripslashes($_POST["name"]));
$Email = htmlspecialchars(stripslashes($_POST["Email"]));
// Datei wird im Anhnge-Modus geffnet
$fp = fopen($datei, "a+");
// E-Mail-Link entsteht
$Email = "<a href='mailto:$Email'>$Email</a>";
// Datum ermitteln und formatieren
$datum = date("j.n.Y");
// Meinung zusammensetzen
$meinung="<p><b>$name</b> ($Email) schrieb am " .
"<i>$datum</i>:<br>$comment</p>\n";
// neue Meinung unten an Datei anhngen:
fputs($fp, $meinung);
// Datei schlieen
fclose($fp);
}
readfile($datei);
?>
</div>
282
Das eigene Gstebuch

Kapitel
12 Schaue zur ersten und letzten Zeile: Der Autor benutzt das Tag-Paar
<div style="width: 600px"></div>. Damit sieht er eine feste
Breite von 600 Pixeln vor. Das sorgt dafr, dass sich der Text
auch bei breiten Bildschirmen nicht unendlich in die Lnge
zieht und besser lesbar bleibt.
Der Quelltext kurz erklrt
Muss ich den Quelltext gro erlutern? Das meiste erschliet sich be-
stimmt beim Durchlesen. Ein Formular schickt die Felder comment, name
und Email an sich selber ab. Danach lege ich im PHP-Teil den Dateinamen
in einer Variablen fest:
$datei = "comment.txt";

Eine if-Abfrage prft, ob die Formularfelder nicht etwa leer gelassen wur-
den, denn nur dann soll der Kommentar in die Textdatei eingetragen wer-
den. Aus Bequemlichkeit wandle ich danach die klobigen $_POST-Variablen
wie $_POST["comment"] usw. in schlankere Formen um. Hier das Beispiel
fr den Kommentar.
$comment = htmlspecialchars(stripslashes($_POST["comment"]));

Nun ffne ich und das ist die Besonderheit unsere Textdatei im Anhn-
ge-Modus.
$fp = fopen($datei, "a+");

Bei diesem Modus wird der Dateizeiger am Ende der Datei platziert. Im
Klartext: Das Skript schreibt den neuen Gstebucheintrag einfach ganz
unten in die Datei! Auch die nchsten Zeilen bergen kein Geheimnis, zudem
habe ich sie noch gut kommentiert: Ein E-Mail-Link fr die Textausgabe
entsteht und das Datum wird ermittelt und formatiert. Schlielich soll dem
Eintrag auch ein genaues Datum zugeordnet werden.
// E-Mail-Link entsteht
$Email = "<a href='mailto:$Email'>$Email</a>";
// Datum ermitteln und formatieren
$datum = date("j.n.Y");
283
Hacking-Versuche unterbinden

Hacking-Versuche unterbinden
Erinnerst du dich noch an Kapitel 8? Dort habe ich dir gezeigt, wie man mit
der Funktion htmlspecialchars() die HTML-Zeichen entschrft und mit
stripslashes() eventuelle Maskier-Schrgstriche entfernt. Das habe ich
nicht nur bei $comment, sondern auch fr $name und $Email gemacht.
$name = htmlspecialchars(stripslashes($_POST["name"]));
$Email = htmlspecialchars(stripslashes($_POST["Email"]));

Warum ist gerade die Funktion htmlspecialchars() so verdammt
wichtig fr das Skript? Sie verhindert, dass dir irgendein Scherzkeks
HTML-Tags im Klartext in dein Skript schummelt. Sonst knnten fremde
Links, fremder Quelltext und sogar gefhrliche PHP- oder JavaScripte
einfach so mir nichts dir nichts in dein Gstebuch eingetragen werden.
Und das wre fatal! Auf diese Weise werden diese Zeichen in ihre Entit-
ten umgewandelt (< wird z. B. zu &lt;) und die Gefahr ist gebannt!
Also: Gib den Hackern und Skript-Kids keine Chance!
Die Funktionen nl2br() und
readfile()
Nach so vielen bekannten Funktionen und Anweisungen gibt es auch zwei
Novitten.
Zeilenumbruch erhalten: nl2br()
Die erste Besonderheit steckt in der Zeile:
$comment = nl2br($comment);

Hier kommt die neue Funktion nl2br() zum Einsatz. Lies diese Funktion
als new line 2 (2 wie to) break. Diese Funktion sorgt dafr, dass nach Zei-
lenumbrchen im Quelltext zustzlich das Tag <br /> (bzw. <br> je nach
Alter der PHP-Version) eingefgt wird. Als Argument bergibst du einfach
den umzuwandelnden String und hltst das neue Ergebnis in der gleichen
Variablen fest.
284
Das eigene Gstebuch

Kapitel
12
Wozu ist das gut? Auf diese Weise wird jeder Zeilenumbruch auch auf dei-
ner Gstebuchseite sichtbar! Denn ein normaler Break wrde ansonsten nur
im Quelltext erscheinen. Im Klartext: Wenn der Gstebuchschreiber auf
[Enter] drckt, sieht man auch ein Enter.

Jeder Druck auf [Enter] wird im Quelltext zustzlich durch <br /> gekennzeichnet. Nicht
wundern, PHP verwendet schon die XHTML-Syntax. Eigentlich wre auch <br> okay.
Die weiteren Zeilen sind wieder bekannt und vertraut. Du setzt den Gste-
bucheintrag zusammen und formatierst ihn ein wenig. Dann hngst du ihn
mit fputs() ans Ende der Datei und schliet den ganzen Laden (bzw. die
Datei) zu.
Datei auslesen mit readfile()
Doch wie und wo werden die Daten letztendlich angezeigt? Schlielich
wollen auch andere die Gstebucheintrge lesen knnen? Das gelingt mit
der genial einfachen Funktion readfile(). Sie liest eine Datei aus uns
stellt sie dar. Die entsprechende Zeile sieht so aus:
readfile($datei);

Ganz bewusst habe ich die Funktion unterhalb des if-Blocks notiert.
Schlielich soll der Inhalt des Gstebuchs in jedem Fall angezeigt werden
und nicht nur, wenn man selber einen Eintrag vornimmt.
Schon besser: Gstebuch Version 2
Probiere das Gstebuch aus. Zufrieden? Ich bin es nicht, denn die neuesten
Eintrge werden zuunterst angezeigt. Es sollte eigentlich umgedreht sein!
Offenbar war die Sache mit dem Anhnge-Modus wohl doch nicht so eine
geniale Idee.
285
Schon besser: Gstebuch Version 2

Neueste Eintrge zuoberst anzeigen
Hast du eine Idee, wie du die neuesten Eintrge stets nach oben be-
kommst? Mit dem vorhandenen Wissen knntest du es schaffen. ndere
einfach etwas im Modus beim ffnen der Datei, fge ein paar Zeilen hinzu
und fertig.

Hat nicht geklappt? Hier mein Vorschlag. Ich zeige dir lediglich den PHP-
Teil. Alle vernderten bzw. ergnzten Passagen habe ich hervorgehoben.
<?php
// Dateiname in Variable speichern
$datei = "comment.txt";
// Variable Kommentar gesetzt? Name und E-Mail nicht leer?
if (!empty($_POST["comment"]) && !empty($_POST["name"])
&& !empty($_POST["Email"])) {
// HTML-Zeichen maskieren, Slashes weg
$comment = htmlspecialchars(stripslashes($_POST["comment"]));
// Umbrche erhalten
$comment = nl2br($comment);
$name = htmlspecialchars(stripslashes($_POST["name"]));
$Email = htmlspecialchars(stripslashes($_POST["Email"]));
// Datei wird im Lese- und Schreib-Modus geffnet
$fp = fopen($datei, "r+");
// alte Daten herauslesen und in $old sichern
$old = fread($fp, filesize($datei));
// E-Mail-Link entsteht
$Email = "<a href='mailto:$Email'>$Email</a>";
// Datum ermitteln und formatieren
$datum = date("j.n.Y");
// Meinung zusammensetzen
Schon besser: Jetzt
stehen die neuesten
Eintrge zuoberst.
286
Das eigene Gstebuch

Kapitel
12

$meinung="<p><b>$name</b> ($Email) schrieb am " .
"<i>$datum</i>:<br>$comment</p>\n";
// Dateizeiger marschiert an den Anfang
rewind($fp);
// neue Meinung vor alte in Datei schreiben
fputs($fp, "$meinung \n $old");
// Datei schlieen
fclose($fp);
}
readfile($datei);
?>

Und, begeistert? Die Lsung ist im Prinzip wirklich simpel. Du sicherst den
alten Inhalt aus comment.txt in der Variablen $old und platzierst den
neuen Eintrag einfach vor dem alten. Da wir den Dateimodus auf r+ gen-
dert haben, musst du den Dateizeiger natrlich vorher mit rewind($fp)
zurcksetzen.
Ich habe mir fr dieses erweiterte Gstebuchprojekt einen neuen Ordner
angelegt. Schlielich kannst du auch die alte, andersherum sortierte Datei
comment.txt nicht weiter verwenden. Mein Beispiel findest du daher
unter kapitel12/version2.
So vermeidest du Doppeleintrge
Schn, schn. Bisher macht das Gstebuch durchaus etwas her. Oder gibt
es da noch einen Haken? Es gibt mehrere Haken. Beginnen wir bei der Sa-
che mit den Doppeleintrgen. Da braucht blo mal ein bereifriger Gste-
buchschreiber auf den RELOAD-Button zu drcken: Zack, schon steht der
Eintrag ein zweites Mal im Gstebuch.

Nervt: Dieser unqualifi-
zierte Eintrag steht
gleich doppelt im
Gstebuch.
287
So vermeidest du Doppeleintrge

Aber auch dagegen ist ein Kraut gewachsen. Wage dich an die dritte Versi-
on des Gstebuchs. Falls du stecken bleibst: Mein Beispiel findest du unter
kapitel12/version3.
Die Funktion time()
Schaue zuerst nach oben in den Formularteil. Fge ein neues Feld in dein
Formular ein, und zwar ein verstecktes Formularfeld:
<input type="hidden" name="uw" value="<?php echo time(); ?>">

Die Position spielt keine Rolle, da das Feld versteckt wird. Dafr sorgt die
Angabe type="hidden". Hauptsache, du setzt das Feld innerhalb des
Tagpaars <form></form> ein. (Ich habe es unter dem Feld fr die E-Mail-
Adresse platziert.)
Was passiert in diesem Geheimfeld? Der Trick steckt hinter diesem Attri-
but-Werte-Paar:
value="<?php echo time(); ?>"
Hier wird praktisch ein Zeitstempel erzeugt und in die Datei geschrieben.
Erinnerst du dich an das Cookie-Kapitel 9? Dort hattest du die Funktion
time() schon kennengelernt. Sie macht nichts weiter, als die Zahl der
Sekunden seit dem 1.1.1970, 0:00 Uhr zu ermitteln, also die Sekunden,
die seit Beginn der Unix-Epoche vergangen sind. Da ich ein echo voran-
gestellt habe, wird bei jedem Aufruf des Formulars eine andere Zahl hin-
ter das Attribut value geschrieben. Diese Zahl kann spter bequem ber
$_POST["uw"] aufgefangen werden.
Vorgehensweise planen
Ahnst du schon, was ich vorhabe? Richtig! Diese Sekundenzahl spielt eine
Schlsselrolle bei unserem Reload-Killer. Jeder wirklich neue Gstebuchein-
trag erzeugt auch einen neuen Wert. Schlielich heit es: Time goes die
Zeit luft.
Doch was passiert bei einem Reload? Da erscheint der gleiche Gste-
bucheintrag noch einmal. Er stammt quasi aus dem Browser-Cache, aus
dem unsichtbaren Zwischenspeicher. Zwischengespeichert wurde dabei
auch die Sekundenzahl, und zwar die alte!
288
Das eigene Gstebuch

Kapitel
12
>
Zum Festhalten der Sekundenzahl bereitest du nun eine Textdatei vor
namens unique.txt!
>
Lege sie in den gleichen Ordner. Das wird die Speicherdatei fr unsere
Sekundenzahl.
>
Denke nach dem Hochladen ggf. wieder an den chmod 666.
Wir mssen nun bei jedem Gstebucheintrag lediglich den entsprechenden
Sekundenstempel festhalten. Beim nchsten Eintrag muss die neue Zahl
hher sein als die alte. Falls beide Werte jedoch gleich sind, handelt es sich
um eine Doppelung aus dem Browsercache.
Stelle fest, was Sache ist! Und zwar mit Hilfe der handgestrickten Funktion
isDouble(). Du notierst sie direkt hinter dem einleitenden <?php-
Abschnitt. Und zwar noch ber den Zeilen:
// Dateiname in Variable speichern
$datei = "comment.txt";
Die Funktion isDouble()
Alles klar? Dann zeige ich dir nun diese groartige Funktion:
function isDouble()
{
$gleichheit = false;
if (isset($_POST["uw"])) {
$datei = "unique.txt";
$fp = fopen($datei, "r+");
$aw = fgets($fp, 30);
if ($aw == $_POST["uw"]) {
$gleichheit = true;
}
rewind($fp);
fputs($fp, $_POST["uw"]);
fclose($fp);
}
return $gleichheit;
}

Beachte wieder, dass bei Funktionen die ffnende geschweifte Klammer auf
einer eigenen Zeile stehen sollte ganz im Gegensatz zu if-else-Kon-
trollstrukturen oder Schleifen.

289
So vermeidest du Doppeleintrge

Dir ist das Prinzip der Funktion schon entfallen? Dann schlage schnell im
Kapitel 6 nach. Dort hatte ich dich mit der Wirkungsweise vertraut ge-
macht. Die Funktion fhrt im Beispiel einen Test durch und gibt je nach
Sachstand den entsprechenden Wahrheitswert zurck. Ich habe deshalb
eine Funktion erstellt, weil man den Code so bequemer wiederverwerten
kann.
Unterhalb der Funktion ergnzt du bitte noch folgende Zeile:
$double = isDouble();

Im Klartext: Du speicherst den Rckgabewert der Funktion in einer Variab-
len namens $double. Denn mit dieser Variablen wollen wir arbeiten.
Bei der Funktion isDouble() kommt die sogenannte Kamelschreib-
weise zum Einsatz. Als Hcker gilt der groe Buchstabe D. Diese gut
lesbare Schreibweise mit einem oder mehreren Grobuchstaben ist bei
Profis beliebt. Sie nutzen sie gern fr Funktionsnamen und Variablen.
Die Funktion im berblick
Nehmen wir die Funktion isDouble() auseinander! Was passiert da ge-
nau? Zuerst gehe ich davon aus, dass eine Ungleichheit zwischen der in der
Datei unique.txt gespeicherten und der aus dem Formular stammenden
Sekundenzahl besteht. Ich initialisiere die Variable $gleichheit mit dem
Wert false.
Wurde das Formular abgeschickt? Existiert die Variable $_POST["uw"]?
Dann ffne ich die Datei unique.txt zum Schreiben und Lesen und lese
den Inhalt aus. Der Inhalt wird in der Variablen $aw gesichert. Nun verglei-
che ich den Wert aus $aw mit dem, was das Formular aktuell abgeschickt
hat.
Gibt es hier eine Gleichheit? Dann wird die Variable $gleichheit auf
true geschaltet. Unterhalb des if-Bereichs wird der neue Wert in der
unique.txt gespeichert und die Datei wird geschlossen.
Die Funktion gibt nun den entsprechenden Wahrheitswert aus
$gleichheit zurck. Entscheidend ist nun die schon gezeigte Zeile unter-
halb der Funktion. Hier wird die Funktion schlielich aufgerufen:
$double = isDouble();

290
Das eigene Gstebuch

Kapitel
12
Die Variable $double beherbergt also je nach Sachstand den Wert false
(keine Doppeleingabe) oder true (Doppeleingabe).
Warum verwende ich innerhalb der Funktion eigentlich so ungeniert die
Variablen $fp und $datei? Ist es nicht problematisch, da diese Variab-
len auch im zweiten Teil des Skripts vorkommen? Nicht im Geringsten!
Erstens werden die Variablen jedes Mal neu initialisiert, also mit einem
neuen Wert gefttert. Schon von daher kann es keine Probleme geben.
Zum anderen berleben die in der Funktion initialisierten Variablen so-
wieso nur innerhalb dieser Funktion!
Bedingung erweitern
Zurck zum Beispiel. Die Funktion hat ermittelt, ob es sich um eine Doppel-
eingabe handelt oder nicht. Der entsprechende Wahrheitswert liegt in der
Variablen $double bereit. Und nun? Nun musst nun nichts weiter tun, als
die existierende Bedingung
if (!empty($_POST["comment"]) && !empty($_POST["name"])
&& !empty($_POST["Email"])) {

wie folgt zu erweitern:
if (!empty($_POST["comment"]) && !empty($_POST["name"])
&& !empty($_POST["Email"]) && !$double) {

Im Klartext: Es darf keine Doppeleingabe vorliegen, sonst wird der Gste-
bucheintrag kaltbltig vom Skript storniert!
Gstebuch sicherer machen
Aber ist das Gstebuch in dieser Fassung wirklich schon sicher? Leider nein!
Du solltest es so mglichst nicht im Web verffentlichen.
Die Gefahr durch Spammer
Gstebcher sind inzwischen zu einem beliebten Objekt von Spammern
geworden, also von den Zeitgenossen, die berall unaufgefordert ihre Wer-
bung eintragen und zweifelhafte Links hinterlassen. Hufig erfolgt dieses
Spamming sogar automatisch durch ein Skript.
291
Schlussbemerkung

Ein weiteres Problem stellt das Eingeben der E-Mail-Adresse dar. Auch
E-Mail-Adressen werden lngst automatisch von Programmen ausgelesen,
von Betrgern gesammelt und zum Versand von Spam verwendet.
Lsungen fr diese Probleme
Das erste Problem wird hufig durch ein sogenanntes CAPTCHA gelst,
durch einen Test, ob es sich wirklich um einen Menschen oder eine Ma-
schine handelt. Dabei kommt oft ein verschleiertes Bildchen zum Einsatz.
Der Eintragende muss eine Zeichenfolge auslesen und diese zur Sicherheit
in ein Zusatzfeld eintragen. Der Haken: Das Erzeugen und Einbinden derar-
tiger, sich stndig verndernder Bildchen ist kompliziert fr
dieses PHP-Einstiegsbuch berfordert es uns bei weitem. (Aber
auch eine Rechenaufgabe oder ein anderer Test sind denkbar.)
Typisches CAPTCHA bei professionellen Gstebchern. Bild: Wikipedia.de.
Und inzwischen gibt es auch schon die ersten Programme, mit denen sich
selbst ausgefuchste Bild-CAPTCHAs knacken lassen.
Ich schlage eine sehr simple, aber wirkungsvolle Methode vor: Erlaube nur
deinen Freunden und Bekannten, sich im Gstebuch einzutragen. Gib ihnen
vorab ein spezielles Passwort. Und damit du deine Freunde erkennst,
schtzt du das Gstebuch dann einfach mit eben diesem Passwort.
Auerdem solltest du das Feld fr die E-Mail-Adresse weglassen oder durch
ein Feld fr die Homepage ersetzen gerne fr die Lieblings-Homepage.
(Es kann ja sein, dass der Eintragende noch keine eigene Homepage hat.)
Fr beide Ideen halte ich im bungsteil die passenden Aufgaben bereit!
Schlussbemerkung
Du hast dein eigenes, einfaches Gstebuch erstellt und es funktioniert.
Glckwunsch! Dabei konntest du viele der Techniken aus den vorigen Kapi-
teln festigen. Als Hhepunkt des Beispiels kam eine Funktion zum Einsatz.
Du weit aber auch, dass du das Gstebuch fr den Einsatz im Web noch
etwas sicherer machen musst! Und damit fangen wir gleich an.
292
Das eigene Gstebuch

Kapitel
12 Zusammenfassung
0 Du kennst die Funktion nl2br(). Diese Funktion sorgt dafr, dass nach
Zeilenumbrchen im Quelltext zustzlich das Tag <br /> eingefgt
wird.
0 Du kennst die Funktion readfile(), mir der du den Inhalt einer Datei
auslesen kannst.
0 Du weit, wie du mit der selbsterstellten Funktion isDouble() Dop-
peleintrge verhindern kannst. Sichere einen Zeitstempel in einer Extra-
datei und prfe bei jedem Eintrag, ob der neue und alte Zeitstempel
Unterschiede aufweisen.
Ein paar Fragen
1. Wofr steht die Funktion nl2br(), was bedeutet die Zeichenfolge
nl2br?
2. Wozu dient die Funktion time()?
3. Welchen Buchstaben setzt du in fopen() ein, wenn du eine Datei im
Anhnge-Modus zum Lesen und Schreiben ffnen mchtest?
4. Sind die in einer Funktion definierten Variablen auch auerhalb der
Funktion sichtbar?
und ein paar Aufgaben
1. Zuerst die leichteste Aufgabe zum Gstebuch. Ersetze das Feld zur Ab-
frage der E-Mail-Adresse durch eines zum Erfassen der Homepage. Der
Name des Feldes soll www lauten. Passe auch den Link bei der Anzeige
an. Es darf kein mailto-Link mehr sein, sondern ein normaler.
2. Fge ein zustzliches Feld zur Abfrage des Kennwortes ein. Das Kenn-
wort soll t6rzXi2P heien. Frage das Kennwort ebenfalls mit ab.
3. Sorge dafr, dass der Inhalt der Felder vom Passwortfeld abgesehen
nach dem Absenden nicht verloren geht! Tipp: Erinnere dich an das
Feedbackformular in Kapitel 8 dort haben wir das schon gemacht! (Es
gengt mir, wenn die Inhalte in den Feldern stehen bleiben. Du musst
die Werte nicht unbedingt nach dem Abschicken lschen.)
293
und ein paar Aufgaben

4. Du hast vergessen, die Datei comment.txt anzulegen? Dann produziert
die Funktion readfile() eine Fehlermeldung. Versuche, diese Fehler-
meldung zu unterdrcken. Tipp: Du bentigst nur ein kleines Zeichen.
5. Baue die Reload-Sperre aus der Funktion isDouble() in die Mei-
nungsumfrage aus dem vorigen Kapitel ein. Einfach zur zustzlichen Si-
cherheit!
6. Prfe, ob du die Reload-Sperre korrekt in die Umfrage eingebaut hast.
Deaktiviere Cookies im Browser. Stimme ab. Gehe zurck mit dem BACK-
Button des Browsers. Stimme noch einmal ab. Diese zweite Stimme darf
nun nicht mehr gezhlt werden!
295



13
Ein Adressbuch fr dein
Team
Keine Angst vor Datenbanken! In diesem Kapitel wagen wir uns von der
praktischen Seite an das Thema heran. Wie wre es mit einem Adressbuch
fr dein Team? Dabei ist es ganz egal, ob es sich bei diesem Team um
deine Klassenkameraden, die Vereinsmitglieder oder die Kunden eines Onli-
ne-Shops handelt. Das Schne an der Sache: Dank unserer fabelhaften
XAMPP-Installation bist du schon im Besitz des Datenbankprogramms
MySQL. Auch die fr uns unentbehrliche grafische Oberflche phpMyAdmin
wurde bei dir automatisch installiert. Auf diese Weise ist das Anlegen und
Bearbeiten von Datenbanken kinderleicht.
Bei dir ist noch nichts Derartiges auf deiner Festplatte installiert? Dann
studiere unbedingt noch einmal das Kapitel 2 zur Installation deines lo-
kalen Webservers!
Du lernst in diesem Kapitel:
$ wie du eine Datenbanktabelle planst und einrichtest
$ wie du mit dem Tool phpMyAdmin arbeitest
$ wie du mit SQL und MySQL arbeitest
$ wie du Daten eingibst und ausliest
$ wie du SQL-Befehle in eine PHP-Datei einfgst
296
Ein Adressbuch fr dein Team

Kapitel
13 Planung ist die halbe Miete
Was ist eine Datenbank? Eine Bank fr Daten! Also eine Art Datenspeicher!
Eine Datenbank besteht aus Datenbanktabellen. Herrjeh, Tabellen? Gleich
mehrere auf einmal? Nicht unbedingt! Im einfachsten Fall besteht die Da-
tenbank nur aus einer einzigen Datenbanktabelle. Und da das Kapitel ein-
fach wird, fangen wir mit dieser einen Tabelle an. Und zwar mit unserer
Adressliste. Doch bevor es losgeht, planst du zuerst die Struktur!
Die Struktur der Datenbank planen
Planen? Das klingt ja furchtbar. Es stimmt Datenbanken sind ein Graus
fr alle diejenigen, die das geordnete Chaos lieben. Trotzdem gilt: Fr
Datenbankdesign brauchst du eine klare Struktur. Da kommst du nicht
drum herum.
Vor dem Aufbau einer Datenbanktabelle musst du dir eine Datenbank-
Struktur ausdenken. berlege dir, welche Eintrge erforderlich sind. Defi-
niere also die sogenannten Feldnamen. Das nachtrgliche ndern einer
Datenbankstruktur ist nur unter Schwierigkeiten mglich vor allem,
wenn du schon viele Daten eingetragen hast! Datenverlust knnte die
Folge sein.
Hier zeige ich dir, was bei meinen Struktur-berlegungen zum Adressbuch
herausgekommen ist. Dazu habe ich mir die knftige Datenbanktabelle
schon einmal als Tabelle skizziert:
Vorname Name Str PLZ Ort Tel EMail WWW Notizen
Hans Meier Waldweg 7 12345 Neustadt 234567 hans@lexi.de www.lexi.de
Feldnamen und Datenstze
Fr unsere Adressdatei habe ich mir also folgende sinnvolle Feldnamen
ausgedacht: Vorname, Name, Str, PLZ, Ort, Tel, EMail, WWW und Notizen.
Die Feldnamen sind hier selbsterklrend.
Okay! Da sind wir also bei den Fachbegriffen angelangt. Das ist aber gar
nicht schlimm: Die erste Zeile einer Tabelle enthlt die Beschriftung.
Man spricht von den sogenannten Feldnamen. In den brigen Zeilen be-
finden sich die Eintrge, die Datenstze. Jeder Datensatz besteht aus den
einzelnen Datenbankfeldern.
297
Planung ist die halbe Miete

Du planst eine Datenbanktabelle? Denke dir kurze, przise und selbster-
klrende Feldnamen aus. Verzichte auf Umlaute, Leer- und Sonderzei-
chen. Beachte, dass zwischen Gro- und Kleinschreibung unterschieden
wird. Auerdem ist der Bindestrich nicht erlaubt. Das E-Mail-Feld darf
also keinesfalls E-Mail heien, sondern nur EMail, email, eMail usw.
Eine Datenbanktabelle kann brigens hunderte oder sogar tausende von
Datenstzen enthalten. Eigentlich ist die Zahl fast unbegrenzt.
Die Sache mit dem Schlsselfeld
Halt, unsere Planung ist noch nicht ganz vollstndig! Jede gute Datenbank-
tabelle sollte ein sogenanntes Schlsselfeld erhalten. Das ist eine Kennung,
die jeden Datensatz eindeutig identifiziert. Dazu habe ich meine Skizze um
eine zustzliche Spalte am Anfang erweitert. Die Spalte heit id.
id Vorname Name Str PLZ Ort Tel EMail WWW Notizen
1 Hans Meier Waldweg 7 12345 Neustadt 234567 hans@lexi.de www.lexi.de
2 Martina Weber Waldweg 2 12345 Neustadt 234568 martina@lexi.de mag
Kaugummis

Das Schlsselfeld heit also id wie identifier (Identifizierer, eindeutige
Kennung). Solch ein Schlsselfeld ist deshalb wichtig, damit man jeden
Datensatz eindeutig identifizieren kann. Der Name reicht im Beispiel zum
Identifizieren kaum aus. Denn es kann durchaus sein, dass es drei Meiers
und fnf Schulzes in deinem Team gibt.
Als Zhler verwenden wir eine Zahl. Jeder Datensatz bekommt einen um
eins erhhten Wert. Im Beispiel habe ich einen weiteren Datensatz in die
Tabelle eingetragen.
Damit du dich nicht aus Versehen verzhlst, solltest du die Zhlerei dei-
nem Datenbankprogramm berlassen. MySQL kennt einen Befehl namens
auto_increment. Das steht fr automatisch zhlen. Wir werden beim
Einrichten der Datenbanktabelle also darauf achten, dass wir solch eine
Zhlautomatik in unser Schlsselfeld einbauen.
Wichtig zu wissen: Solch ein Schlssefeld wird auch als Primrschlssel
bezeichnet. Dafr kannst du dir den Befehl PRIMARY KEY merken.
Diese eindeutige Kennung alias Primrschlssel ist auch dann wichtig,
wenn man mehrere Datenbanktabellen miteinander in Beziehung setzen
mchte. Doch halt so weit sind wir an dieser Stelle noch nicht. Dafr
musst du dich noch ein paar Kapitel gedulden!
298
Ein Adressbuch fr dein Team

Kapitel
13
Was bentigen wir?
Halten wir fest: Wir bentigen eine Datenbank. Ich schlage folgenden Na-
men vor:
0 team
Auerdem brauchen wir die eben geplante Datenbanktabelle, also den ei-
gentlichen Datenspeicher. Diese Tabelle nennen wir im Beispiel Nomen
est Omen einfach mal:
0 adressen
In dieser Datenbanktabelle legen wir zuerst die Feldnamen fest und tragen
dann die Daten ein. Doch schn der Reihe nach
Geniales Tool: phpMyAdmin
Wir nutzen das Datenbankprogramm MySQL. Das ist klar. Der Haken bei der
Geschichte: MySQL ist alles andere als komfortabel. Fr die Bedienung von
MySQL musst du auf Kommandozeilen-Ebene hinabsteigen. Im Klartext: Du
musst eine DOS-Box ffnen und das Programm von dort aus mit Befehlen
fttern. Hast du dazu Lust? Nein? Kein Problem! Es gibt ein Programm, mit
dem man MySQL auf ganz komfortable Weise bedienen kann! Sowohl mit
Befehlen also auch grafisch mit Komfort. Dieses Programm heit phpMy-
Admin! Es ist also eine Art grafische Oberflche fr MySQL.
phpMyAdmin aufrufen
Du hast XAMPP und deinen lokalen Webserver erfolgreich installiert? Dann
ist phpMyAdmin fix und fertig eingerichtet. Das Tool wartet auf seinen
groen Auftritt. Der einzige Haken: phpMyAdmin sieht in jeder Version und
bei jedem Webhoster ein wenig anders aus. Immer wieder ndern die Ma-
cher das Layout. Wundere dich also nicht, wenn meine Abbildungen etwas
von der Ansicht abweichen, die du am PC siehst. Das Prinzip bleibt gleich!

>
Tippe http://localhost/phpmyadmin und drcke [Enter] das
Programm phpMyAdmin erscheint. Stellen wir es erst etwas ein.
Schaue in den rechten Bereich und whle in den Listenfeldern das
Oberflchendesign ORIGINAL und eine Schriftgre von 90%.
299
Geniales Tool: phpMyAdmin

Die Datenbank anlegen
Als erstes werden wir nun die Datenbank anlegen. Ich rede ber die Daten-
bank, noch nicht ber die Datenbanktabelle! Die Datenbank soll team hei-
en. Auf los gehts los!
>
Klicke in das Feld NEUE DATENBANK ANLEGEN. Tippe den Namen der Da-
tenbank, im Beispiel team.
>
Whle im Feld namens Kollation die Einstellung utf8_general_ci. Im
Feld darunter, bei Zeichensatz / Kollation der MySQL-Verbindung soll-
te ebenfalls utf8_general_ci stehen. Das ist meist die Voreinstellung.
>
Drcke auf die Schaltflche ANLEGEN.

>
Zack! Die Datenbank ist fertig! Das erkennst du an einer Bestti-
gungsseite. Allerdings meldet dir diese Seite auch, dass noch keine
Tabellen gefunden wurden. Wie denn auch. Es gibt noch keine. Das
Anlegen der Tabellen folgt schlielich erst im nchsten Schritt!

Zum Verstndnis: Die Datenbank selbst ist nur die bergeordnete Hlle. Die
eigentlichen Daten liegen jedoch in den Datenbanktabellen. Im Beispiel
bentigen wir eine einzige Tabelle namens adressen.
Die meisten gnstigen Anbieter mit PHP/MySQL-Untersttzung erlau-
ben dir leider nicht, eigene Datenbanken anzulegen. Du darfst in der Re-
gel oft nur eine einzige MySQL-Datenbank nutzen, deren Name noch da-
zu fest vorgegeben ist. Das ist aber nicht weiter schlimm. Schlielich
kannst du in dieser Datenbank immerhin Datenbanktabellen nach dei-
nem Geschmack einrichten. Und ob die bergeordnete Hlle nun team
oder v945rz3 heit, spielt fr die eigentlichen Daten keine Rolle.
Auf Knopfdruck legst
du eine neue Daten-
bank an.
300
Ein Adressbuch fr dein Team

Kapitel
13 Etwas SQL zum Anlegen der
Datenbanktabelle
Genug geredet. Nun geht es um das Anlegen der Datenbanktabelle. Do you
speak SQL? In diesem Kapitel bekommst du einen ersten Einblick in eine
neue Fremdsprache. Du lernst die Grundzge der Sprache SQL kennen.
SQL ist die Abkrzung fr Structured Query Language. Das heit so viel
wie strukturierte Abfragesprache. Dahinter verbirgt sich eine Sprache
zum Abfragen, aber auch zum Einrichten von Datenbanken und Daten-
banktabellen. Das Schne daran: SQL ist international, sie wird welt-
weit gesprochen. Du kannst damit praktisch jede Datenbank abfragen,
egal ob sie nun MySQL, Access oder Oracle heit. Es handelt sich also um
eine Art Datenbank-Esperanto, allerdings mit englischen Akzent.
Tatsache: Die Sprache SQL hnelt dem gesprochenen Englisch! Sie lehnt
sich an die Kleinkind-Sprache mit ganz einfachen Stzen an. Solch ein Satz
knnte (auf Deutsch) lauten ERZEUGE TABELLE adressen. Auf SQL-
Englisch heit das dann CREATE TABLE adressen.
Merke: SQL-Befehle schreibt man nur deshalb gro, um sie besser unter-
scheiden zu knnen. Du knntest sie ebenso gut auch klein schreiben, da
Gro- und Kleinschreibung nicht unterschieden werden. Im Buch bleibe
ich aber bei der Groschreibung die hat sich durchgesetzt.
Syntax zum Anlegen der Tabelle
Nutzen wir SQL doch gleich zum Anlegen einer neuen Datenbanktabelle.
Schlielich wartet das Feld SQL-BEFEHL(E) IN DATENBANK TEAM AUSFHREN in
phpMyAdmin regelrecht darauf, dass hier etwas passiert. Die Syntax zum
Einrichten einer Tabelle lautet wie folgt:
CREATE TABLE Tabellenname () DEFAULT CHARACTER SET utf8;
Hinter unserem Tabellenerzeugungssatz folgt also noch ein Paar runder
Klammern. In den runden Klammern gibst du nacheinander die Felder und
die jeweiligen Datentypen an. Jede Felddefinition bekommt eine eigene
Zeile damit es bersichtlicher wird. Du trennst solch eine Definitionszei-
le jeweils durch ein Komma von der nchsten!
Nach dem Klammernpaar legst du UTF-8 als Standard-Zeichensatz fest.
301
Etwas SQL zum Anlegen der Datenbanktabelle

Datenbankfelder definieren
Zur Erinnerung: Fr unsere Adressdatei habe ich mir folgende Feldnamen
ausgedacht: id, Vorname, Name, Str, PLZ, Ort, Tel, EMail, WWW und Notizen.
Doch wie sehen diese Felddefinitionen aus? Geduld! Zuerst liste ich dir die
entsprechenden Befehle schon einmal vorab auf:
Feldname Datentyp (Felddefinition)
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
Vorname VARCHAR(20)
Name VARCHAR(20)
Str VARCHAR(20)
PLZ CHAR(5)
Ort VARCHAR(30)
Tel VARCHAR(25)
EMail VARCHAR(30)
WWW VARCHAR(30)
Notizen TEXT
Schlsselfeld anlegen (Primrschlssel)
Fangen wir mit der ersten und wohl schwierigsten Zeile an. Es geht um die
Befehle zum Anlegen des Primrschlssels:
INT NOT NULL AUTO_INCREMENT PRIMARY KEY

Was bedeutet INT? Ganz einfach: Das Feld soll eine Zahl von Datentyp
Integer (INT) sein! Schlielich wird hier automatisch gezhlt!
Der Datentyp Integer erlaubt Werte, die bis in den Milliardenbereich
gehen. Konkret sind das Werte zwischen -2.147.483.648 und
2.147.483.647. Das gengt, findest du nicht auch? Wenn du dich jedoch
auf weniger Adressen beschrnken mchtest, kannst du den Datentyp
SMALLINT UNSIGNED verwenden. Das erlaubt immer noch bis zu 65.535
Datenstze! (Die wichtigsten Datentypen bespreche ich gleich.)
Mit dem Schlsselwort NOT NULL klammere ich den Wert 0 aus.
AUTO_INCREMENT bedeutet wiederum, dass das Hochzhlen ganz automa-
tisch erfolgt. Der Wert wird bei jedem neuen Datensatz automatisch inkre-
mentiert (hochgezhlt). Besonders wichtig ist der Befehl PRIMARY KEY.
Damit mache ich dieses Feld zum Schlsselfeld, zum Primrschlssel. Es ist
der eindeutige Bezeichner. Jedes Feld bekommt dadurch also einen abwei-
chenden Wert, eine eindeutige id!
302
Ein Adressbuch fr dein Team

Kapitel
13
VARCHAR, CHAR und TEXT
In fast allen brigen Feldern verwende ich den Datentyp VARCHAR(). Das
ist ein Datentyp, der das Speichern von Zeichenketten mit variabler Lnge
erlaubt. Wie lang diese Zeichenketten sein drfen, gibst du innerhalb der
runden Klammern an. Es ist eine maximale Lnge von 255 Zeichen mglich!
Wenn das Feld nur 20 Zeichen umfassen soll, schreibst du: VARCHAR(20).
Wenn du dagegen 255 Zeichen ausschpfen mchtest, schreibst du
VARCHAR(255). Du darfst die runden Klammern bei diesem Datentyp nicht
weglassen. Fr die Postleitzahl bentige ich dagegen (bei uns in Deutsch-
land) immer genau 5 Zeichen. Die Lnge variiert nicht. Da gengt der Da-
tentyp CHAR fr eine feste Lnge. Das spart pro Datensatz ein Byte:
CHAR(5).
Warum speichere ich Zahlen wie die PLZ oder Telefonnummer mit einem
Text-Datentyp, also mit VARCHAR bzw. CHAR? Warum nicht! Schlielich
bentige ich diese Zahlen nicht fr irgendwelche Berechnungen. Auer-
dem kann ich auf diese Weise auch Telefonnummern mit groer Lnge
sichern, ohne mich darum kmmern zu mssen, welchem Zahlen-Daten-
typ diese Lnge entspricht. Fast noch wichtiger ist folgender Fakt: Nur so
lassen sich Telefonnummern mit Binde- oder Querstrichen sichern; Zei-
chen, die man bei aller Liebe nicht dem Zahlenformat zuordnen kann.
Das Feld Notizen bekommt dagegen den Datentyp TEXT zugewiesen.
Solch ein Feld hat Platz fr eine ganze Kurzgeschichte. Du kannst weit
ausschweifende Passagen mit bis zu 65.535 Zeichen Lnge eintragen!
Die Tabelle anlegen
So, und nun bauen wir mit diesem Wissen die Tabelle zusammen. Zuerst
notierst du CREATE TABLE adressen () wie vorhin besprochen. Auer-
dem bereitest du zwischen den runden Klammern schon ein paar Leerzeilen
vor. In den runden Klammern werden wir nun Zeile fr Zeile die Definition
des entsprechenden Datenfelds festlegen. Bei dieser Gelegenheit legen wir
den Feldnamen und den entsprechenden Datentyp fest.
Zuerst notierst du den Namen des knftigen Feldes. Dann lsst du ein
Leerzeichen frei. Danach folgt die schon besprochene Definition des Da-
tentyps. Bei Bedarf (z. B. beim ersten Feld fr den Primrschlssel) kom-
men weitere Befehle und Anweisungen hinzu. Am Schluss der Zeile setzt
du ein Komma. Nur bei der letzten Zeile verzichtest du auf das Komma!
303
Etwas SQL zum Anlegen der Datenbanktabelle

Und so sieht die Befehlsfolge im Beispiel aus:
CREATE TABLE adressen (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Vorname VARCHAR(20),
Name VARCHAR(20),
Str VARCHAR(20),
PLZ CHAR(5),
Ort VARCHAR(30),
Tel VARCHAR(25),
EMail VARCHAR(30),
WWW VARCHAR(30),
Notizen TEXT
) DEFAULT CHARACTER SET utf8;

Tippe diese Zeilen in das Eingabefeld fr die SQL-Befehle. Dieses Feld er-
reichst du durch Klick auf die Registerzunge SQL.
Dein Dienstleister bietet MySQL-Untersttzung? Du hast dort ber das
Konfigurationsmen schon eine Datenbank eingerichtet bzw. findest eine
vorinstallierte Datenbank vor? Dann kannst du die nchsten bungen
auch direkt auf dem Server durchfhren! Lies die Hinweise am Anfang
von Kapitel 17! Lies den Abschnitt MySQL und dein Dienstleister.
Egal ob online oder offline: Hast du das Feld gefunden? Beachte, dass die
letzte Zeile vor der schlieenden runden Klammer kein Komma mehr be-
kommen darf. Lasse also diesen Pausenhaken hinter TEXT auf jeden Fall
weg. Und setze hinter DEFAULT CHARACTER SET utf8 ein Semikolon.
Alles klar? Klicke auf die Schaltflche OK.

Tippe die Befehle in das
entsprechende
Eingabefeld.
304
Ein Adressbuch fr dein Team

Kapitel
13
Wenn es geklappt hat, erscheint nun dieses oder ein hnliches Bild. Hier
eine Ansicht aus einer lteren Version von phpMyAdmin:

Hoppla, du hast einen Fehler gemacht? Prfe noch einmal ganz genau,
ob du dich nicht irgendwo verschrieben hast! Schon ein vergessenes
Komma oder ein falsch gesetztes Leerzeichen fhrt dazu, dass der SQL-
Code fehlerhaft ist. Zum Glck zeigt dir phpMyAdmin stets die fehlerhaf-
te Zeile und du bekommst eine zweite Chance. Korrigiere deinen Code
und probiere es erneut!
Wenn es partout nicht klappen will, schaue einfach auf die CD! Im Ordner
mit den Beispieldateien findest du die Datei SQL_adressen.txt. Dort
habe ich die SQL-Befehle zum Anlegen dieser Tabelle fr dich abgelegt. Du
brauchst einfach nur diese Textdatei aufzurufen und die Befehlsfolge in
phpMyAdmin hineinzukopieren!
Oder du schaust zum Register IMPORTIEREN und klickst auf die Schaltflche
DURCHSUCHEN. Suche die Textdatei mit den SQL-Befehlen aus dem Dateisys-
tem aus. Nach Klick auf OK werden die Befehle ausgefhrt.
Die Datentypen im berblick
Reden wir nun kurz ber die Datentypen. (Wenn du schnell an deiner Tabel-
le weitermachen mchtest, kannst du diesen Abschnitt auch berfliegen.
Lies ihn spter. Aber lies ihn!)
PHP ist einfach, erinnerst du dich? Du brauchst dich um den Datentyp nicht
zu kmmern. Das Programm erkennt automatisch, ob es sich um eine
Ganzzahl, eine Kommazahl oder um Text handelt. Es gibt nur wenige Da-
305
Die Datentypen im berblick

tentypen. Und auch die knnen dir egal sein, denn die Zuweisung erfolgt
automatisch. Ganz anders ist das jedoch in einer Datenbank! Hier spielen
die Datentypen eine enorm wichtige Rolle. Bei Datenbanken mit mehreren
tausend Eintrgen geht es schlielich um die optimale Ausnutzung des
Speicherplatzes. Bisher kennst du lediglich INT, VARCHAR, CHAR und TEXT,
aber es gibt weit mehr Datentypen.
Du erwartest unzhlige Eintrge in deiner Datenbanktabelle? Dann wh-
le mglichst den Datentyp mit dem geringsten Speicherbedarf. Bei zehn
Adressen ist das Thema Speicherplatz sicher egal, bei zehntausend spielt
es schon eine entscheidende Rolle, ob das Feld ein paar Bytes mehr oder
weniger bentigt!
Die wichtigsten Datentypen
Keine Angst, hier folgen keine seitenlangen Tabellen. Ich zeige dir nur die
wichtigsten Datentypen. Es sind die Datentypen, die am hufigsten ver-
wendet werden. Aus diesem Grund habe ich die Datentypen auch ausfhr-
lich beschrieben.

Datentyp Beschreibung Besonderheit Speicherbedarf
VARCHAR(M)
Zeichenkette mit variabler
Lnge
1 bis 255 Zeichen Lnge
mglich, die maximal
erlaubte Lnge wird
durch M gekennzeich-
net, (M) darf nicht
weggelassen werden
Lnge des Wertes
plus 1 Byte
CHAR(M)
Zeichenkette mit fester
Lnge
1 bis 255 Zeichen Lnge
mglich, die maximal
erlaubte Lnge wird
durch M gekennzeich-
net, (M) darf nicht
weggelassen werden
M Bytes
TEXT
Zeichenkette mit maximal
65.535 Zeichen (64 KB)
Gro- und Kleinschrei-
bung werden nicht
bercksichtigt (wichtig
fr Sortierung und
Vergleich)
Lnge des Wertes
plus 2 Bytes
INT oder
auch
INT(M)
Ganzzahl zwischen -2,147
Mrd und 2,147 Mrd, (M)
bezieht sich auf die Anzeige
breite und ist optional.
Der Zusatz UNSIGNED
(ohne Vorzeichen) be-
schrnkt auf den positi-
ven Wertebereich. INT
UNSIGNED beherbergt
Zahlen zwischen 0 und
4,3 Mrd.
4 Bytes (32 Bits)
306
Ein Adressbuch fr dein Team

Kapitel
13

Datentyp Beschreibung Besonderheit Speicherbedarf
SMALLINT
oder auch
SMALLINT(M)
Ganzzahl zwischen
-32.768 und 32.767,
(M), die Anzeigebreite,
ist optional
bei zustzlicher Verwen-
dung des Attributs
UNSIGNED ist ein Werte-
bereich von 0 bis 65.535
mglich
2 Bytes (16 Bits)
TINYINT
oder auch
TINYINT(M)
sehr kleine Ganzzahl
zwischen 128 und
127, (M) ist optional
bei zustzlicher Verwen-
dung des Attributs
UNSIGNED ist ein Werte-
bereich von 0 bis 255
mglich
1 Byte
FLOAT
Fliekommazahl (Kom-
mazahl) mit einem
Wertebereich von 0 und
von +/-1,175494351E-
38 bis +/-
3,402823466E+38
In anderen Worten: eine
Kommazahl mit einer
recht hohen Genauigkeit
hinter dem Komma (Be-
achte, dass du beim
Eintragen in die Daten-
bank statt des Kommas
einen Dezimalpunkt
setzen musst!)
4 Bytes (32 Bits)
DOUBLE
Fliekommazahl (Kom-
mazahl) mit einem
Wertebereich von 0 und
von +/-
2.2250738585072014E
-308 bis +/-
1.7976931348623157E
+308
Eine Kommazahl mit einer
enormen Genauigkeit
hinter dem Komma
(Double Precision)
8 Bytes (64 Bits)
DATE
Feld zum Speichern des
Datums im Format
YYYY-MM-DD (2004-
12-31)
Mit berprfung, ob
weniger als 32 Tage und
13 Monate verwendet
wurden, Wertebereich
zwischen 01.01.1000 und
31.12.9999
3 Bytes (24 Bits)
DATETIME
Feld zum Speichern von
Datum und Zeit im
Format YYYY-MM-DD
hh:mm:ss (2004-12-31
23:58:58)
Erfasst auch die Zeit,
Wertebereich zwischen
01.01.1000 und
31.12.9999
8 Bytes (64 Bits)
TIMESTAMP
bzw.
TIMESTAMP(M)
Aktueller Zeitstempel
im Format YYY-
YMMDDhhmmss, reicht
von 19700101000000
bis zum Jahr 2037
Kann durch M gesteuert
werden, M kann z. B. die
Werte 14, 12, 8 oder 6
annehmen, bei
TIMESTAMP(12) ist das
Datum nur noch zweistel-
lig YYMMDDhhmmss, bei
TIMESTAMP 8 ist das
Datum zwar vierstellig,
aber die Uhrzeit entfllt
usw.
4 Bytes (32 Bits)

307
Trage ein paar Adressen ein!

Trage ein paar Adressen ein!
Das Grundgerst der Tabelle steht? Wunderbar! Trage einfach ein paar Ad-
ressen in deine Datenbanktabelle ein. Auch hierbei hilft dir der phpMyAd-
min auf ganz hervorragende Weise.
Datensatz eintragen
>
Klicke auf einen Link bzw. eine Registerzunge namens EINFGEN. Nun
ffnet sich die Ansicht zur Eingabe deiner Daten. Das sieht aus wie
eine Datenbankmaske.
>
Das Feld id lsst du frei. Dahinter steckt schlielich der Primrschls-
sel, der automatisch ausgefllt wird. Trage nun Schritt fr Schritt die
anderen Daten in die entsprechenden Felder ein.

Die Auswahlfelder beim Eintrag FUNKTION sind fr unsere Zwecke nicht
wichtig. Doch was bedeutet das Hkchen bei NULL? Wenn du ein Feld frei
lsst, wird automatisch der Wert 0 eingetragen. Um das zu unterbinden,
httest du in der Definition der Feldnamen zustzlich das Schlsselwort
NOT NULL eintragen mssen, z. B. Tel VARCHAR(25) NOT NULL! Das
haben wir aber nicht gemacht, da die 0 berhaupt nicht strt und
gleichbedeutend ist mit Nichts. (Die Datenbank gibt an dieser Stelle
spter keine 0, sondern einen Leerstring aus.)

Nach Klick auf EINFGEN kannst du bis zu zwei Datenstze untereinander eingeben.
Trage die Daten in die
entsprechenden
Felder ein!
308
Ein Adressbuch fr dein Team

Kapitel
13
>
Du mchtest einen dritten Datensatz eintragen? Schaue zum Ende der
Eingabeseite. Whle eine Option, die je nach Version von phpMyAd-
min Neuen Datensatz eintragen oder (und dann) anschlieend einen
weiteren Datensatz einfgen heit und whle die Schaltflche OK.
Du kannst dir auch die schon eingegebenen Datenstze anzeigen lassen!
Klicke dafr auf den Link Anzeigen. Du mchtest nun von dieser Ansicht
aus Daten eingeben? Du bentigst also eine neue Zeile? Klicke dazu je
nach phpMyAdmin-Version auf Einfgen bzw. Neue Zeile einfgen.
Geht auch: Daten per SQL-Befehl INSERT
eingeben
Lerne wieder etwas SQL! Denn natrlich kannst du auch per SQL deine
Daten in die Tabelle einfgen. Die entsprechende Syntax ist ausnahmsweise
relativ kompliziert, aber du solltest sie trotzdem lernen. Du bentigst sie fr
spter!
Notiere zuerst das Schlsselwort
0 INSERT INTO
wie EINFGEN IN. Gib danach den Namen der Tabelle und ein paar runde
Klammern an:
0 INSERT INTO adressen ()
In den runden Klammern notierst du alle Feldnamen der Datenbanktabelle,
und zwar in der von dir gewnschten Reihenfolge. (Du kannst dabei eine
ganz beliebige Reihenfolge whlen.) Trenne die Feldnamen lediglich durch
ein Komma voneinander.
0 (id, Vorname, Name, Str, PLZ, Ort, Tel, EMail, WWW,
Notizen)
Danach schreibst du nach einem Leerzeichen (oder in einer neuen Zeile)
das Schlsselwort
0 VALUES ()
und vergisst auch hier die runden Klammern nicht. Du gibst nun die einzu-
fgenden Werte an, und zwar genau in der gleichen Reihenfolge wie oben!
Ganz wichtig: Setze jeden Wert in ein Paar einfache Gnsefchen! Auch
das Schlsselfeld bekommt ein paar Gnsefchen, diese lsst du jedoch
leer.
309
Trage ein paar Adressen ein!

('', 'Peter', 'Geppert', 'Hafenstr 3', '76543', 'Kstenstadt',
'', 'geppert@lexi.de', '', 'schwimmt gerne')

Wenn du fr ein Feld keine Daten vorgesehen hast, setzt du ein paar leerer
Gnsefchen! Beachte auf jeden Fall die Reihenfolge innerhalb der runden
Klammern. Du darfst auf keinen Fall einen Wert weglassen! Der ganze Be-
fehl sieht nun so aus. Notiere ihn in das Feld zur EINGABE DER SQL-BEFEHLE:
INSERT INTO adressen
(id, Vorname, Name, Str, PLZ, Ort, Tel, EMail, WWW, Notizen)
VALUES
('', 'Peter', 'Geppert', 'Hafenstr 3', '76543', 'Kstenstadt',
'', 'geppert@lexi.de', '', 'schwimmt gerne')

bung macht den Meister! Trage ruhig auch den zweiten Datensatz ein, im
Beispiel handelt es sich um eine gewisse Monika Hasemann:
INSERT INTO adressen
(id, Vorname, Name, Str, PLZ, Ort, Tel, EMail, WWW, Notizen)
VALUES
('', 'Monika', 'Hasemann', 'Am Feldrand', '01234', 'Kuhdorf',
'0170-8739874', 'mohase@lexi.de', '', '')

Und, hat das Eintragen der Daten funktioniert? Prfe es! Klicke auf den Link
Anzeigen, um alle Datenstze einzublenden! Hinweis: Das erste runde
Klammernpaar kannst du auch weglassen immer dann, wenn du beim
Eintragen der Daten alle Felder bercksichtigst und dabei die vorgegebene
Reihenfolge der Felder einhltst. (Das werden wir aber erst im Gstebuch
von Kapitel 15 ausprobieren!)
Du erntest stndig Fehlermeldungen? Du findest deinen Fehler nicht?
Kein Problem, ich habe dir diese beiden SQL-Befehle auf die CD zum
Buch gelegt. Rufe einfach die Datei SQL_Datensaetze.txt auf und
bernimm die dort enthaltenen SQL-Befehle. (Da ich dort zwei SQL-
Anweisungen hintereinander notiert habe, musste ich sie durch ein Se-
mikolon trennen!)
Wo legt MySQL die Daten ab?
Hast du dich eigentlich schon einmal gefragt, wo MySQL die ganzen Daten
sichert? Wo landet deine Datenbank team? Wo stecken die Daten der Da-
tenbanktabelle adressen? Zumindest fr dein lokales System kann ich dir
310
Ein Adressbuch fr dein Team

Kapitel
13
diese Frage beantworten! Die Daten liegen in einem Unterordner unter
mysql. Dieser Unterordner heit data. Da MySQL in unserem Beispiel un-
ter C:\xampp\mysql installiert wurde, finden sich alle Datenbanken unter
C:\xampp\mysql\data.

Jede Datenbank bekommt einen eigenen Unterordner.
Du kannst diese Unterordner sichern und auf diese Art sogar auf andere
Rechner bertragen.
Wo diese Datenbanken jedoch beim Dienstleister genau abgelegt wer-
den, ist in der Regel nicht bekannt! Bei den preisgnstigen Dienstleistern
mit PHP/MySQL-Untersttzung kommst du normalerweise nicht an die-
sen Ordner heran. Diese Anbieter erlauben dir lediglich, ber das Tool
phpMyAdmin mit deiner Datenbank zu kommunizieren. Fr den vollen
Datenbankzugriff bentigst du einen eigenen Webserver und das wird
teuer!
Tipps und Tricks zur Bedienung von
phpMyAdmin
phpMyAdmin bietet eine freundliche und einfach zu bedienende Oberfl-
che! Mit diesem Tool kannst du alle deine Datenbanken und Datenbankta-
belle verwalten. Trage Daten ein, lasse sie dir anzeigen. Hier ein paar Tipps
und Tricks zur Bedienung:
Hauptseite aufrufen
Die Hauptseite oder auch Willkommens-Seite des Programms erreichst
du, wenn du links oben auf den Link HOME klickst also auf das Huschen.
311
Trage ein paar Adressen ein!

Datenbank auswhlen
Die gewnschte Datenbank whlst du links aus dem Listenfeld aus zu-
mindest bei neueren Versionen von phpMyAdmin. Hier werden nicht alle
Datenbanken gezeigt? Die Datenbank team fehlt? Manchmal hngt die
Anzeige etwas! Whle zuerst eine vorhandene Datenbank aus, in der Regel
wird die Anzeige dann aktualisiert.
Datenbanktabellen einblenden
Die in einer Datenbank enthaltenen Datenbanktabellen findest du ebenfalls
im linken Bereich. Klicke das Symbol vor dem Namen der Datenbanktabelle
an, um die Tabellenstruktur zu sehen. Klicke im Beispiel auf das Symbol
links von adressen.
Infos zum Speicherplatzverbrauch der Datenbanktabelle
Rolle in der Tabellenstruktur nach unten. Klicke auf Tabellenstruktur analy-
sieren. Hier findest du ntzliche Infos und Tools rund um diese Datenbank-
tabelle. Interessant sind z. B. die Angaben zum Speicherplatzverbrauch.
Inhalt der Datenbanktabelle anzeigen
Du mchtest den Inhalt der Datenbanktabelle anzeigen? Das geht zum
einen durch Klick auf die Registerzunge ANZEIGEN. Zum anderen kannst du
aber auch links direkt auf den Namen der Datenbanktabelle klicken.

Datenstze sortieren
Du mchtest deine Datenstze sortiert anzeigen? Kein Problem! Klicke ein-
fach auf die entsprechende Spaltenbeschriftung. Ein neuerlicher Klick dreht
die Sortier-Reihenfolge um.
Zum Hauptmen der Datenbank wechseln
Du mchtest zwar nicht auf die Willkommens-Seite von phpMyAdmin,
aber ins Hauptmen der jeweiligen Datenbank? Vielleicht, weil du weitere
Datenbanktabellen einrichten mchtest? Klicke im linken Bereich einfach
auf den Namen der Datenbank, hier auf team. Auch das ist also ein Hyper-
Der Klick auf den ent-
sprechenden Link zeigt
den Inhalt der Daten-
banktabelle.
312
Ein Adressbuch fr dein Team

Kapitel
13
link! phpMyAdmin ist ein ntzliches Werkzeug mit vielen Mglichkeiten.
Probiere am Anfang ruhig ein wenig herum!
SQL geht dir momentan etwas auf den Senkel? Du mchtest eine Daten-
banktabelle auf komfortablere Art und Weise einrichten? Gehe ins
Hauptmen der jeweiligen Datenbank, z. B. durch Klick auf den Namen
der Datenbank oder durch Auswahl der Datenbank im Listenfeld ganz
links. Rolle dann etwas tiefer zum Bereich Neue Tabelle in Datenbank so-
undso erstellen. Trage den Namen der gewnschten Datenbanktabelle in
das Feld NAME ein. Lege die Anzahl der Felder im Feld FELDER fest. Nach
Klick auf OK erscheint eine Seite, auf der du die Namen der einzelnen
Felder und die jeweiligen Datentypen ber Mens auswhlen kannst.
phpMyAdmin generiert den entsprechenden SQL-Code automatisch fr
dich und zeigt ihn dir an! Ideal auch zum spielerischen Lernen von SQL!
Lerne am Vorbild!
Alle Teammitglieder da? Schaue
nach!
Datenbanking mit SQL macht Spa! Wetten? Ich empfehle dir trage ruhig
ein paar weitere Adressen in die Datenbanktabelle adressen ein. Damit
hast du etwas Material zum Spielen. Denn jetzt zeige ich dir, wie du mit
SQL Datenbanktabellen abfragst spielerisch natrlich! Fr die nchsten
Experimente bentigst du stets die Hauptansicht. Klicke am besten im
linken Bereich auf den Namen deiner Datenbank. Klicke im Beispiel auf den
Namen team. Whle dann die Registerzunge SQL. Dann siehst das Feld zur
Eingabe der SQL-Befehle und genau das brauchst du!

Gib die SQL-Befehle im
Register SQL ein oder
importiere sie aus einer
Textdatei! Letzteres
gelingt im Register
Importieren.
313
Alle Teammitglieder da? Schaue nach!

Alle Datenstze ausgeben mit SELECT
Und nun gehts weiter mit unserem SQL-Crashkurs! Du mchtest Daten
ausgeben? Dafr bentigst du das Schlsselwort SELECT wie AUSWHLEN.
Wenn du alles auswhlen mchtest, tippst du das Sternchen * und
schreibst zum Schluss das Schlsselwort FROM. Dahinter gibst du den Na-
men der Tabelle an. Vergiss nicht die obligatorischen Leerzeichen zwischen
den einzelnen Schlsselwrtern.
Du mchtest alle Datenstze aus deiner Tabelle adressen ausgeben? Fol-
gender Befehl erledigt den Job fr dich:
SELECT * FROM adressen

Klicke auf OK und staune. So einfach ist SQL!
Nur einzelne Felder ausgeben
Du mchtest nicht alle Felder anzeigen? Du willst nur den Namen wissen?
Oder den Namen und den Vornamen? Nichts leichter als das. Folgende Zeile
SELECT Name FROM adressen

gibt nur die Namensspalte aus. Alle anderen Spalten werden weggeblendet.
Wenn du dagegen Namen und Vornamen mchtest (Feld Name und Feld
Vorname), trennst du diese Angaben einfach mit einem Komma.
SELECT Name, Vorname FROM adressen
Nach bestimmten Auswahlkriterien filtern
mit WHERE
Du mchtest nur diejenigen herausfiltern, die aus Neustadt kommen? Nut-
ze das Schlsselwort WHERE und gib zuerst den Feldnamen an, z. B. den Ort.
Nach einem Gleichheitszeichen notierst du in Gnsefchen den Wert,
nach dem du filtern mchtest. Im Beispiel schreibst du:
WHERE Ort='Neustadt'

Du mchtest die entsprechenden Datenstze komplett ausgeben? Dann
schreibe:
SELECT * FROM adressen WHERE Ort='Neustadt'

314
Ein Adressbuch fr dein Team

Kapitel
13
Und wie lautet der Befehl, wenn du nur Namen und Vornamen aller Team-
mitglieder aus Neustadt anzeigen mchtest? Genau so:
SELECT Name, Vorname FROM adressen WHERE Ort='Neustadt'

Gro- und Kleinschreibung spielt hier brigens keine Rolle. Auch wenn du
in der Datenbank aus Versehen neustadt notiert hast, wird dieser Daten-
satz gefunden! Allerdings sind keine Zustze zum Wort Neustadt erlaubt,
das Gleichheitszeichen verlangt exakt diese Zeichenfolge.
Was machst du jedoch, wenn einige der Teammitglieder in Neustadt-
Sd, andere dagegen in Neustadt-Nord und andere wiederum in Gro
Neustadt wohnen? Denn mit Ort='Neustadt' erwischst du doch wirk-
lich nur diejenigen, die genau in Neustadt wohnen?! Du verwendest den
Operator LIKE. Denn so kannst du auerdem auf den Platzhalter % zu-
rckgreifen, der quasi als Joker fr kein, ein oder auch beliebig viele an-
dere Zeichen steht. Folgender Vergleich
SELECT * FROM adressen WHERE Ort LIKE '%Neustadt%'
liefert wirklich alle Datenstze, in denen das Feld Ort irgendwas mit
Neustadt zu tun hat.
Auswahlkriterien miteinander verknpfen
Wenn du mchtest, kannst du auch mehrere Auswahlkriterien miteinander
verknpfen. Dafr stehen dir z. B. folgende Operatoren zur Verfgung:
0 AND (wie UND)
0 OR (wie ODER)
Du mchtest alle Teammitglieder aus Neustadt anzeigen, die mit Nachna-
men Meier heien? Schreibe
SELECT * FROM adressen WHERE Ort='Neustadt' AND Name='Meier'

Du mchtest dagegen die Mitglieder herausfinden, die in Neustadt wohnen
oder die Meier heien?
SELECT * FROM adressen WHERE Ort='Neustadt' OR Name='Meier'

Dann bekommst du zum einen die Neustdter angezeigt und auch alle
anderen eventuellen Meiers. Probiere es aus! Trage ggf. noch ein paar Da-
tenstze in die Liste ein!
315
Alle Teammitglieder da? Schaue nach!

Wundere dich nicht: phpMyAdmin hngt an alle Abfragen noch das
Schlsselwort LIMIT 0, 30. Damit werden nur die ersten 30 Datenst-
ze angezeigt. Der erste Wert steht fr den Startdatensatz. Die Zhlung
beginnt hierbei wieder bei 0 die Arrays lassen gren! Der zweite Wert
sagt aus, wie viele Datenstze du gleichzeitig sehen mchtest. Wenn du
die nchsten 30 Datenstze einblenden mchtest, gibst du den SQL-
Befehl erneut ein. Fge dann LIMIT 30, 30 ein.
Sortieren mit ORDER BY
Auch das Sortieren deiner Datenstze ist mit SQL berhaupt kein Problem!
Dafr bentigst du das Schlsselwort ORDER BY. Sortiere deine Adressliste
doch einfach nach dem Nachnamen. Dafr setzt du nach diesem Schls-
selwort lediglich den Feldnamen ein:
0 ORDER BY Name
Dabei wird automatisch aufsteigend nach dem Alphabet sortiert. Um z. B.
alle Datenstze nach Namen sortiert anzuzeigen, schreibst du:
SELECT * FROM adressen ORDER BY Name

Wenn du jedoch nach dem Ort und innerhalb des Ortes auch nach dem
Namen sortieren mchtest, schreibst du
SELECT * FROM adressen ORDER BY Ort, Name

In diesem Falle richtet sich die Hauptsortierreihenfolge nach dem Ort. Die
Orte stehen alphabetisch geordnet untereinander. Innerhalb eines Ortes
jedoch werden die Datenstze zustzlich nach Namen sortiert.
Du kannst aber auch absteigend sortieren. Dann notierst du hinter dem
Sortierbefehl zustzlich das Schlsselwort DESC fr descending, abstei-
gend. Du mchtest alle Datenstze nach dem Namen sortieren, und zwar
alphabetisch rckwrts? Dann sieht die Zeile folgendermaen aus:
SELECT * FROM adressen ORDER BY Name DESC
Nun werden die Namen mit X, Y oder Z an allererster Stelle erscheinen.
316
Ein Adressbuch fr dein Team

Kapitel
13
Wie wrs mit einem UPDATE?
Du mchtest den bestehenden Inhalt einer Datenbank aktualisieren? Das ist
manchmal sogar verdammt wichtig! Schlielich kannst du nicht davon
ausgehen, dass deine Team-Mitglieder immer am gleichen Ort wohnen
bleiben. Die Mglichkeit fr Adressnderungen solltest du schon vorsehen.
ndere eins oder auch mehrere Felder eines Datensatzes, und zwar mit dem
Schlsselwort UPDATE. Danach gibst du wieder den Tabellennamen an und
notierst auerdem das Schlsselwort SET
0 UPDATE tabellenname SET
Doch welche Felder mchtest du aktualisieren? Und von welchem Daten-
satz? Hier kommt wieder die WHERE-Klausel ins Spiel. Angenommen, Petra
Kulicke (Datensatz mit der id 5) zieht von der Parkstr. 12 in Platanenallee
22. Dann schreibst du.
UPDATE adressen SET Str='Platanenallee 22' WHERE id='5'

Dadurch werden die alten Werte dieser Felder automatisch berschrieben!
Die Zahl musst du brigens nicht in Gnsefchen einkleiden. Das Feld id
ist schlielich ein Feld vom Typ INT (Integer), also ein Zahlenfeld. Wenn du
die Gnsefchen jedoch setzt, ist das nicht schlimm.
Soll neben der Strae gleichzeitig die Postleitzahl gendert werden? Kein
Problem! Liste das zweite (oder dritte, vierte usw.) Feld einfach nach einem
Komma auf.
UPDATE adressen SET Str='Platanenallee 22', PLZ='23010'
WHERE id='5'
Auch das geht: Datenstze lschen mit
DELETE
Zum Schluss stelle ich dir den wohl mchtigsten, aber auch gefhrlichsten
SQL-Befehl vor. Es ist der Befehl DELETE. Die Syntax lautet
0 DELETE FROM tabellenname WHERE bedingung
Du mchtest den Datensatz mit der id 2 aus deiner Tabelle entfernen?
Dann schreibst du
DELETE FROM adressen WHERE id='2'
317
Daten als HTML-Tabelle ausgeben

Auf hnliche Weise knntest du auch alle Meiers oder alle Teammitglieder
aus Kuhdorf aus deiner Datenbank herausradieren. Fr die Meiers she das
so aus:
DELETE FROM adressen WHERE Name='Meier'

Du mchtest eine ganze Tabelle auf einen Rutsch lschen? Dann ver-
wendest du statt DELETE das Schlsselwort DROP. Der Befehl DROP
TABLE adressen lscht die gesamte Tabelle adressen auf einen
Rutsch. Halt nicht ausprobieren, das war doch nur als Information ge-
dacht. Wie bitte, schon zu spt? Nimms von der heiteren Seite! Das ist
immerhin eine gute bung zum Wiederholen und Festigen! Lege die Ta-
belle adressen einfach erneut an. Richte die entsprechenden Adress-
Datenstze ein. Und hte dich beim nchsten Mal vor dem Befehl DROP!
Daten als HTML-Tabelle ausgeben
Hast du dich schon etwas eingefuchst mit SQL? Klappt es mit den Befehlen
und Abfragen? Hervorragend! Die kleine Mhe war nicht umsonst, wie du
gleich merken wirst. Du bentigst das SQL-Wissen fr den Zugriff auf die
Datenbank!
Blende die Daten mit PHP und HTML ein. Das ist gar nicht so einfach, aber
wir schaffen das! Zuerst fangen wir ganz bescheiden an und geben ledig-
lich ein paar Felder unserer Adressliste aus. Danach steigern wir uns bis zu
einer schicken Tabelle, die alle Datenfelder anzeigt.
Einfache Ausgabe der Daten
Im ersten Beispiel liest du alle Datenstze aus. Zeige von allen Datenstzen
den Vornamen, Namen und den Ort an. Also nur diese drei Felder.
Erstelle dazu eine PHP-Datei und fge folgenden Code ein. Ich liste dir den
gesamten Bereich zwischen <body></body> auf. Speichere das Dokument
und probiere es aus. Funktioniert es?
<h3>Adressen anzeigen</h3>
<p>
<?php
$db = mysqli_connect("localhost", "root", "");
mysqli_set_charset($db, "utf8");
mysqli_select_db($db, "team");
318
Ein Adressbuch fr dein Team

Kapitel
13

$sql = "SELECT * FROM adressen";
$result = mysqli_query($db, $sql);
while ($row = mysqli_fetch_assoc($result)) {
echo "$row[Vorname] $row[Name], $row[Ort] <br>\n";
}
mysqli_close($db);
?>
</p>


Es hat nicht geklappt? Du hast beim Abschreiben einen Fehler gemacht? Du
findest die Datei unter dem Namen zeige_adressen1.php auf der CD.
Beachte, dass du fr deine Datenbank evtl. Benutzernamen und Passwort
anpassen musst. Wo genau, verrate ich dir gleich.
Hast dus gemerkt? Hier greift der Autor auf die Komfortschreibweise bei
assoziativen Arrays zurck. Komfortschreibweise bedeutet, dass der key
nicht in Gnsefchen notiert wird, wie es eigentlich sein sollte. Also
statt $row["Vorname"] verwendet der Autor stets die Schreibweise
$row[Vorname] und statt $row["Name"] einfach $row[Name] usw.
Dieser kleine Trick vereinfacht den Code. Er ist dann zulssig, wenn die
Variable selber innerhalb eines Strings notiert wurde, also selber Teil ei-
nes weit umspannenden Gnsefchen-Paars ist. Auf diese Weise er-
sparst du dir das Verketten der Variablen und kommst nicht so leicht mit
den vielen Punkten und Gnsefchen durcheinander.
Im weiteren Verlauf dieses Kapitels greift der Autor aus Grnden der Ver-
einfachung zumindest in diesem Fall immer wieder auf diese bliche
Methode zurck!
Gib Vorname, Name
und Ort von allen
Datenstzen
zeilenweise aus.
319
Daten als HTML-Tabelle ausgeben

Wenn die Variable selber jedoch nicht innerhalb von Gnsefchen plat-
ziert wurde, drfen die Gnsefchen um den key herum nicht fehlen.
0 Orientiere dich an den Farben im PSPad. Wenn der key des Arrays far-
big hervorgehoben wird, ist alles in Ordnung. In diesem Fall sind keine
weiteren Gnsefchen ntig.
0 Bleibt er schwarz, fehlen die Gnsefchen und sollten nicht weggelas-
sen werden. Setze dann je nach Geschmack doppelte oder einfache
Gnsefchen.
So funktioniert das Skript
Nach diesem hoffentlich erfolgreichen Versuch schauen wir uns die Wir-
kungsweise etwas genauer an. Du wirst sehen vieles hnelt vom Prinzip
her dem Umgang mit Textdateien!
Die Funktion mysqli_connect()
Was macht folgende Zeile?
$db = mysqli_connect("localhost", "root", "");

Diese Zeile sorgt zuerst einmal fr die Verbindung mit dem Datenbankser-
ver. Dafr verwendest du die Funktion mysqli_connect. Als Argumente
gibst du folgendes an, und zwar in Gnsefchen, jeweils durch ein Komma
getrennt.
0 localhost (Ort der Datenbank, gilt sowohl offline auf dem heimischen
Rechner als auch auf dem Webserver. Nur, wenn du von einer anderen
Domne aus auf die Datenbank zugreifst, musst du den Namen der Do-
mne angeben.)
0 Benutzername fr die MySQL-Datenbank (z. B. root)
0 Kennwort (z. B. Leerstring)
Beachte, dass bei den meisten Dienstleistern Benutzernamen und Kennwort
fr dich eingerichtet sind. Schaue in die Anmeldungs-E-Mail oder in deine
Vertragsunterlagen!
Und was macht die Variable $db am Anfang? Sie speichert die Verbin-
dungskennung, das ist eine Art Verbindungszeiger. ber diese Kennung
beziehst du dich auf die jeweilige Datenbankverbindung. Andere Funkti-
onen bentigen diese Kennung. $db ist praktisch der rote Faden, der sich
durch alle wichtigen Datenbankfunktionen hindurchzieht. Du kennst das
Prinzip ja schon vom Umgang mit Textdateien!
320
Ein Adressbuch fr dein Team

Kapitel
13
Die Funktion mysqli_set_charset()
Diese Funktion legt den Standard-Zeichensatz fest: UTF-8! Sie bentigt
zwei Argumente: Verbindungskennung und Namen des Zeichensatzes.
mysqli_set_charset($db, "utf8");
(Wenn du diese Zeile weglsst, wird der Inhalt aus der Datenbanktabelle
automatisch als ISO-8859-1 ausgegeben. Das ergibt in unserer als UTF-8
gekennzeichneten und gespeicherten PHP-Datei natrlich frchterlichen
Umlautsalat. Du musst in diesem Fall erst das Meta-Tag fr den Zeichen-
satz bearbeiten. ndere wenn du es unbedingt willst - die Zeichenfolge
utf-8 um in iso-8859-1. Und konvertiere die Datei per FORMAT|ANSI.)
Die Funktion mysqli_select_db()
Die Verbindung steht! Die Funktion mysqli_select_db() sucht nun die
gewnschte Datenbank heraus. Notiere wieder zwei Argumente: zuerst die
Verbindungskennung, dann den Namen der Datenbank in Gnsefchen.
mysqli_select_db($db, "team");

Dein Dienstleister hat dir eine Datenbank vorgegeben? Dann musst du statt
team natrlich diesen Namen in Gnsefchen eintragen. Beachte das
bitte!
SQL-Code in einer Variablen speichern
Die nchste Zeile wird dir vertraut vorkommen. Hier speicherst du vorab
den gewnschten SQL-Befehl. Der Musterbefehl whlt alle Datenstze aus
der Datenbanktabelle adressen aus.
$sql = "SELECT * FROM adressen";

Zum Speichern nutze ich eine Variable, die ich sinnigerweise $sql genannt
habe. Zugegeben, du musst den SQL-Befehl nicht vorab in einer separaten
Variablen speichern. Du knntest ihn auch direkt in den Befehl aus der
nchsten Zeile einfgen.
Aus Grnden der bersichtlichkeit empfehle ich dir jedoch die von mir ge-
zeigte Vorgehensweise!
Abfrage ausfhren mit mysqli_query()
In der nchsten Zeile fhrst du die SQL-Abfrage aus. Dabei hilft dir die
Funktion mysqli_query(). In den runden Klammern bergibst du erst die
Kennung, dann den in der Variablen $sql gespeicherten SQL-String:
$result = mysqli_query($db, $sql);

321
Daten als HTML-Tabelle ausgeben

oder du trgst den SQL-Code direkt in Gnsefchen ein:
$result = mysqli_query($db, "SELECT * FROM adressen");

Das Abfrage-Ergebnis wird in einer Variablen festgehalten, die ich $result
genannt habe, result wie Ergebnis.
Bei diesem Ergebnis handelt es sich um eine sogenannte Ergebnisliste,
um ein result set. Die einzelnen Zeilen werden in Listenform in dieser Va-
riablen gespeichert. Die Zeilen stehen im Prinzip untereinander, wie in
einer Tabelle. Diese Ergebnisliste wird spter Zeile fr Zeile ausgelesen
werden.
Daten mit Hilfe einer Schleife ausgeben
Die nchsten drei Zeilen sind nicht mehr ganz so einfach zu verstehen. Das
gebe ich zu:
while ($row = mysqli_fetch_assoc($result)) {
echo "$row[Vorname] $row[Name], $row[Ort] <br>\n";
}

Zum einen gibt es da eine while-Schleife. Diese fhrt die Befehle aus,
solange die Bedingung wahr ist. Doch was ist hier die Bedingung?
Diese steckt in der Funktion mysqli_fetch_assoc($result)! Das ist
eine ganz ungewhnliche und recht talentierte Funktion. Diese Funktion
holt sich die Ergebnisliste aus unserer Abfrage, also unsere Datenbankta-
belle mit allen Zeilen. Und diese liegt schlielich in der Variablen $result
vor.
Liste ist das Stichwort, die Daten liegen hier zeilenweise vor. Zuerst holt
sich die Funktion mysqli_fetch_assoc($result) die erste Zeile und
wandelt diese in ein Array um. Fetch assoc heit so viel wie hole assozi-
atives Array. Dieses Array wird in einer Variablen gespeichert, die ich sin-
nigerweise $row genannt habe, row wie Zeile!
Die jeweilige Zeile wird dabei als assoziatives Array verwaltet, wie der
Name assoc schon sagt. Der Name des Arrays heit $row. Der key er-
gibt sich aus den Feldnamen. Du mchtest stattdessen ein indiziertes
Array erhalten, also ein Array mit Zahlen? Dann whlst du die Funktion:
0 mysqli_fetch_row()

322
Ein Adressbuch fr dein Team

Kapitel
13 Am hufigsten findest du in der Praxis merkwrdigerweise folgende
Funktion, die mich persnlich jedoch nicht berzeugt hat:
0 mysqli_fetch_array()
Diese liefert beides, und zwar ein assoziatives und ein indiziertes Array
zugleich. Das ist einerseits natrlich ein Komfortgewinn. Diese Funktion
wird in unserem bisherigen Beispiel deshalb auch funktionieren. Diese
doppelte Array-Buchfhrung bereitet jedoch dann Probleme, wenn du
die Elemente des Array zhlen und mit einer foreach()-Schleife durch-
laufen mchtest. In solch einem Falle wird diese Funktion eher hinderlich
sein, da sie alles doppelt zhlt und jeden key bzw. value zweimal aus-
gibt.
Zurck zur Funktion mysqli_fetch_assoc(). Der Clou an der Geschich-
te: Diese Funktion greift sich nach Abarbeitung der vorigen nun die nchste
Zeile. Diese Zeile existiert? Die Funktion in runden Klammern gibt true
zurck? Dann wird die while-Schleife erneut aktiv. Die Funktion
mysqli_fetch_assoc($result) holt sich die nchste Zeile der Daten-
banktabelle und wandelt diese in das Array $row um usw. usf. Das ge-
schieht dank unserer while-Schleife so lange, bis alle Zeilen der Ergebnis-
liste abgearbeitet sind.
Denn erst dann gibt mysqli_fetch_assoc($result) false zurck und
die while-Schleife wird verlassen.
Auf diese Weise kannst du also Zeile fr Zeile auf die gewnschten Werte
zurckgreifen! Im Beispiel gebe ich dabei jedoch lediglich Vornamen, Na-
men und Ort aus:
echo "$row[Vorname] $row[Name], $row[Ort] <br>\n";

Das geschieht so lange, bis alle Zeilen abgearbeitet sind.
Verbindung zur Datenbank beenden
Die letzte Zeile mysqli_close($db); beendet die Verbindung zur Daten-
bank. Das ist zwar nicht unbedingt ntig, gehrt aber zu einem sauberen
Programmierstil. Auch hier muss die Verbindungskennung als Parameter
bergeben werden.
323
Daten als HTML-Tabelle ausgeben

Zeilenzahl ausgeben mit mysqli_num_rows()
Wre es nicht schick, wenn du zustzlich zu den Daten selbst auch die
Anzahl der ermittelten Datenstze ausgeben knntest? Wieso knntest, du
kannst! Dabei hilft dir die Funktion mysqli_num_rows(). Diese Funktion
erwartet das Ergebnis der SQL-Abfrage, also unsere schon besprochene
Ergebnisliste. In unserem Falle also die Variable $result. Die Funktion
mysqli_num_rows() macht nichts weiter, als hier die Zeilen durchzuzh-
len!
Die so ermittelte Zeilenzahl kannst du in einer weiteren Variablen (hier
$zeilen) festhalten und mit echo ausgeben. Platziere diese Zeilen ber
der while-Schleife:
$zeilen = mysqli_num_rows($result);
echo "$zeilen Eintrge:<br><br>\n";


Nicht schlecht, oder? Das derart erweiterte Skript findest du auch in der
Datei zeige_adressen2.php.
Fehlermeldungen unterdrcken
Unser Skript funktioniert, besitzt bisher jedoch noch einige Schnheitsfeh-
ler! Was passiert, wenn der Datenbankzugriff einmal nicht gelingt? Viel-
leicht, weil MySQL gerade nicht zur Verfgung steht? Weil das Passwort
verkehrt ist? Oder der Name der Datenbank nicht stimmt?
Mache dir doch einmal den Jux und verflsche sowohl Benutzernamen oder
Passwort in der ersten PHP-Zeile und den Datenbanknamen in der dritten
PHP-Zeile.
Gib die Zahl der auszuge-
benden Datenstze an.
324
Ein Adressbuch fr dein Team

Kapitel
13

$db = mysqli_connect("localhost", "root", "falscher_Eintrag");
mysqli_set_charset($db, "utf8");
mysqli_select_db($db, "teamz");

Was passiert? Es hagelt Fehlermeldungen noch und ncher!

Was kann man dagegen unternehmen? Ich prsentiere dir zwei Geheim-
tricks!
Der Trick mit dem Klammeraffen
Der erste Trick besteht darin, vor den jeweiligen Funktionen einen Klam-
meraffen zu notieren. Das geht bei den meisten Funktionen und unter-
drckt alle Fehlermeldungen:
$db = @mysqli_connect("localhost", "root", "falscher_Eintrag");
mysqli_set_charset($db, "utf8");
@mysqli_select_db($db, "teamz");

Wenn du deine Seite jetzt aktualisierst, siehst du mglicherweise ber-
haupt nichts. Die Daten werden nicht angezeigt. In der Regel erscheinen
keine, oder zumindest weit weniger kryptische Fehlermeldungen!
Hmm. Trotzdem willst du sicher gerne wissen, wo genau das Problem
steckt? Kein Problem! Da greift mein zweiter Trick:
Friss oder stirb, Liebling!
Verlngere die gewnschten Funktions-Zeilen einfach um die weiter vorne
schon besprochene Anweisung.
or die();

Dadurch wird die Ausfhrung des Skriptes an dieser Stelle abgebrochen. In
den runden Klammern notierst du eine sinnvolle Fehlermeldung. Die so
prparierten Zeilen sehen folgendermaen aus, ich wende diese Technik bei
der Verbindung zu MySQL und der Verbindung zur Datenbank an.
Fehler ber Fehler so
macht der Datenbank-
zugriff keinen Spa!
325
Daten als HTML-Tabelle ausgeben

$db = @mysqli_connect("localhost", "root", "falscher_Eintrag")
or die("Verbindung zu MySQL gescheitert!");
mysqli_set_charset($db, "utf8");
@mysqli_select_db($db, "teamz")
or die("Datenbankzugriff gescheitert!");

Je nach Problem bekommst du nun entweder die Meldung Verbindung zu
MySQL gescheitert oder Datenbankzugriff gescheitert zu sehen. Probiere es
aus, indem du mal das Passwort in der ersten und dann den Tabellennamen
in der dritten Zeile flschst. Ab jetzt werden wir diese beiden Tricks ganz
selbstverstndlich in unsere Datenbankabfrage hineinpacken. Vergleiche
mit der Datei zeige_adressen3.php, wo du beide Tricks im Einsatz fin-
dest.
Und noch einen Trick gibt es: Funktionen wie mysqli_connect() und
mysqli_select_db() geben je nach Erfolg oder Misserfolg entweder
true oder false zurck. Du kannst also auch mit einer if-Abfrage ar-
beiten. Das zeige ich dir ganz am Schluss des Kapitels, und zwar bei der
Eingabe von Datenstzen. Denn gerade dann ist es ntzlich zu wissen, ob
die Abfrage berhaupt funktioniert hat.
Ausgabe aller Datenstze in einer Tabelle
Aber ich hatte dir ja eine Tabelle versprochen. Auerdem sollen im Beispiel
die Felder von allen Datenstzen eingeblendet werden, und nicht nur der
Vorname, der Name und der Ort.
Geht das? Na klar! Dabei hilft uns wieder die schon bekannte while-
Schleife in Zusammenarbeit mit einer zustzlichen foreach-Schleifen-
konstruktion.

Schau dir das Beispiel an, vielleicht verstehst du es ja schon beim Lesen.
Wenn du keine Lust zum Abschreiben hast du findest den Quellcode auch
in der Datei zeige_adressen4.php.
Gib deine Datenbankta-
belle aus und zwar als
HTML-Tabelle!
326
Ein Adressbuch fr dein Team

Kapitel
13

<h3>Adressen anzeigen</h3>
<div>
<?php
$db = @mysqli_connect("localhost", "root", "")
or die("Verbindung zu MySQL gescheitert!");
mysqli_set_charset($db, "utf8");
@mysqli_select_db($db, "team")
or die("Datenbankzugriff gescheitert!");
$sql = "SELECT * FROM adressen";
$result = mysqli_query($db, $sql);
$zeilen = mysqli_num_rows($result);
echo "<p>$zeilen Eintrge:</p>\n";
// Tabelle definieren:
echo "<table border='1' cellspacing='0'>\n";
// Kopfzeile der Tabelle anlegen:
echo "<tr><th>id</th><th>Vorname</th>" .
"<th>Name</th><th>Str</th><th>PLZ</th>" .
"<th>Ort</th><th>Tel</th><th>EMail</th>" .
"<th>WWW</th><th>Notizen</th></tr>\n";
// while-Schleife Anfang
while ($row = mysqli_fetch_assoc($result)) {
echo "<tr>"; // Zeile erzeugen
// foreach Anfang:
foreach ($row as $key => $value) {
echo "<td>$value&nbsp;</td>\n";
} // foreach Ende
echo "</tr>"; // Zeile schlieen
} // while Ende
echo "</table>\n"; // Tabelle schlieen
mysqli_close($db);
?>
</div>
Der Quellcode kurz erklrt
Blickst du durch? Als kleine Lesehilfe habe ich einige Kommentare einge-
fgt: Zuerst erzeuge ich die Elemente fr die HTML-Tabelle: Ich definiere
die Tabelle und lege die Kopfzeile an. Die Spaltenkpfe werden in
<th></th> eingekleidet. Sie erscheinen dadurch fett. Sinnigerweise ver-
wende ich als Beschriftung die Feldnamen. Das dient der Wiedererkennung.
327
Mit PHP: Eingabeformular selbst gestrickt

Das eigentlich Interessante findet jedoch innerhalb der while-Schleife
statt. Als erstes wird mit echo "<tr>"; die Zeile erzeugt, vergleiche mit
meinem Kommentar.
Danach folgt eine foreach-Schleife, also eine Schleife in einer Schleife.
Foreach durchluft das gesamte Array, also alle Datenfelder der jeweiligen
Zeile. Ausgegeben wird der $value, also der Inhalt des jeweiligen Daten-
feldes. Diesen kleide ich kunstvoll in eine Tabellenzelle <td></td> ein:
echo "<td>$value&nbsp;</td>";

Wozu dient das Zeichen &nbsp;? Das ist ein non breaking space, ein ge-
schtztes Leerzeichen. Mit diesem Trick sichere ich zu, dass auch leere
Zellen zumindest mit einem Leerzeichen ausgefllt werden! Denn vllig
leere Zellen erscheinen in Browser irgendwie als Fehlstellen das wrde
den optischen Gesamteindruck der Tabelle doch arg beeintrchtigen.
Auerhalb von foreach, aber noch innerhalb von while schliee ich die
Tabellenzeile mit </tr> ab. Unterhalb der Schleife wird auch die Tabelle
selbst mit </table> geschlossen.
Du wunderst dich, warum in den meisten Beispielen anderer Bcher oder
Skripte immer nur die Funktion mysqli_fetch_array() verwendet
wird, hier jedoch nicht? Da wundere ich mich aber auch, denn ich finde
die Funktion mysqli_fetch_array() nicht so ideal. Sptestens in die-
sem Fall sind wir zwingend auf mysqli_fetch_assoc() oder auf
mysqli_fetch_row() angewiesen! Probiere es aus: Beim Einsatz von
mysqli_fetch_array() wird die Tabelle vllig schief und krumm aus-
sehen, da mysqli_fetch_array() schlielich zwei Arrays gleichzeitig
erzeugt. Und so ein Doppelarray lsst sich halt schlecht auswerten,
denn foreach() wrde hier alles doppelt zhlen.
Mit PHP: Eingabeformular selbst
gestrickt
Doch nun zur Dateneingabe selbst. Auch die erfolgt natrlich wieder mit
SQL. Zum einen bentigst du ein Eingabeformular. Dieses schickt die Daten
im Beispiel an sich selbst. Ich habe es dir auf der nchsten Seite abgebildet.
328
Ein Adressbuch fr dein Team

Kapitel
13


Mit dieser selbst gestrickten Maske werden neue Adressen eingegeben.
Im PHP-Teil musst du die Dateneingabe mit folgender SQL-Anweisung
durchfhren:
INSERT INTO adressen () VALUES ()

Erinnerst du dich? Wir hatten diesen Befehl ganz am Anfang schon einmal
trainiert! Dabei werden im ersten runden Klammernpaar die Feldnamen
notiert, nur durch ein Komma getrennt. Im zweiten Klammernpaar mssen
die entsprechenden Werte eingetragen werden. Diese notierst du in einfa-
chen Gnsefchen. Beachte auerdem auf jeden Fall die richtige Reihen-
folge.
Der Quelltext im berblick
Im Endeffekt sieht das Skript folgendermaen aus. Es ist lediglich eine rei-
ne Abschreib-Fleiarbeit. Eine kleine Besonderheit steckt in der zweiten
if-Abfrage, die wir danach besprechen:
<h3>Adressen eingeben</h3>
<form action="eingabe_adressen.php" method="post">
Vorname: <input type="text" name="Vorname"><br>
Name: <input type="text" name="Name"><br>
Str: <input type="text" name="Str"><br>
PLZ: <input type="text" name="PLZ"><br>
329
Mit PHP: Eingabeformular selbst gestrickt

Ort: <input type="text" name="Ort"><br>
Tel: <input type="text" name="Tel"><br>
E-Mail: <input type="text" name="EMail"><br>
Webadresse: <input type="text" name="WWW"><br><br>
Notizen:<br>
<textarea cols="60" rows="4" name="Notizen">
</textarea><br>
<input type="submit" value="Daten eintragen"
name="submit">
</form>
<?php
if (!empty($_POST["submit"])) {
$db = @mysqli_connect("localhost", "root", "")
or die("Verbindung zu MySQL gescheitert");
mysqli_set_charset($db, "utf8");
@mysqli_select_db($db, "team")
or die("Datenbankzugriff gescheitert!");
$sql="INSERT INTO adressen " .
"(id, Vorname, Name, Str, PLZ, Ort, Tel, EMail, " .
"WWW, Notizen) VALUES ('', '$_POST[Vorname]', " .
"'$_POST[Name]', '$_POST[Str]', '$_POST[PLZ]', " .
"'$_POST[Ort]', '$_POST[Tel]', '$_POST[EMail]', " .
"'$_POST[WWW]', '$_POST[Notizen]')";
if (mysqli_query($db, $sql)) {
echo "<p>Abfrage erfolgreich!</p>";
} else {
echo "<p>Abfrage nicht erfolgreich!</p>";
}
mysqli_close($db);
}
?>

Eigentlich ist das Skript nicht schwer zu durchschauen. Du verbindest ein
HTML-Formular mit einem PHP-Teil. Das HTML-Formular schickt die Daten
per POST an sich selber. Der PHP-Teil wird aktiv, wenn die Variable
$_POST["submit"] nicht leer ist (also wenn der Submit-Button angeklickt
wurde). Dafr sorgt die dir schon bekannte Technik mit einer alles umspan-
nenden if-Abfrage.
Wir verwenden die schon besprochene Funktion empty(). Diese prft
schlielich, ob der Wert der Variablen nicht gesetzt ist, leer ist oder 0 ent-
spricht. Dann gibt diese Funktion true zurck. Da wir in der if-Abfrage
aber das Gegenteil auslesen mchten, stellen wir der Funktion den Opera-
tor ! voran.
330
Ein Adressbuch fr dein Team

Kapitel
13
Im Klartext: Nur bei gesetzter Variable empty($_POST["submit"])
also wenn die Variable nicht leer ist wird der Code der if-Abfrage ausge-
fhrt. So weit, so gut.
Und der SQL-Teil? Den hatten wir vom Prinzip her schon mehrfach bespro-
chen. Beachte, dass der SQL-Code fr die Variable $sql diesmal ziemlich
lang wird. Das geht los mit INSERT INTO adressen ... und setzt sich
ber mehrere Zeilen fort. Ich teile diesen Code daher auf mehrere Zeilen
auf und nutze dabei den Verkettungsoperator Punkt (.).
Wunderst du dich ber die if-Abfrage im letzten Teil des Skriptes? Also
ber die Zeile if (mysqli_query($db, $sql)) {? Damit teste ich,
ob die Abfrage an die Datenbank korrekt war. Nur dann kann ich davon
ausgehen, dass die Daten vermutlich richtig eingetragen wurden.
Vermutlich bedeutet: Ich kann damit nicht feststellen, ob beim Eintragen
der Daten auch wirklich alles geklappt hat. Das gelingt erst mit der
Funktion mysqli_affected_rows(). Die besprechen wir im nchsten
Kapitel. Wir mssen uns ja schlielich noch eine Steigerungsmglichkeit
offen lassen! Wenn du neugierig bist blttere zur Seite 348.
Du findest den Code auch auf der CD, und zwar in der Datei eingabe_
adressen.php.
Verbinde beide Seiten mit einem Hyperlink
Verbinde am Schluss beide Seiten mit einem Hyperlink. Meine beiden ferti-
gen Hauptseiten heien:
0 zeige_adressen.php (Darstellung der Adresstabelle)
0 eingabe_adressen.php (Formular zur Eingabe der Daten)
Auf der Formularseite baust du in diesem Fall folgenden Link ein:
<p><a href="zeige_adressen.php">Adressen anzeigen</a></p>

Auf der Tabellenseite wiederum steht
<p><a href="eingabe_adressen.php">Adressen eingeben</a></p>

Was ist noch nicht perfekt?
Kurz: eine ganze Menge! Unser Skript hat noch mehrere erhebliche Mngel
und Schnheitsfehler!
331
Mit PHP: Eingabeformular selbst gestrickt

Probleme mit Gnsefchen
Zum einen gibt es Probleme mit dem einfachen Gnsefchen. Probiere
doch einmal das Eintragen eines Namens wie O'Hara. Zumindest auf unse-
rem lokalen Webserver klappt es nicht! Auch bei vielen Dienstleistern gibt
es Schwierigkeiten. Warum? Schon die entsprechende Array-Variable wird
von einfachen Gnsefchen umhllt: '$_POST[Name]'. Und ein weiteres
einfaches Gnsefchen bringt den SQL-Code durcheinander. Diese Gnse-
fchen kommen sich gegenseitig ins Gehege.
Fazit: Wir mssten die eventuell strenden Gnsefchen noch entwerten,
also einen Backslash davorsetzen.
Das ist nur die halbe Wahrheit. Bei manchen Dienstleistern werden die
Gnsefchen automatisch entwertet, dank der magic quotes. Das Pro-
blem: Du kannst (und solltest) dich nicht darauf verlassen!
Dieses Kuddelmuddel gehen wir im nchsten Kapitel auf Seite 351 an! Dort
stelle ich dir die Funktion mysqli_real_escape_string() vor und ver-
rate dir mehr zu den Vor- und Nachteilen der magic quotes.
Werte werden nicht berprft
Ein weiteres Problem: Die Werte aus den Formularfeldern werden nicht
getestet. Fr den Praxiseinsatz solltest du umfangreiche Prfroutinen in
das Formular einbauen. Nutze dafr beispielsweise die regulren Ausdr-
cke, prfe auf korrekten Aufbau der E-Mail-Adresse, auf Mindestlnge usw.
Wenn du dieses Formular ungeschtzt im Web einsetzt, musst du die
Formularfelder unbedingt berprfen! Sonst ist deine Datenbanktabelle
schneller zugespammt, als dir lieb ist. Wurden alle wichtigen Felder aus-
gefllt? Handelt es sich bei der E-Mail-Adresse um eine gltige E-Mail-
Adresse? Wurde bei bestimmten Feldern eine Mindest-Zeichenlnge er-
reicht? Weiterhin bentigst du im Skript auch eine Funktion namens
mysqli_real_escape_string(), um das Hacken deiner Datenbank zu
unterbinden. Ihre Wirkungsweise lernst du im nchsten Kapitel kennen.
Auerdem solltest du gegebenenfalls die Ausgabe von HTML-Zeichen
entschrfen. Dazu steht dir die Funktion htmlspecialchars() zur Ver-
fgung. Das ist vor allem dann ntig, wenn du vermutest, dass jemand
bswilligen Quellcode in deine Datenbanktabelle schummeln wird!
Doch ich bitte um Geduld! An dieser Stelle verkneife ich mir jedoch diesen
ganzen Aufwand. Schlielich ist das Formular nur als Lehrbeispiel gedacht
zum Warmwerden. Es soll in dieser Form ja auch gar nicht im Web einge-
332
Ein Adressbuch fr dein Team

Kapitel
13
setzt werden! Und wenn, dann hchstens mit Passwortschutz und damit
fr ausgewhlte Nutzer. Bei den Praxisbeispielen der nchsten Kapitel ach-
ten wir jedoch verstrkt auf Sicherheit!
Schlussbemerkung
Uff. Was fr ein Kapitel! Datenbanking ist wohl doch nicht so einfach wie
vermutet. Aber du hast es geschafft Du kennst dich mit SQL aus! Mit
diesem Kapitel hast du die Grundlagen fr dynamisches Webdesign erwor-
ben. Und dafr hat sich die harte Arbeit gelohnt, oder?
Zusammenfassung
0 Du weit, dass du eine Datenbank vor dem Anlegen planen musst. Du
bentigst den Namen der Datenbank, der bergeordneten Hlle. Am
wichtigsten ist jedoch der Name der Datenbanktabelle. Denke dir au-
erdem die Feldnamen aus und vergiss nicht das Schlsselfeld (Primr-
schlssel) fr die eindeutige Identifizierung eines jeden Datensatzes.
0 Du kennst das Tool phpMyAdmin, eine Art grafische Oberflche fr
MySQL. Damit kannst du Datenbanken und Datenbanktabellen anlegen,
SQL-Anfragen starten, Daten eintragen, ausgeben und lschen und vie-
les andere mehr.
0 Du kennst den grundlegenden SQL-Befehl zum Anlegen einer Daten-
banktabelle, und zwar CREATE TABLE Tabellenname ().
0 Du kennst wichtige Datentypen, z. B. VARCHAR fr variable Zeichenfol-
gen bis 255 Zeichen Lnge, TEXT fr Passagen mit einer Lnge von bis
65.535 Zeichen und INT fr Ganzzahlen bis zu vier Milliarden.
0 Du kennst den Befehl zum Eintragen von Datenstzen in eine Tabelle,
und zwar INSERT INTO adressen () VALUES (). Im ersten runden
Klammernpaar trgst du die Feldnamen, im zweiten Klammernpaar die
Werte ein, jeweils durch ein Komma getrennt. Die Werte mssen auer-
dem in Hochkommata gesetzt und in der richtigen Reihenfolge notiert
werden.
0 Du kennst die diversen SQL-Befehle zur Ausgabe von Daten. Du weit,
dass SELECT * FROM tabelle alle Datenstze auswhlt und dass du
statt des Sternchens auch die einzelnen Felder angeben kannst. Du ver-
wendest WHERE zum Filtern von Daten, ORDER BY zum Sortieren,
UPDATE zum Ergnzen und DELETE zum Lschen von Werten.
333
Ein paar Fragen

0 Du kennst die Grundfunktion fr den Verbindungsaufbau mit der Da-
tenbank wie mysqli_connect() und die Funktion fr die Auswahl der
Datenbank mysqli_select_db().
0 Du kennst die Funktion zum Festlegen des Standardzeichensatzes fr
die Verbindung: mysqli_set_charset().
0 Du speicherst das Ergebnis von mysqli_query() in einer Variablen
$result und erhltst damit die sogenannte Ergebnisliste. Hier sind die
einzelnen Datenstze zeilenweise gespeichert.
0 Mit mysqli_num_rows($result) kannst du die Zahl der Zeilen eines
Ergebnisses zhlen.
0 Die Funktion mysqli_fetch_assoc($result) geht diese Ergebnis-
liste Zeile fr Zeile durch und gibt jede Datenbankzeile als assoziatives
Array zurck. Dieses Array legst du in einer selbst festzulegenden Vari-
able ab, fange es z. B. auf mit $row = mysqli_fetch_assoc
($result). Fr den Zeilenvorschub arbeitest du mit einer while-
Schleife.
0 Jeder einzelne Wert lsst sich nun nach dem Schema $row[Feldname]
ermitteln.
0 Du kennst auch die Funktion mysqli_fetch_row($result) fr die
Ausgabe eines indizierten Arrays und die problematische Funktion
mysqli_fetch_array($result), die sowohl ein assoziatives als
auch ein indiziertes Array gleichzeitig erzeugt.
0 Du kennst Techniken zum Abfangen von Fehlermeldungen. Notiere ei-
nen Klammeraffen vor der entsprechenden Funktion. Gib durch die An-
weisung or die() im Misserfolgsfalle eine Meldung aus. Oder nutze
einfach eine klassische if-Abfrage fr die Darstellung von Erfolg oder
Misserfolg.
0 Du weit, wie du eine Eingabeseite zum Eintragen von Daten in die
Datenbank programmierst. Du verbindest ein HTML-Formular mit dem
entsprechenden PHP-Abschnitt. Dort greifst du auf den SQL-Code
INSERT INTO adressen () VALUES () zurck.
Ein paar Fragen
1. Wozu bentigst du einen Primrschlssel und wie lautet der Befehl zum
Festlegen dieses Schlssels?
2. Mit welchem Befehl sicherst du zu, dass ein Feld automatisch hoch-
zhlt?
334
Ein Adressbuch fr dein Team

Kapitel
13
3. Angenommen du lschst einen Datensatz komplett mit DELETE. Ange-
nommen, dieser Datensatz besitzt den Primrschlssel 8. Wo die Zahl 8
doch nun frei geworden ist, wird sie fr den nchsten Datensatz wie-
der vergeben werden? Und wenn nicht, warum nicht?
4. Mit welchem SQL-Befehl fragst du alle Datenstze der Tabelle
adressen ab?
5. Welcher Datentyp speichert das Datum im Format YYYY-MM-DD, also
Jahr vierstellig, Monat zweistellig und Tag zweistellig?
6. In welchem Unterordner auf deiner lokalen Festplatte legt MySQL seine
Daten ab?
7. Wie lautet der Befehl zur Verbindung mit einer Datenbank? Welche
Argumente bentigst du?
8. Welche Techniken kennst du zur Unterdrckung von Fehlermeldungen
bei Funktionen?
und ein paar Aufgaben
1. Bearbeite die HTML-Datei zur Ausgabe der Adressen so, dass die Daten-
stze nach Namen geordnet ausgegeben werden.
2. Bearbeite die Datei zur Eingabe der Daten. Passe das HTML-Formular so
an, dass die Lnge der Felder dem Datentyp der Datenbanktabelle
adressen entspricht. Im Klartext: Wenn ein Feld den Datentyp
VARCHAR(20) besitzt, darf das entsprechende Feld im Eingabeformular
auch nicht mehr als 20 Zeichen zulassen! (Tipp: Dafr bentigst du gute
HTML-Kenntnisse. Du musst zumindest wissen, wie du in einem Formu-
larfeld die maximale Lnge erzwingst.)
3. Fr Profis: Baue die Seite zur Eingabe der Adressen weiterhin so um,
dass man nur bei Kenntnis des folgenden Passwortes ?zk63Xxd Daten
eingeben kann. Sorge auerdem dafr, dass der Nutzer bei Unkenntnis
des Passworts darber informiert wird.
4. Fr Profis: Erstelle ein drittes Dokument, mit welchem du einzelne Da-
tenstze bearbeiten, updaten kannst. Dabei sollen alle Datenfelder auf
einen Schlag berarbeitet werden. Erkenne die Datenstze anhand ihrer
id. Nenne das Dokument update_adressen.php und verlinke es mit
den anderen beiden Seiten.
335



14
Gstebuch de luxe als
Datenbanktabelle
Wie wrs mal mit einem richtigen Gstebuch? Kein Problem mit MySQL!
Schritt fr Schritt baust du dein Gstebuch de luxe zusammen. In diesem
Kapitel zeige ich dir, wie du
$ die Gstebuch-Tabelle planst und Gstebuchdaten mit PHP ausgibst
$ nur vier Datenstze zugleich und die neusten Eintrge zuoberst anzeigst
$ ein Eingabeformular fr die Daten schreibst
$ Doppeleingaben zuverlssig verhinderst diesmal auf Datenbankebene
$ Gstebuchspammer durch ein CAPTCHA (Rechenaufgabe) ausschliet
$ eine Mglichkeit zum Freischalten der Eintrge vorbereitest
Einiges davon kommt dir sicher bekannt vor. Wenn nicht, blttere zum Ka-
pitel 12, zu unserer Nur-PHP-Gstebuchversion. Auch aus dem Kapitel 8
(Feedbackformular) werden wir einiges bernehmen. Vieles jedoch ist neu,
z. B. die Blttermglichkeit mit Begrenzung der Anzeige auf vier Datenst-
ze. Es muss schlielich Vorteile besitzen, mit einer Datenbank zu arbeiten!
Wie bei den meisten groen Projekten gilt auch hier: Wir fangen be-
scheiden an. Du baust das Skript Schritt fr Schritt zusammen, die ent-
sprechenden Verbesserungen folgen erst, wenn du das Prinzip verstanden
hast. Du findest den aktuellen Stand stets auch auf der CD zum Buch.
336
Gstebuch de luxe als Datenbanktabelle

Kapitel
14 Datenbanktabelle planen
Es geht langweilig und profan los. Du planst die Datenbanktabelle fr dein
Gstebuch. Wie viele Spalten soll die Tabelle besitzen? Welche Feldnamen
brauchst du und wie nennst du diese? Welche Felddatentypen wren ideal?
Feldnamen und Felddatentypen festlegen
Hier mein Vorschlag:
Feldname id Name Home Datum Kommentar Zeigen
Felddatentyp INT (Primr-
schlssel)
VARCHAR(35) VARCHAR(50) VARCHAR(30) TEXT TINYINT

Die meisten Felder erschlieen sich sofort. Besonders wichtig ist natrlich
der Primrschlssel, die automatisch erzeugte eindeutige Kennung. Dafr
sehe ich wieder ein Feld namens id vor. Im Feld Name gibt die oder der
Eintragende seinen Namen ein. Das kann der Vorname, Nachname, beides
oder einfach nur der Spitzname sein. Dafr sollten 35 Zeichen ausreichen.
Im Feld Home mchte ich auf freiwilliger Basis die Webadresse oder aber
die E-Mail-Adresse des Eintragenden sichern. Hierfr sind 50 Zeichen si-
cher ausreichend. Das Datum soll als komplettes Datum nebst Uhrzeit ge-
speichert werden. Mit 30 Zeichen kommt man gut ber die Runden. Fr
den eigentlichen Eintrag (Feld Kommentar) biete ich mit dem Felddatentyp
TEXT wieder reichlich Platz an, und zwar 65.535 Zeichen.
Warum nehme ich fr das Feld Datum den Felddatentyp VARCHAR() und
nicht DATE? Weil ich mit DATE auf das Zwangsformat des Felddatentyps
angewiesen wre, auf das Format YYYY-MM-DD (Jahr-Monat-Tag). Das
gefllt mir aber nicht! Ich erzeuge das Format lieber selber, und zwar als
Tag-Monat-Jahr, Stunde:Minute. Dafr werde ich die PHP-Funktion
date() mit den entsprechenden Formatierschaltern verwenden.
Das Feld Zeigen bestimmt, ob der Eintrag angezeigt werden soll oder
nicht. Nur wenn hier eine 1 steht, soll der Eintrag sichtbar sein der Feld-
datentyp TINYINT (sehr kleine Ganzzahl) ist dafr bestens geeignet. Immer-
hin reicht der Wertebereich von -128 bis 127 und der Speicherplatzbedarf
ist mit 1 Byte minimal.
Du bestimmst im Skript, ob ein Gstebucheintrag sofort oder erst nach
Begutachtung und Freischaltung durch dich angezeigt werden soll!
337
Datenbanktabelle planen

SQL-Befehle zum Einrichten der Tabelle
Nun setzt du das Ganze wieder in SQL um! Zuerst erstellst du die Grund-
struktur fr diese Datenbanktabelle. berlege dir einen Namen fr die Ta-
belle wie wre es mit guestbook? Der Einfachheit halber legst du diese
Tabelle in unserer im vorigen Kapitel erzeugten Datenbank team ab. Bei
vielen Dienstleistern darfst du sowieso nur eine einzige Datenbank verwen-
den. Doch nun zum Erstellen der Datenbanktabelle guestbook. Starte
phpMyAdmin, ffne deine Datenbank team und gib den entsprechenden
Code in das Eingabe-Feld ein. Trage im Beispiel also Folgendes ein und
klicke auf OK:
CREATE TABLE guestbook (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Name VARCHAR(35),
Home VARCHAR(50),
Datum VARCHAR(30),
Kommentar TEXT,
Zeigen TINYINT
) DEFAULT CHARACTER SET utf8;
Erstelle einige Testeintrge!
Die Datenbank ist fertig. Nun trgst du mit Hilfe von phpMyAdmin schon
ein paar Testeintrge ein. Das knnen ruhig Flschungen sein, wir brau-
chen diese Eintrge nur fr bungszwecke. Wie du die Eingabemaske auf-
rufst, hast du dir gemerkt? Klicke in phpMyAdmin auf EINFGEN, dann er-
scheint die Datenmaske. Denke dir nun ein paar Eintrge aus.
Im Feld Datum trgst du das Datum im folgenden Stil ein:
0 18.04.2010, 12:11 Uhr
Im Feld Kommentar kannst den Text ruhig durch Druck auf [Enter] glie-
dern. Du musst also nicht alles hintereinander schreiben.
Du wunderst dich, warum das Eingabefeld fr den Kommentar in
phpMyAdmin so klein ist? Schreibe einfach los! Drcke auf [Enter] du
wirst sehen, wie es mglicherweise mitwchst. Dieses gewhnungsbe-
drftige, sich selbst in der Hhe verndernde Texteingabefeld findest du
zum Glck nur bei lteren Versionen von phpMyAdmin.
Im Feld Zeigen notierst du brigens schon einmal eine 1. Sonst kann der
Eintrag ja gar nicht angezeigt werden!
338
Gstebuch de luxe als Datenbanktabelle

Kapitel
14

Trage ein paar Daten in die Tabelle guestbook ein. Das Kommentarfeld wchst mit!
Daten erst einmal ausgeben
Die MySQL-Tabelle steht. Nun bauen wir Schritt fr Schritt das dazugeh-
rige Gstebuch zusammen. Ich habe mir fr das Gstebuch den Dateina-
men guestbook.php ausgedacht.
Ehe wir uns ber das Eingabeformular hermachen, sollen die Eintrge erst
einmal ausgegeben werden. Im Beispiel also das, was du eben in die Daten-
banktabelle guestbook geschrieben hast. Du hast doch schon ein paar
Testeintrge eingegeben, oder?
Gerade bei komplexen Projekten wie diesem Gstebuch empfehle ich dir
unbedingt die hier von mir verwendete Modulbauweise! Fange klein
an. Setze zuerst einen Teilabschnitt deines Projekts um. Prfe, ob es
klappt. Erweitere das Projekt um das nchste Modul. Arbeite dabei
wenn es sein muss ruhig mit Platzhaltertext. Fge die entsprechenden
Elemente erst nach und nach ein. Teste regelmig, und zwar gleich
nach dem Einbau eines neuen Moduls. Auf diese Weise entsteht das
groe Projekt Schritt fr Schritt und du kannst deine Fehler leichter
entdecken! Ganz wichtig bei der Geschichte mache von jedem Bearbei-
tungsschritt eine Sicherheitskopie. So ist bei einem Fehler nicht gleich
alles verloren. Du kannst problemlos zur vorherigen Entwicklungsstufe
zurckkehren.
339
Daten erst einmal ausgeben

Der Ausgabe-Quellcode
Modulbauweise, einverstanden! Der erste Schritt besteht in nichts weiter
als der Ausgabe der Daten. Hier zeige ich dir den kompletten Abschnitt
zwischen den Tags <body></body>. Du findest diesen Quelltext komplett
auf der CD zum Buch, und zwar in der Datei guestbook1.php. Schaue in
den Ordner kapitel14, Unterordner guestbook.
<div style="width: 600px">
<h1>Gstebuch auf Datenbankbasis</h1>
<?php
$db = @mysqli_connect("localhost", "root", "")
or die("Verbindung zu MySQL gescheitert!");
mysqli_set_charset($db, "utf8");
@mysqli_select_db($db, "team")
or die("Datenbankzugriff gescheitert!");
$sql1 = "SELECT * FROM guestbook WHERE Zeigen = 1";
$sql2 = "SELECT * FROM guestbook WHERE Zeigen = 1 ORDER BY
id DESC LIMIT 0, 4";
$result1 = mysqli_query($db, $sql1);
$zeilen = mysqli_num_rows($result1);
$result2 = mysqli_query($db, $sql2);
echo "<h2>Bisherige Eintrge:</h2>";
echo "<p>Anzahl der Eintrge: $zeilen</p>\n";
// while-Schleife Anfang
while ($row = mysqli_fetch_assoc($result2)) {
echo "<p><strong>1.</strong> <b>"
. htmlspecialchars($row["Name"]) . "</b> ";
if (!empty($row["Home"])) {
echo "(" . htmlspecialchars($row["Home"]) . ")";
}
echo "<br>--&gt; schrieb am " .
"<strong>" . $row["Datum"] . "</strong>:</p>" .
"<p>" . nl2br(htmlspecialchars($row["Kommentar"])) .
"</p><hr>\n";
} // while Ende
mysqli_close($db);
?>
</div>

Probiere es aus. Werden deine bisher notierten Datenstze angezeigt?
Nein? Vergiss nicht, dass du die Zugriffsdaten ggf. an deine Bedrfnisse
anpassen musst! Die 1 im Feld Zeigen hattest du notiert?
340
Gstebuch de luxe als Datenbanktabelle

Kapitel
14

Nach jedem Datensatz wird mit <hr> eine Linie erzeugt.
Sieh wohlwollend darber hinweg, dass mit dieser Version des Skriptes nur
hchstens vier Datenstze angezeigt werden knnen und jeder Datensatz
ein 1. vorangestellt bekommt.
Kleiner Layout-Trick: Auch bei diesem Gstebuch legt der Autor die Brei-
te der Seite mit einem DIV-Container fest. Dafr sorgt das Tag <div
style="width: 600px"> direkt unter dem Tag <body>. Dieses Tag
wird ber dem ausschaltendem </body> mit </div> wieder ausge-
schaltet. Aber das ist nur eine Empfehlung. Ob du deine Seite lieber mit
einer Tabelle in Form hltst oder auf eine exakte Breite ganz verzich-
test, bleibt dir berlassen!
Besonderheiten des Skriptes
Die ersten beiden eigentlichen PHP-Zeilen stellen nichts Besonderes dar.
Damit wird zum einen die Verbindung zu MySQL und zum zweiten die Ver-
bindung zur Datenbank team aufgebaut. Dabei kommen die schon erwhn-
ten bewhrten Tricks zur Unterdrckung von Fehlermeldungen zum Einsatz.
Darunter folgen merkwrdigerweise zwei Zeilen mit zwei unterschiedlichen
SQL-Abfragen. Die Zeile $sql1 = "SELECT * FROM guestbook WHERE
Zeigen = 1"; ermittelt alle freigeschalteten Datenstze der Tabelle, also
alle Eintrge, bei denen im Feld Zeigen eine 1 notiert wurde. Diese Be-
341
Daten erst einmal ausgeben

schrnkung erreichen wir mit der WHERE-Klausel WHERE Zeigen = 1.
Wir bentigen diese Abfrage fr unsere Variable $zeilen, also fr die
Ausgabe der Gesamtzahl der (anzuzeigenden) Eintrge.
Die zweite, lngere Zeile $sql2 = "SELECT * FROM guestbook WHERE
Zeigen = 1 ORDER BY id DESC LIMIT 0, 4"; dient lediglich fr die
Anzeige der freigeschalteten Daten. Dabei soll zum einen absteigend nach
dem Feld id sortiert werden. Das gelingt mit ORDER BY id DESC und auf
diese Weise stehen die neuesten Eintrge zuoberst. Zum anderen wird die
Ausgabe mit dem SQL-Befehl LIMIT 0, 4 (vorerst) auf die ersten vier Ein-
trge limitiert. (Wir werden diese Werte spter dynamisch anpassen fr
eine seitenweise Ausgabe der Daten!)
Den Rest haben wir vom Prinzip her schon besprochen, doch vielleicht
wunderst du dich ber die Passage <p><strong>1.</strong>? Wird
doch dadurch jedem Eintrag ein fett formatiertes 1. vorangestellt? Auch
das dient vorerst nur als Platzhalter. In einem spteren Projektstadium soll
diese Zahl mit einer Variablen natrlich dynamisch ermittelt werden!
Erinnerst du dich noch an das erste Gstebuch von Kapitel 12? Auch im
neuen Gstebuch arbeite ich bei der Ausgabe der Daten zum Schutz vor
Scherzbolden mit der Funktion htmlspecialchars(). Diese Funktion
sorgt dafr, dass spezielle HTML-Zeichen in ihre entsprechenden Entit-
ten umgewandelt und somit entschrft werden. Wichtig, damit dir nie-
mand HTML-Code, CSS-Anweisungen oder sogar JavaScript-Code in dein
Gstebuch schummelt!
Das Kommentarfeld wird zustzlich mit der Funktion nl2br() verschnt.
Diese ebenfalls schon besprochene Funktion sorgt dafr, dass Umbrche
auch im Browser angezeigt werden. (Deshalb hatte ich dich gebeten, beim
Eintragen der Daten ruhig mal den einen oder anderen Druck auf [Enter]
zu wagen!)
Homepage-Feld soll freiwillig sein?
Das Feld fr die Homepage soll freiwillig sein. Darauf muss ich im Ausgabe-
skript natrlich reagieren. Das gelingt mit folgender if-Abfrage:
if (!empty($row["Home"])) {
echo "(" . htmlspecialchars($row["Home"]) . ")";
}

Nur wenn das Feld nicht leer ist, wird die Internetadresse angezeigt!
342
Gstebuch de luxe als Datenbanktabelle

Kapitel
14
Wichtig: Datenbank-Zugangsdaten auslagern!
Mehr Sicherheit, bitte! Ich rate dir: Lagere deine Zugangsdaten fr die Da-
tenbank einfach aus. Nutze dafr die schon bekannte Funktion include().
Das ist bequemer, da du auf diese Weise Benutzernamen und Passwort an
zentraler Stelle speicherst und nur einmal schreiben musst. Auf der nchs-
ten Seite zeige ich dir, wie das geht:
>
Erstelle eine leere Textdatei, die du zugriff.inc.php nennst. Fge
folgendes Listing in diese Datei ein:
<?php
$db = @mysqli_connect("localhost", "root", "")
or die("Verbindung zu MySQL gescheitert!");
mysqli_set_charset($db, "utf8");
@mysqli_select_db($db, "team")
or die("Datenbankzugriff gescheitert!");
?>


>
Speichere diese Datei im gleichen Ordner wie die guestbook.php.
Du musst sie spter mit auf den Webserver laden!
>
So, und nun zur guestbook.php! Binde hier den eben ausgelagerten
Code ein. Lsche dazu die drei Zeilen von @mysqli_connect ...
bis @mysqli_select_db ... im Quelltext der guestbook.php.
Trage an der entsprechenden Stelle einfach die folgende Anweisung
ein: include("zugriff.inc.php");
>
Teste die Ausgabe im Browser. Es drfte sich nichts gendert haben.
Vergleiche mit der Datei guestbook2.php!
Du musst die zugriff.inc.php nicht im gleichen Ordner ablegen. Packe
sie z. B. in den Ordner cgi-bin (bei manchen Dienstleistern gibt es diesen),
da dieser oft von Hause aus geschtzt ist!
Du kannst diese Datei auch in einen separaten Unterordner legen, den du
mit der auf Seite 154 erwhnten .htaccess-Datei geschtzt hast. Es
gengt, wenn diese .htaccess-Datei folgende beiden Zeilen enthlt:
order deny,allow
deny from all
Gib bei include() lediglich den Pfad zu diesem Ordner an. Von auen
jedoch ist der Inhalt dieses Ordners nicht zugnglich. Prfe, ob diese
.htaccess-Lsung auch bei deinem Webhoster funktioniert!
343
Das Eingabeformular entsteht

Das Eingabeformular entsteht
Hast du die Funktion des Skripts erfolgreich getestet? Mit ausgelagerten
Zugangsdaten? Sehr gut! Dann schreibst du nun das Eingabeformular. Da-
bei achten wir auf verstndlichen Code, Sicherheit und das vor allem im
nchsten Kapitel Spamschutz.
Quelltext fr das Formular
Erweitere die guestbook.php zunchst um den HTML-Code fr das For-
mular. Notiere die entsprechenden Zeilen fr das Formular unterhalb der
Passage <h1>Gstebuch auf Datenbankbasis</h1> und oberhalb des
einleitenden Tags <?php.
Mein Formularvorschlag sieht folgendermaen aus, die dazu passende Ab-
bildung zeige ich dir auf der nchsten Seite.
<form action="guestbook.php" method="post">
Dein <strong>Name</strong>:<br>
<input type="text" name="Name"><br>
Homepage (freiwillig):<br>
<input type="text" name="Home"><br>
Deine <b>Botschaft</b>:<br>
<textarea cols="65" rows="5" name="Kommentar">
</textarea><br>
Ziehe vom Jahr (YYYY) den Tag (TT) ab:<br>
<input type="text" name="resultat" maxlength="4"><br>
<input type="reset" value="Zurcksetzen" name="reset">
<input type="submit" value="Eintragen!" name="submit">
</form>

Ein Mini-CAPTCHA
In diesem Formular gibt es eine Besonderheit und zwar das Feld resultat.
Hier stelle ich dem Besucher eine Rechenaufgabe. Er soll vom Jahr (z. B.
2011) den Tag (z. B. 22) abziehen und diese Zahl dann in das Feld eintragen.
Wir werden im Skript berprfen, ob er diese Rechenaufgabe gelst hat.
Das dient als Spam-Schutz. Wir hoffen, dass die automatisierten Gste-
buchspammer mit dieser Aufgabe nicht fertig werden und so (erst einmal)
auen vor bleiben. Und sollten sie es dann doch geschafft haben, ist das
auch kein Beinbruch. Du kannst die Aufgaben aus dem CAPTCHA kompli-
zierter machen. Erweitere sie beispielsweise um die Eingabe zustzlicher
344
Gstebuch de luxe als Datenbanktabelle

Kapitel
14
Sternchen, Rauten, Sonderzeichen usw. Und wenn selbst das nichts hilft,
bleibt immer noch die Option mit der Freischaltung. Bestimme, ob die Da-
tenstze gleich oder erst nach Begutachtung sichtbar sein sollen.
Auerdem gibt es einen Button zum Zurcksetzen und einen zum Absen-
den des Formularinhalts. Der Submit-Button besitzt den Namen submit.
Daraus wird nach dem Absenden $_POST["submit"]. Das Vorhandensein
dieser Variablen werden wir spter prfen und erst dann das Eintragen
der Werte veranlassen! So wie beim Feedback-Formular aus Kapitel 8.
Wie auch immer: Vergleiche erst einmal mit der Datei guestbook3.php.

Formulardaten erst einmal berprfen
Aber auch jetzt wird nach Klick auf den Button EINTRAGEN! nichts weiter
Aufregendes passieren! Schauen wir uns deshalb endlich an, wie die For-
mulardaten berprft und danach in die MySQL-Datenbanktabelle einge-
tragen werden. Hier zeige ich dir den entsprechenden Quellcode. Notiere
ihn unterhalb der Zeile include("zugriff.inc.php"); und oberhalb
von $sql1 = "SELECT * FROM guestbook WHERE Zeigen = 1";
Bekomme keinen Schreck, das ist einfacher als es auf den ersten Blick aus-
sieht! Viele Dinge kennst du schon aus den vorhergehenden Kapiteln, vor
allem aus Kapitel 8 und 12.
Das Formular ist fer-
tig: Als Spamschutz
dient eineinfaches
CAPTCHA.
345
Das Eingabeformular entsteht

// Formular abgesendet?
if (isset($_POST["submit"])) {
// Formularwerte in freundlichen Variablen speichern
$Name = $_POST["Name"];
$Home = $_POST["Home"];
$Kommentar = $_POST["Kommentar"];
$resultat = $_POST["resultat"];
$endwert = date("Y") - date("j");
$fehler = false;
$fehlertext = "<p>";
// Eingaben prfen und Fehlertext zusammensetzen
if (empty($Name)) {
$fehler = true;
$fehlertext .= "Der Name fehlt!<br>";
}
if (empty($Kommentar)) {
$fehler = true;
$fehlertext .= "Bitte einen Kommentar eintragen!<br>";
}
// CAPTCHA-Prfung erst, wenn keine weiteren Fehler
if (!$fehler && (empty($resultat) || $resultat != $endwert)) {
$fehler = true;
$fehlertext .= "Test nicht bestanden!";
}
// Fehlertext ausgeben und Skriptabbruch
if ($fehler) {
echo "$fehlertext</p>";
die("</div></body></html>");
} else {
// Eintrag in die Datenbanktabelle
$datum = date("d.m.Y, H:i") . " Uhr";
$sql = "INSERT INTO guestbook
VALUES ('', '$Name', '$Home', '$datum', '$Kommentar', '1')";
mysqli_query($db, $sql);
// Erfolgsanzeige
if (mysqli_affected_rows($db) > 0) {
echo "<h3>Eintrag erfolgreich</h3>";
} else {
echo "<h3>Eintrag nicht erfolgreich</h3>";
}
}
}

346
Gstebuch de luxe als Datenbanktabelle

Kapitel
14
Wurde das Formular abgesendet?
Der gesamte Bereich wird durch eine if-Abfrage umspannt. Hier prfe ich
auf das Vorhandensein von $_POST["submit"]. Und diese Variable exis-
tiert nur, wenn das Formular auch abgesendet wurde. Und nur dann soll der
Eintrageteil wirksam werden.
Formularwerte und weitere Variablen
Danach sichere ich die Werte der vier Formularfelder Name, Home, Kom-
mentar und resultat in freundlicheren Variablen. So finde ich z. B. $Name
einfach schner und handlicher als das sperrige $_POST["Name"]. (Natr-
lich htte ich an dieser Stelle vorher noch mit isset() oder !empty()
prfen knnen, ob diese Variablen auch existieren. Lediglich aus Schutz vor
der Manipulation von Formluarfeldern. Das spare ich mir jedoch auf Grn-
den der Vereinfachung.)
Darunter berechne ich den Endwert fr das CAPTCHA. In $endwert wird
also die Differenz aus dem aktuellen Jahr und dem Tag des Monats gespei-
chert. Also exakt der Wert, den der Nutzer auch korrekt in das letzte For-
mularfeld eingeben muss. Der eigentliche Vergleich folgt dann etwas tiefer.
Darunter initialisiere ich die Variable $fehler mit dem Wert false und
die Variable $fehlertext mit einem einleitenden <p>-Tag. Du ahnst es
schon ich verwende die gleiche Fehlerbehandlung wie im Feedbackfor-
mular von Kapitel 8.
Eingaben prfen und Fehlertext zusammensetzen
Als Nchstes prfe ich, ob die Variablen $Name und $Kommentar leer ge-
blieben sind. Falls ja, wird $fehler auf true gesetzt und der entsprechen-
de Fehlertext in $fehlertext abgelegt. Es ist von Prinzip her wirklich
genau so wie in Kapitel 8! Lediglich das Feld fr die Homepage wird im
Beispiel nicht berprft, da es freiwillig ist.
Natrlich knnte und sollte ich sicher noch umfangreicher prfen: auf
Mindestlnge oder gar auf bereinstimmung mit einem bestimmten
Suchmuster. So, wie du es in Kapitel 8 schon kennengelernt hast. Darauf
verzichte ich im Beispiel jedoch, um die bersichtlichkeit des Skripts
nicht (weiter) zu gefhrden.
CAPTCHA-Prfung erst, wenn keine weiteren Fehler vorliegen
Schau dir nun die kunstvolle if-Abfrage fr die CAPTCHA-Prfung an:
if (!$fehler && (empty($resultat) || $resultat != $endwert)) {
347
Das Eingabeformular entsteht

Sie soll erst dann zur Wirkung kommen, wenn kein weiterer Fehler vorliegt.
Deshalb formuliere ich als allererste Prfbedingung: !$fehler die Vari-
able $fehler darf also nicht den Wert true beinhalten. Diese Bedingung
verknpfe ich per Und-Operator (&&) mit zwei weiteren Bedingungen.
Diese weiteren Bedingungen habe ich in einer runden Klammer zusammen-
gefasst, da sie zusammengehren. Denn sie sind ebenfalls miteinander
verknpft und zwar mit dem Oder-Operator (||) .
Mit anderen Worten: Das CAPTCHA wurde dann nicht ordnungsgem
aufgelst, wenn das entsprechende Feld nicht ausgefllt wurde (leer blieb)
oder aber der eingegebene Wert nicht mit dem Endwert bereinstimmt.
Erst wenn alle diese Teilausdrcke zusammen wahr sind, wird $fehler auf
true gesetzt und der Text Test nicht bestanden in $fehlertext gesichert.
Alles unklar? Probiere es einfach aus! Schicke das Formular ab, wobei du
mal dieses oder jenes Formularfeld frei lsst.
Eintragen der Daten per SQL
Im else-Zweig erfolgt dann endlich der ersehnte Eintrag in die Daten-
banktabelle. Zuerst speichere ich das aktuelle Datum im Format
27.04.2010, 12:35 Uhr in der Variablen $datum. Das gelingt unter anderem
unter Mithilfe der schon erwhnten Funktion date() in folgender Zeile:
$datum = date("d.m.Y, H:i") . " Uhr";

Danach wird die SQL-Abfrage nach dem Schema INSERT INTO
Tabellenname VALUES () zusammengesetzt und in der Variablen $sql
gesichert. Dabei lasse ich das erste runde Klammernpaar hinter guestbook
einfach weg. Dadurch erspare ich mir das Auflisten der Feldnamen der Da-
tenbanktabelle guestbook.
Das kann man immer dann machen, wenn man beim Eintragen der Werte
im zweiten runden Klammernpaar ganz exakt die Reihenfolge einhlt, in
der die Feldnamen in der Datenbanktabelle stehen. Und wenn man wie
im Beispiel auch alle Felder bercksichtigt.
Eintrge erst spter freischalten?
Apropos alle Felder fr das Feld Zeigen habe ich im Beispiel eine 1 ein-
getragen. Dadurch sind alle eingegebenen Datenstze sofort sichtbar. Wenn
du die Datenstze jedoch erst nachtrglich freischalten mchtest, notierst
du an der entsprechenden Stelle statt 1 einfach eine 0:
VALUES ('', '$Name', '$Home', '$datum', '$Kommentar', '0')";
Am Ende wird die Abfrage per mysqli_query($db, $sql); ausgefhrt.
348
Gstebuch de luxe als Datenbanktabelle

Kapitel
14
Erfolgsanzeige mit mysqli_affected_rows()
Doch damit nicht genug! Wir wollen dem Nutzer auch eine Statusanzeige
prsentieren. Dabei hilft uns die Funktion mysqli_affected_rows($db).
Als Parameter bergeben wir wieder die Datenbankkennung. Die Funktion
ermittelt, wie viele Datenstze (Zeilen) von einer MySQL-Aktion betroffen
waren. In unserem Fall mssen es eben mehr als 0 sein. Und genau das
fragen wir auch ab: if (mysqli_affected_rows($db) > 0) {

Wenn alles geklappt hat, lautet die Meldung: Eintrag erfolgreich. Ansons-
ten jedoch Eintrag nicht erfolgreich. Alles klar? Diese Version findest du in
der Datei guestbook4.php. Es handelt sich immerhin schon um eine
funktionierende Gstebuch-Variante. Probiere es aus!
Mit Sicherheit: Reloadsperre und
Magic Quotes
Sicherheit ist das groe Thema! Und deshalb sorgen wir an dieser Stelle
wieder vor: vor lstigen Doppeleintrgen und vor Angriffen auf die Daten-
banktabelle durch Einschleusung von SQL-Code (SQL-Injection).
Unique Index: Doppeleintrge verhindern
Schutz vor Doppeleintrgen? Kein Problem! Natrlich knnen wir die Funk-
tion isDouble() aus Kapitel 12 recyceln. Doch inzwischen arbeiten wir
schlielich mit Datenbanktabellen. Und da gibt es eine elegantere Lsung
den Unique Index. Es handelt sich um einen speziellen Index-Typ, also einen
Schlssel, mit dem sich Doppeleingaben zuverlssig verhindern lassen.
Hilfreiche Status-
meldung fr den
Anwender.
349
Mit Sicherheit: Reloadsperre und Magic Quotes

Index-Typ? Schlssel? Klar! Einen Index-Typ kennst du sogar schon den
Primrschlssel. Dieser sorgt fr die eindeutige Kennung in deiner Daten-
banktabelle: jeder Wert darf nur ein einziges Mal vorkommen. Ganz hnlich
arbeitet auch der Unique Index. Er wird immer dann gebraucht, wenn au-
er dem Primrschlsselfeld weitere Felder beim Schutz vor Doppeleintr-
gen herangezogen werden soll.
Im Beispiel wollen wir die Felder Name und Kommentar gemeinsam zu
einem Unique Index machen. Es soll sich also um einen Index ber
2 Spalten handeln. Damit schlieen wir aus, dass es zwei Eintrge gibt,
bei denen Name und Kommentar gleich sind. Natrlich htten wir uns
auch auf das Namefeld beschrnken knnen. Doch das wre unklug. Es
kommt durchaus vor, dass zwei Gstebuchschreiber den gleichen Namen
haben. Und das kann man ja schlielich nicht verbieten!
Und so erzeugst du einen Unique Index ber 2 Spalten:
>
Rufe die zu bearbeitende Tabelle in phpMyAdmin auf, im Beispiel die
Gstebuchtabelle guestbook.
>
Klicke auf die Registerzunge STRUKTUR, damit du die Struktur der Da-
tenbanktabelle bearbeiten kannst.

>
Rolle im rechten Fensterbereich ein Stck nach unten und schaue
dorthin, wo Index ber 1 Spalten anlegen steht. (Du siehst dieses Feld
nicht? Klicke vorher auf den Link Details, damit dieser Bereich einge-
blendet wird.) Ersetze nun die 1 durch eine 2 und klicke auf OK!

>
Der Bereich Neuen Index anlegen erscheint: Whle bei INDEXTYP den
Eintrag UNIQUE.

350
Gstebuch de luxe als Datenbanktabelle

Kapitel
14
>
Bei FELD whlst du die gewnschten Felder aus den Pull-down-Mens
aus im Beispiel NAME und darunter KOMMENTAR.
>
Beim Feld Kommentar musst du noch eine Gre eingeben und nur
bei Kommentar. Der Grund liegt im Felddatentyp text. Der ist zu lang
fr den Index! Maximal 256 Zeichen knnen bercksichtigt werden,
sonst gibt es eine Fehlermeldung. Tippe im Beispiel einfach eine 50.

>
Klicke auf SPEICHERN, keinesfalls jedoch auf OK. PhpMyAdmin prsen-
tiert dir nun den dazugehrigen SQL-Quellcode:

>
Der neue Index ist fertig! Du kannst den Status darber brigens je-
derzeit unten in der Strukturansicht ablesen. Dort lsst sich dieser
Schlssel auch nachtrglich bearbeiten und ggf. lschen. (Klicke vor-
her ggf. wieder auf den Link Details, um diese Ansicht einzublenden.)

Nanu, das Anlegen schlgt fehl? Es gibt immer wieder eine Fehlermel-
dung? Dann hast du mglicherweise schon Doppeleintrge in deiner Ta-
belle. Lsche diese und versuche es erneut.
Und nun drcke doch einmal nach Eintragen eines Gstebucheintrags auf
die Browserschaltflche RELOAD. Richtig! Die Anzeige lautet jetzt Eintrag
nicht erfolgreich. War doch gar nicht so dumm, unsere Statusanzeige mit
mysqli_affected_rows()!
351
Mit Sicherheit: Reloadsperre und Magic Quotes

Schutz vor Angriffen auf die Datenbank
Zeit fr etwas Magie! Jetzt geht es um den Schutz unserer Datenbank vor
Code-Einschleusung (SQL-Injection).
Automatische Sicherheit dank magic quotes?
Frher galt in der Regel: Alle Daten aus Formularen oder URL-Anhngen
werden von PHP automatisch escaped. Mit anderen Worten: Alle einfa-
chen bzw. doppelten Gnsefchen, der \ (und der Wert Null-Byte) erhal-
ten wie von Zauberhand einen Backslash. Dafr sorgte eine Zeile namens
magic_quotes_gpc = On in der php.ini. Wie gesagt so war es frher.
Das ist brigens genau das, was auch die Funktion addslashes() erle-
digt: Sie setzt vor die eben genannten Zeichen einen Backslash.
Wie sieht es bei dir und deinem Dienstleister aus? Rufe die Funktion
phpinfo() auf, sie erzeugt ja eine PHP-Info-Seite. Suche hier den Eintrag
magic_quotes_gpc.

Die Zeichenfolge gpc bezieht sich dabei auf get, post und cookie. Diese
magische Quotierung wirkt also auf alle Werte aus $_GET, $_POST und
$_COOKIE in unserem Beispiel natrlich auf $_POST.
Die Idee dahinter war nicht so dumm. Denn derart gefhrliche Zeichen
mssen auf jeden Fall entwertet werden. Angreifer knnten es sonst
schaffen, eigene SQL-Abfragen in die Datenbank zu schummeln. So pro-
vozieren sie Fehlermeldungen, lesen Daten aus der Datenbanktabelle aus
oder lschen diese sogar. Auch das Umgehen eines Passwortschutzes
kann auf diese Weise mglich sein. Im Praxisbuch findest du dazu sogar
ein kleines Beispiel. Noch vor einigen Jahren haben sich viele PHP-
Programmierer noch nicht viel Gedanken um Sicherheit gemacht. Sie
vergaen, Werte vor dem Eintragen in die Datenbanktabelle mit
addslashes() zu behandeln. Deshalb erfand man die magic quotes.
So wurden gefhrliche Zeichen gleich automatisch entschrft und viele
Angriffe auf die Datenbank konnten abgewehrt werden.
Per Voreinstellung war
magic_quotes_gpc
frher meist auf On ge-
stellt das hier ist eine
ltere Abbildung.
352
Gstebuch de luxe als Datenbanktabelle

Kapitel
14
Heute: magic quotes sind nicht mehr sicher genug
Heute sieht das Bild anders aus. Jeder ernsthafte PHP-Programmierer wei,
dass man Daten entschrfen muss, bevor sie in die Datenbanktabelle ge-
schrieben werden knnen. Weiterhin gilt: Die Funktion addslashes() ist
nicht mehr leistungsstark genug. (Magic quotes ist ja nichts weiter, als
eine addslashes()-Automatik.) Es gengt nicht, lediglich Gnsefchen
zu entwerten. Durch Unicode sind neue Zeichen hinzugekommen, die eben-
falls gefhrlich werden knnen. Der Zeichensatz muss also auch berck-
sichtigt werden! Mit anderen Worten: magic quotes ist ein Auslaufmodell
und in PHP 6 wird diese Option abgeschafft!
mysqli_real_escape_string()
Die Lsung heit: mysqli_real_escape_string(). Diese Funktion ar-
beitet grndlicher als addslashes(). Sie erzeugt eine Zeichenfolge, die du
auf jeden Fall in deine SQL-Abfragen bernehmen kannst. Sie erwartet
zwei Parameter, die Verbindungskennung und den umzuwandelnden String.
Und sie bercksichtigt dabei den Zeichensatz der aktuellen Verbindung.
mysqli_real_escape_string($db, string)
Du mchtest den Namen escapen? Ersetze $Name = $_POST["Name"]
durch $Name = mysqli_real_escape_string($db, $_POST["Name"]);
Diese Prozedur solltest du auch den anderen drei Variablen gnnen.
Der entsprechende Abschnitt sieht dann so aus:
// Formularwerte escapen und speichern
$Name = mysqli_real_escape_string($db, $_POST["Name"]);
$Home = mysqli_real_escape_string($db, $_POST["Home"]);
$Kommentar = mysqli_real_escape_string($db, $_POST["Kommentar"]);
$resultat = mysqli_real_escape_string($db, $_POST["resultat"]);

Dank dieser Funktion knnen Inhalte aus Formularen direkt mit INSERT
INTO tabellenname VALUES ('Wert1', 'Wert2', usw.) in die Da-
tenbanktabelle geschrieben werden, ohne dass wir uns Sorgen machen
mssten. Die gefhrlichen Gnsefchen werden auf jeden Fall maskiert
vor allem das einfache ist problematisch, da es in schdlichen SQL-
Abfragen eingesetzt werden kann! Und ein Herr O'Hara kann jetzt auch
eingefgt werden. In der Datenbanktabelle tauchen diese Escape-Zeichen
brigens spter nicht mehr auf, da MySQL sie vorher entfernt.
Vergleiche mit der Datei guestbook5.php, wo du diese Ergnzung be-
wundern kannst. Wir haben mit dieser Manahme einen wichtigen Schritt
in Richtung Sicherheit getan!
353
Mit Sicherheit: Reloadsperre und Magic Quotes

get_magic_quotes_gpc()
Unser Skript ist bisher schon ganz super. Doch was passiert, wenn die ma-
gic quotes bei deinem Dienstleister eingeschaltet sind? Dann werden viele
Zeichen doppelt entwertet! Zumindest jedes einfache und doppelte Gnse-
fchen bekommt einen zustzlichen Slash. Und der bleibt in der Daten-
banktabelle drin! Das ist nicht sehr schn. In diesem Fall musst du die Wir-
kung von magic quotes (= addslashes()) durch ein Gegengift aufhe-
ben. Dieses Gegengift kennst du schon: stripslashes().
Erfrage einfach per Skript, wie dieser magische Schalter bei dir eingestellt
ist. Das gelingt mit der Funktion get_magic_quotes_gpc(). Ist der
Schalter on, gibt sie eine 1, bei off dagegen eine 0 zurck. Und so knnte
eine derartige Abfrage aussehen:
if (get_magic_quotes_gpc()) { // eingeschaltet?
$Variable = stripslashes($Variable);
}

Im Beispiel sieht die Ergnzung fr unser Gstebuch folgendermaen aus:
// Reaktion auf eingeschaltete magic quotes
if (get_magic_quotes_gpc()) { // eingeschaltet?
$_POST["Name"] = stripslashes($_POST["Name"]);
$_POST["Home"] = stripslashes($_POST["Home"]);
$_POST["Kommentar"] = stripslashes($_POST["Kommentar"]);
$_POST["resultat"] = stripslashes($_POST["resultat"]);
}

Notiere den Block direkt unter if (isset($_POST["submit"])) {. So
wird er ausgefhrt, bevor die Funktion mysqli_real_escape_string()
wirken kann. Vergleiche mit der Datei guestbook6.php.
Du bist bis hierher nur mit Mhe und Not mitgekommen? Du bist zufrie-
den mit der bisherigen Gstebuch-Version? Kein Problem. Mache an die-
ser Stelle eine schpferische Pause. Wenn du das Gstebuch in der bis-
herigen Fassung verwenden mchtest, nderst du zuerst die SQL-Abfrage
$sql2 = "SELECT * FROM guestbook WHERE Zeigen = 1 ORDER
BY id DESC LIMIT 0, 4"; wie folgt: Entferne die Passage LIMIT 0,
4, da sonst immer nur die letzten vier Eintrge angezeigt werden wr-
den! Auerdem musst du echo "<p><strong>1.</strong> " .
streichen. Schlielich soll nicht jeder Eintrag mit 1. beginnen!
354
Gstebuch de luxe als Datenbanktabelle

Kapitel
14 Nicht alle Datenstze auf einmal
Du willst weitermachen? Herzlichen Glckwunsch. Dann teste doch gleich
die bisherige Version des Gstebuches. Gib ruhig noch ein oder zwei Eintr-
ge ein! Und, funktioniert alles? Klappt auch der Reload-Schutz? Super!
Den Zhler zusammenbauen
Als nchstes baust du den Zhler zusammen. Aus der sich stndig wieder-
holenden Anzeige 1. soll schlielich 1., 2., 3. usw. werden. Der jeweils
oberste Eintrag (der neuste) bekommt dabei die 1., alle anderen werden
fortlaufend nummeriert. Auerdem bereitest du die Ausgabe der ersten vier
Datenstze schon vor.
>
Schaffe in deinem Skript etwas Platz, tippe ein paar Leerzeichen. Den
entsprechenden Abschnitt habe ich hier gekennzeichnet:
<?php
(HIER PLATZ SCHAFFEN)
include("zugriff.inc.php");

>
Fge an dieser frei gehaltenen Stelle nun folgende Codezeilen ein:
$start = 0; // Startwert setzen (0 = 1. Zeile)
$step = 4; // Wie viele Eintrge gleichzeitig?
// Startwert verndern:
if (isset($_GET["start"])) {
$muster = "/^[0-9]+$/"; // reg. Ausdruck fr Zahlen
if (preg_match($muster, $_GET["start"]) == 0) {
$start = 0; // Bei Manipulation Rckfall auf 0
} else {
$start = $_GET["start"];
}
}
$nr = $start + 1;


Was passiert in diesem neuen Abschnitt? Ich erschaffe insgesamt drei
weitere Variablen. Die Variable $start beherbergt den Startwert fr meine
SQL-Abfrage, sie wird am Anfang mit 0 initialisiert. Schlielich soll die
Ausgabe mit dem 0. Datensatz beginnen also mit der ersten Zeile. Als
nchstes folgt die Variable $step. Hier lege ich fest, wie viele Eintrge
gleichzeitig ausgegeben werden sollen. Das knnen 2, 3, 4 oder auch 10
355
Nicht alle Datenstze auf einmal

Eintrge sein! Dank dieser fabelhaften Variablen kann ich den Wert hinter-
her immer wieder problemlos anpassen!
Zum Schluss dieses Code-Abschnitts wird die Variable $nr initialisiert.
Diese Variable wird erzeugt aus dem Startwert, erhht um 1. Da die Zh-
lung der Datenstze bei 0 beginnt, muss fr den ersten Datensatz folge-
richtig eine 1 ausgegeben werden.
Den Startwert verndern
Und nun zur if-Abfrage, denn diese ist besonders wichtig fr die dynami-
sche Ausgabe der Datenstze. Diese if-Abfrage verndert schlielich den
in der Variablen $start gespeicherten Startwert. Wenn der Nutzer die
nchsten vier Datenstze sehen mchte, muss der Startwert auf 4 gesetzt
werden. Wie erreichen wir das? Wir bergeben den Startwert mit der GET-
Methode. Wir hngen ihn an die URL an, und zwar nach folgendem Muster:
Dateiname?start=4
Bei unserem Gstebuch sieht das so aus: guestbook.php?start=4
Es wird also ein Parameter namens start per GET bergeben. Die erste
if-Abfrage prft also, ob dieser Parameter vorhanden ist:
if (isset($_GET["start"])) {
Dann muss aus Sicherheitsgrnden jedoch noch ein zweiter if-Test gefah-
ren werden! Wir prfen danach mit einem regulren Ausdruck, ob es sich
wirklich um einen Zahlwert handelt. Schlielich lassen sich URL-Parameter
von Witzbolden schnell mal verndern. Da derart geflschte Werte keines-
falls vom Skript weiterverarbeitet werden drfen, setzt unser Filter den
Wert von $start bei Manipulationsversuchen auf 0.
Natrlich wre auch ein Skriptabbruch mit die() denkbar. Aber in diesem
Fall gengt es, bei Manipulationsversuchen einen Standardwert zu setzen.
Nur wenn der aus $_GET["start"] bernommene Wert koscher ist, greift
der else-Zweig. Dort wird dann endlich der Wert des Parameters ausgele-
sen und in $start abgelegt: $start = $_GET["start"];
Push it to the LIMITs
Weiter gehts im Text. Die eben mhselig festgelegten Variablen ntzen dir
berhaupt nichts, wenn du sie nicht an den richtigen Stellen einbaust!
Wage dich zuerst an die SQL-Abfrage $sql2. ndere diese Zeile:
$sql2 = "SELECT * FROM guestbook WHERE Zeigen = 1 ORDER BY
id DESC LIMIT 0, 4";

356
Gstebuch de luxe als Datenbanktabelle

Kapitel
14
wie folgt:
$sql2 = "SELECT * FROM guestbook WHERE Zeigen = 1 ORDER BY
id DESC LIMIT $start, $step";

Die SQL-Anweisung LIMIT kennt zwei Parameter. Die erste Ziffer gibt an, ab
welchem Datensatz die Daten ausgegeben werden. Die zweite Ziffer legt
die Zahl der gewnschten Datenstze fest. Raffiniert, nicht wahr?
Wo bleibt die Nummerierung?
Na klar, du musst natrlich auch die Nummerierung anpassen. ndere also
noch folgende Zeile:
echo "<p><strong>1.</strong> " .

in
echo "<p><strong>$nr.</strong> " .

Auerdem musst du kurz vor dem Ende der while-Schleife darauf achten,
dass die Variable $nr um eins erhht wird. Fge also ber dieser Zeile
} // while Ende

folgende ganz kurze Zeile ein:
$nr++;

Jetzt sieht die while-Schleife insgesamt so aus. Alle Umbaumanahmen
habe ich hervorgehoben:
while($row = mysqli_fetch_assoc($result2)) {
echo "<p><strong>$nr.</strong> <b>"
. htmlspecialchars($row["Name"]) . "</b> ";
if (!empty($row["Home"])) {
echo "(" . htmlspecialchars($row["Home"]) . ")";
}
echo "<br>--&gt; schrieb am " .
"<strong>" . $row["Datum"] . "</strong>:</p>" .
"<p>" . nl2br(htmlspecialchars($row["Kommentar"])) .
"</p><hr>\n";
$nr++;
} // while Ende

357
Links fr die seitenweise Ausgabe

Verschrieben? Kein Problem! Den bisherigen Stand findest du auch in der
Datei guestbook7.php!
Ausprobieren lautet die Devise, ausprobieren! Zum einen wirst du mer-
ken, dass die Datenstze nun automatisch durchgezhlt werden. Zum
anderen solltest du auch versuchen, die nchsten vier Datenstze auszu-
geben. Tippe statt guestbook.php einfach guestbook.php?start=3
und beobachte die Datenausgabe. Es funktioniert natrlich nur, wenn du
schon mindestens vier Datenstze eingetragen hast!

Ein Startwert von 3 blendet als obersten Eintrag den vierten Gstebucheintrag ein.
Links fr die seitenweise Ausgabe
Du bist schon weit gekommen, aber noch nicht fertig! Schlielich kannst
du vom Nutzer kaum erwarten, dass sie oder er jedes mal die Zeichenfolge
?start=4 oder ?start=8 an die Webadresse hngt. Das ist nicht sonder-
lich komfortabel, das musst du zugeben.
Eine schicke Linkleiste muss her, und zwar nach dem Muster [1-4] [5-8] [9]
usw. Wenn sie oder er z. B. auf [5-8] klickt, wird die Seite noch einmal auf-
gerufen. Diesmal jedoch mit dem Anhngsel ?start=4! Auf diese Weise
knnen die entsprechenden Datenstze eingeblendet werden.
Kein Problem? Mit einer Schleife lsst sich das ganz einfach lsen? Einver-
standen, hier sind die Lsungen:
358
Gstebuch de luxe als Datenbanktabelle

Kapitel
14
For-Schleife, die erste!
Schau dir zuerst unsere einfache Variante an. Sie funktioniert, ist aber noch
nicht ganz perfekt. Ergnze dafr einfach den entsprechenden Code. Setze
ihn zwischen diese beiden Zeilen:
$result2 = mysqli_query($db, $sql2);
Neuen Code hier einfgen;
echo "<h2>Bisherige Eintrge</h2>";

Und so sieht der entsprechende Code nun aus:
for ($i = 0; $zeilen > $i; $i = $i + $step) {
$anf = $i + 1;
$end = $i + $step;
echo "[ <a href=\"guestbook.php?start=$i\">$anf-$end</a> ] ";
}

Ich arbeite mit einer for()-Schleife. Die Zhlvariable $i wird mit 0 initia-
lisiert, $i = 0. Diese Zhlvariable soll nach jedem Durchgang um $step
erhht werden ($i = $i + $step), also im Beispiel um 4. Die Bedingung
lautet $zeilen > $i, die Zhlvariable $i muss kleiner bleiben als die
Gesamtzahl der Zeilen unserer Datenbanktabelle ($zeilen). Mit anderen
Worten: Erst wenn es 5 Gstebucheintrge gibt, wird die Schleife ein zwei-
tes Mal durchlaufen! Innerhalb der Schleife werden die Variablen $anf und
$end initialisiert und nach Durchlaufen der Schleife natrlich aktualisiert.
Das Ausgeben des Hyperlinks selber erfolgt im echo-Teil. Hier entsteht
ein Verweis auf sich selbst mit dem Anhngsel ?start=$i. Die Zhlva-
riable $i sorgt also dafr, dass hier dynamisch der richtige Wert steht.
Schlielich ist $i bei ersten Durchlauf der Schleife noch 0. Beim zweiten
Durchlauf betrgt der Wert 4, dann 8 usw.. Die eckigen Klammern und das
zustzliche Leerzeichen wurden lediglich aus optischen Grnden eingefgt.
Wenn dein Gstebuch reich gefllt ist, werden schlielich unzhlige dieser
Links nebeneinander aufgereiht.
Was glaubst du eigentlich, warum ich die Variablen in dieser Passage
<a href=\"guestbook.php?start=$i\">$anf-$end</a> einfach so
aneinanderreihe? Woher wei der PHP-Interpreter, wo die Variable $i
aufhrt? Warum gibt es ebenfalls keine Probleme bei diesem $anf-
$end-Gebilde? Ganz einfach! Die Zeichen >, <, ?, =, \ oder der Binde-
strich drfen in Variablen nicht vorkommen. Sie sind das Stopp-Signal.
359
Links fr die seitenweise Ausgabe

Diese Version findest du in der Datei guestbook8.php.
Die zweite Version der for-Schleife
Probiere es aus! Es funktioniert. Allerdings besitzt diese Version noch einige
Schnheitsfehler. Einen davon zeige ich dir in der nchsten Abbildung.

Zwar sind es nur sieben Eintrge, die Links suggerieren allerdings acht!
Ganz unbeeindruckt von der tatschlichen Zahl der Gstebucheintrge
zeigt das Skript immer [1-4] oder [1-4] [5-8] oder [1-4] [5-8] [9-12] usw.
usf. je nachdem, wie voll dein Gstebuch ist. Eine etwas feiner abge-
stimmte Anzeige nach dem Motto [1-2] oder [1-4] [5] oder [1-4] [5-7]
erreichst du dagegen mit folgender, erweiterter Schleifenkonstruktion:
for ($i = 0; $zeilen > $i; $i = $i + $step) {
$anf = $i + 1;
$end = $i + $step;
if ($end > $zeilen) {
$end = $zeilen;
}
if ($anf == $end) {
echo "[ <a href=\"guestbook.php?start=$i\">$end</a> ] ";
} else {
echo "[ <a href=\"guestbook.php?start=$i\">$anf-$end</a> ] ";
}
}

Hinzugekommen sind zwei if-Abfragen innerhalb der Schleife. Diese sor-
gen stets fr die richtige Feinabstimmung. Nehmen wir gleich das erste if:
Wenn der Wert von $end die tatschliche Anzahl der Zeilen berschreitet,
360
Gstebuch de luxe als Datenbanktabelle

Kapitel
14
wird der Variablen $end kurzerhand der wahrheitsgetreue Wert aus
$zeilen verpasst. Das sorgt fr eine Anzeige wie [1-3] statt [1-4].
Das zweite if beseitigt einen weiteren Schnheitsfehler. Angenommen, es
gibt genau fnf Gstebucheintrge. Ohne dieses if wrde die Anzeige wie
folgt aussehen: [1-4] [5-5]. Hier entspricht der Anfangswert $anf also dem
Endwert $end! Doch zwei gleiche Werte sehen recht ungeschickt aus. In
diesem Fall gengt die Ausgabe eines Wertes. Das zweite if mit else-
Zweig fhrt also zu der Anzeige [1-4] [5] bei fnf Gstebucheintrgen.

Schwirrt der jetzt der Kopf? Du findest den aktuellen Stand auch in der
Datei guestbook9.php!
Adminbereich fr den Gstebucheigner?
Du mchtest Eintrge lschen? Oder neu eingetragene Datenstze frei-
schalten? Das erledigst du bequem und komfortabel mit phpMyAdmin!
Schlielich bietet dir dieses Tool den perfekten berblick ber den Inhalt
deiner Datenbanktabellen.
Natrlich ginge es noch komfortabler. Ich denke an einen Login-Bereich fr
den Administrator. Logge dich direkt in dein Gstebuch ein. Schalte Eintr-
ge von hier aus frei oder lsche sie direkt. Das ntige Know-how vermittle
ich dir im Nachfolgeband PHP und MySQL Praxisbuch fr Kids. Dort ver-
wendest du Cookies im Zusammenhang mit der fr diesen Zweck bestens
geeigneten Session-Technologie. Ich zeige dir das Prinzip an mehreren Pra-
xisbeispielen vom Fotoweblog bis hin zum ausgewachsenen Content-Ma-
Schnheitsfehler
beseitigt dein Gste-
buch ist damit im
Prinzip schon fertig!
361
Schlussbemerkung

nagement-System. Erste Anregungen bekommst du aber auch schon im
nchsten Kapitel. Dort verwendest du die Cookies fr einen Einloggbereich.

Schlussbemerkung
Was fr ein Projekt! Konntest du Schritt fr Schritt folgen? Wenn ja, be-
glckwnsche ich dich dazu. Wenn nicht, lass den Kopf nicht hngen und
versuche es noch einmal. Und auch wenn du nur einen Teilabschnitt be-
wltigst hast, ist das schon ein kleiner Erfolg!
Und bilde dir nur nicht ein, ich htte das Ding an einem Nachmittag zu-
sammengehustet. Habe ich nicht! Manchmal grbele ich Tage an Skripten
wie diesem, und irgendwann mitten beim Spazierengehen fllt mir noch
eine Lsung ein! Apropos Spazierengehen das wre jetzt wirklich eine
gute Idee! Denn danach habe ich noch ein paar Fragen an dich. Und ein
paar Aufgaben.
Zusammenfassung
0 Du weit, wie eine Gstebuch-Datenbanktabelle aussehen muss und
kannst sie in die Praxis umsetzen.
0 Du nutzt den SQL-Befehl LIMIT, wenn du nur eine bestimmte Anzahl
an Datenstzen ausgeben mchtest.
0 Du weit, dass du ein umfangreiches Projekt stets in Teilschritten um-
setzen solltest. Prfe den Code nach jedem neuen Teilschritt. Erstelle
von jedem Modul eine Sicherheitskopie.
Dank phpMyAdmin wird
das Bearbeiten und
Lschen der Beitrge
zum Kinderspiel.
362
Gstebuch de luxe als Datenbanktabelle

Kapitel
14
0 Du verwendest die Funktion include(), mit der du Teile des Codes
extern auslagerst. Im Beispiel sind es die Zugangsdaten fr deine SQL-
Datenbank. Lege sie in einer Datei namens zugriff.inc.php ab.
0 Du nutzt die Technik, einer URL einen zustzlichen Parameter zu ber-
geben. Wenn du z. B. ?start=0 an die URL anhngst, erhltst du die
Variable $_GET["start"] und kannst den entsprechenden Wert im
Skript auslesen und darauf reagieren.
0 Auf diese Weise realisierst du das seitenweise Abrufen der Gstebuch-
eintrge. Du bergibst den Startwert, der dem Datensatz entspricht,
welchen du einblenden mchtest.
Ein paar Fragen
1. Warum sollte ausgelagerter Code auf .php enden und nicht z. B. auf
.txt?
2. Warum sollte man die Zugriffsdaten fr die SQL-Datenbank in einer
include-Datei auslagern? Welche Vorteile bringt das?
3. Mit welchem SQL-Befehl sorgst du fr eine absteigende Anzeige?
4. Mit welchem SQL-Befehl kannst du die Ausgabe der Datenstze limi-
tieren?
und ein paar Aufgaben
1. Klar, das Gstebuch ist noch nicht perfekt. Sorge zuallererst dafr, dass
die Daten nach Absenden nicht aus den Formularfeldern gelscht wer-
den. Das ist vor allem dann rgerlich, wenn der Nutzer ein Feld verges-
sen hat. Wie das geht, habe ich dir ja schon in Kapitel 8 gezeigt.
2. Gib eine Mindestlnge fr die Felder Name und Kommentar vor. Der
Name soll mindestens 3 und der Kommentar mindestens 10 Zeichen
lang sein. Mache den Nutzer im Zweifelsfall darauf aufmerksam, dass
die entsprechende Eingabe nicht lang genug ist.
3. Fr Profis: Baue das Skript so um, dass beim Anzeigen der Homepage
automatisch ein Hyperlink erzeugt wird. Die Zieladresse soll sich in ei-
nem neuen Browserfenster ffnen.
4. Die Schwierigkeit bei diesen Links besteht darin, den Nutzer zu zwin-
gen, seine Adresse mit http:// einzugeben. berprfe also auch das
Formularfeld fr die Homepage. Der Test soll jedoch erst anschlagen,
363
und ein paar Aufgaben

wenn das Home-Feld nicht leer ist. Das Feld ist schlielich freiwillig!
Dann jedoch soll geprft werden, ob die Eingabe am Anfang http://
enthlt und ob sie keine Umlaute und Sonderzeichen besitzt. (Die selte-
nen Umlautadressen wollen wir im Beispiel nicht zulassen!)
Folgender regulrer Ausdruck prft, ob eine Zeichenfolge mit den eben
formulierten Bedingungen bereinstimmt:
"|^http://[a-zA-Z0-9-_.]+$|"
Als Begrenzer kommen diesmal brigens senkrechte Striche zum Ein-
satz. Der Grund: Das http:// besitzt schon zwei Schrgstriche.
Teste auf bereinstimmung mit diesem Suchmuster. Gib bei Misserfolg
folgenden Text aus: Deine Webadresse ist nicht korrekt! Bitte vergiss
nicht das http:// am Anfang und vermeide Umlaute und Sonderzeichen!
5. Sorge dafr, dass dir das Gstebuch-Skript nach jedem Eintrag eine
E-Mail schreibt. Diese E-Mail soll dir auch das Eintragsdatum, den Na-
men, ggf. die Homepage und den Kommentar des Nutzers zuschicken.
Orientiere dich an der Abbildung. Tipp: Die Mail muss verschickt wer-
den, wenn das Eintragen erfolgreich war.

Hinter dieser Aufgabe steckt eine zustzliche Schwierigkeit. Es kann Pro-
bleme geben beim Versenden der E-Mail, wenn die Seite als UTF-8 ko-
diert ist. Wir haben uns darber ja schon im Kapitel 8 unterhalten. Ko-
diere die Seite also als ISO-8859-1. Sorge auerdem dafr, dass der Zei-
chensatz der Datenbankverbindung ebenfalls ISO-8859-1 lautet. (Dafr
musst du lediglich eine Zeile in der zugriff.inc.php entfernen!)
6. Verbessere den CAPTCHA-Test. Der Nutzer soll vor der berechneten Zahl
fnf Sternchen und danach eine Raute # und eine Tilde ~ tippen. Je-
weils ohne Leerzeichen. Das sieht im Zweifelsfall so aus: *****1998#~
365



15
Weblog fr Kids: Das
Mini-CMS
Hast du Lust auf ein eigenes Weblog? Wolltest du immer schon wissen, wie
man ein kleines News-System programmiert? Dann bist du in diesem Kapi-
tel genau richtig! Ich zeige dir, wie du ein attraktives und einfach zu hand-
habendes Web-Tagebuch erstellst. Auch wenn du kein Blogger bist,
sollst du auf deine Kosten kommen. Dann nennst du dein Projekt einfach
CMS wie Content Management System. Das Beispiel lsst sich fr viele
Zwecke einsetzen. Denn auf den Inhalt kommt es an, auf den Content.
In diesem Kapitel zeige ich dir, wie du
$ das Mini-CMS planst und die entsprechende Datenbanktabelle erstellst
$ deine Seite mit HTML und CSS attraktiv gestaltest
$ mit der Heredoc-Syntax HTML noch einfacher in PHP eingliederst
$ einen per Cookie gesicherten Passwort-Zugang erstellst
$ die Anzeige der Eintrge auf eine bestimmte Lnge krzt
$ einen Link zu Archiv-Beitrgen angibst
Bei diesem Projekt greife ich unter anderem auf die Erfahrungen aus dem
Gstebuchprojekt von Kapitel 14 zurck. Aber auch die Cookies rufen wir
uns in Erinnerung. Ganz wichtig: Auch hier erstellst du den Code wieder
Schritt fr Schritt. Auch hier steht Projektarbeit im Vordergrund!
366
Weblog fr Kids: Das Mini-CMS

Kapitel
15 Pflichtenheft: Zuerst planst du
das Projekt
Wie immer bei groen Projekten muss geplant werden. Damit du weit
um was es geht, prsentiere ich dir das fertige Ergebnis in einer Abbildung.

Content managen: Erst nach Klick auf ALLES LESEN erscheint der komplette Eintrag.
Anforderungen an das System
Unser System soll folgende Anforderungen erfllen:
0 Anzeigen der aktuellen Eintrge zuoberst, Archiv-Link fr ltere Ein-
trge.
0 Krzen der Anzeige, wenn eine bestimmte Zeichenzahl berschritten
wird. In diesem Fall wird zustzlich ein Link bereitgestellt, ber den der
komplette Beitrag aufgerufen werden kann.
0 Anbringen eines ZURCK-Links, damit man vom kompletten Beitrag wie-
der zurck zur Hauptseite navigieren kann.
0 Anbringen eines HOME-Links auf jeder Seite.
0 Notieren eines NACH OBEN-Links, der vom Seitenende zurck zum Sei-
tenanfang fhrt.
367
Pflichtenheft: Zuerst planst du das Projekt

0 Bequeme Eingabe der Beitrge durch ein per Passwort geschtztes Ein-
gabeformular. Unaufflliges Login am Seitenfu.
0 Zulassen von HTML-Code im Beschreibungstext, damit z. B. auch Grafi-
ken eingefgt werden knnen.
0 Nicht zuletzt schickes Aussehen mit Rahmen, Hintergrundgrafik und
fester Breite.
Natrlich spielt auch bei diesem Projekt die Sicherheit eine groe Rolle.
Zum Glck ist ein Weblog lngst nicht so kritisch wie ein Gstebuch. Vor
allem beim Eingabeformular knnen wir den Aufwand begrenzen!
Im Idealfalle bist du der alleinige Urheber der Eintrge. Oder du beziehst
ein paar engere Freunde in dein Tagebuchprojekt mit ein. Die Funktion
htmlspecialchars() zum Unterdrcken von HTML-Code bentigst du
in diesem Fall ebenso wenig wie eine Reload-Sperre. Schlielich sollen
HTML-Eintrge erlaubt sein. Schon deshalb wre htmlspecialchars()
hinderlich, da diese Funktion alle HTML-Tags schlielich entschrft.
(Wenn der Tagebuchschreiber jedoch ausnahmsweise HTML-Tags darstel-
len mchte, muss sie oder er die spitzen Klammern umschreiben; < wird
z. B. zu $lt; und > zu &gt;.)
Und wieder grt die Datenbanktabelle
Auf los gehts los! Die Voraussetzungen fr unsere Datenbanktabelle sind
ganz hnlich wie beim Gstebuch. Fr die Tabelle schlage ich den Namen
cms vor. Als Feldnamen verwendest du id (Primrschlssel), Name (Name
des Weblogbesitzers), Headline (fr die berschrift), Datum (automati-
scher Datumsstempel) und Eintrag fr den eigentlichen Text.
Statt ausschweifender Felddatentyp-Diskussionen zeige ich dir lieber
gleich den entsprechenden SQL-Code. Richte die Datenbanktabelle mit
phpMyAdmin ein:

CREATE TABLE cms (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Name VARCHAR(35),
Headline VARCHAR(80),
Datum VARCHAR(30),
Eintrag TEXT
) DEFAULT CHARACTER SET utf8;

368
Weblog fr Kids: Das Mini-CMS

Kapitel
15
Auch hier bitte ich dich, schon im Vorfeld einen oder zwei Eintrge zu er-
stellen. Genau wie beim Gstebuch erwarte ich fr das Datum das Format:
0 24.04.2010, 16:00 Uhr
Denke dir auerdem fr jeden Eintrag eine sinnvolle berschrift aus. Ver-
wende bei mindestens einem Eintrag ruhig einen etwas lngeren Text.
Du kannst dabei sogar wenn du mchtest mit HTML-Code arbeiten. Da-
durch lassen sich beispielsweise Aufzhlungen erzeugen, Passagen hervor-
heben oder sogar Grafiken einfgen. (Wenn du Grafiken einfgst, fgst du
natrlich nur den Verweis auf die Grafik ein. Die Abbildung ldst du dann
separat mit auf den Server. Es ist nicht sinnvoll, Abbildungen in Datenbank-
tabellen zu sichern!)
An dieser Stelle ein ganz wichtiger Tipp! Erstelle fr dieses Projekt einen
separaten Ordner. Ich schlage den Namen cms vor. Lege diesen Ordner
unter dem Ordner htdocs ab. Fr diesen separaten Ordner gibt es meh-
rere Grnde: Zum einen wird es bei einigen der Dokumente Namens-
gleichheit mit schon erstellten Dateien geben. Das muss vermieden wer-
den, damit die alten Dateien nicht aus Versehen berschrieben werden.
Zum anderen soll die Startdatei des Blogs index.php heien. Der Trick
dabei: Der Apache-Webserver ist so eingestellt, dass eine Datei namens
index.php (ebenso wie index.html) automatisch als Startdatei auf-
gerufen wird. Du musst nur den jeweiligen Ordner aufrufen. Du tippst im
Beispiel also lediglich:
0 http://localhost/cms
und schon erscheint dein Weblog in Gestalt der index.php vor dir!
Schickes Design: Die Ausgabe
aller Daten
Als nchstes bereitest du die Seite so weit vor, dass die Daten ausgegeben
werden. Und zwar so attraktiv wie mglich! Ich zeige dir den ersten Stand
unserer index.php vorab. Danach besprechen wir alle Einzelheiten ganz in
Ruhe.
369
Schickes Design: Die Ausgabe aller Daten

Der Quellcode im berblick
Wenn du keine Lust zum Abtippen hast, kannst du dir diese Version auch
von der CD holen. Sie steckt im Pfad kapitel15/cms_version1.
<?php
include("edit/zugriff.inc.php"); // Zugriffsdatei einbinden
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="de">
<head>
<title>Unser Webtagebuch</title>
<meta http-equiv="content-type" content="text/html;
charset=utf-8">
<link rel="stylesheet" type="text/css" href="css/weblog.css">
</head>
<body>
<div id="wrapper">
<?php
include("admin.inc.php"); // Admin-Datei einbinden
?>
<h1>Unser Webtagebuch:</h1>
<div>[ <a href="index.php">Home</a> ]</div>

<?php
$start = 0; // Startwert setzen (0 = 1. Zeile)
$step = 2; // Wie viele Eintrge gleichzeitig?
$muster = "/^[0-9]+$/"; // reg. Ausdruck fr Zahlen
// Startwert verndern:
if (isset($_GET["start"])) {
if (preg_match($muster, $_GET["start"]) == 0) {
$start = 0; // Bei Manipulation Rckfall auf 0
} else {
$start = $_GET["start"];
}
}
$sql1 = "SELECT * FROM cms";
$sql2 = "SELECT * FROM cms ORDER BY id DESC LIMIT $start, $step";
$result1 = mysqli_query($db, $sql1);
$zeilen = mysqli_num_rows($result1);
$result2 = mysqli_query($db, $sql2);
echo "<p>Anzahl der Eintrge: $zeilen</p>\n";

370
Weblog fr Kids: Das Mini-CMS

Kapitel
15

// while-Schleife Anfang
while ($row = @mysqli_fetch_assoc($result2)) {
$Eintrag = nl2br($row["Eintrag"]);
// Eintrge anzeigen
echo "<h3>$row[Headline]</h3>\n" . "<p>$Eintrag</p>" .
"<div><small>eingetragen von <b>$row[Name]</b> " .
"am <strong>$row[Datum]</strong></small></div><br><br>\n";
} // while-Ende

// Link zu lteren Eintrgen einblenden
$start = $start + $step;
echo "<p>";
if ($start < $zeilen) { // if-Anfang
echo "[ <a href=\"index.php?start=$start\">&lt;&lt;
ltere Eintrge</a> ]";
}
echo "[ <a href='#wrapper'>nach oben</a> ]</p>\n";

mysqli_close($db);
?>
</div>
</body>
</html>

Hier noch ein schneller Tipp zur Notation! Viele Autoren gliedern ihren
Quellcode durch Einrckungen. Untergeordnete Strukturen, z. B. der Titel
<title></title> oder untergeordnete if-Abfragen usw. werden da-
bei durch Druck auf die []-Taste oder mit Leerzeichen eingerckt. (Ich
empfehle Leerzeichen!) Dadurch wird der Code besser lesbar, besser ver-
stndlich und klarer gegliedert. Auf die Programmausfhrung hat das
jedoch keine Auswirkung. Auch der Autor dieses Buches verwendet diese
Technik. Er gliedert zustzlich noch durch das Einfgen von Leerzeilen
vor besonders wichtigen Passagen. Denn auch leere Zeilen stren den
Programmablauf nicht und sorgen ebenfalls fr einen besseren berblick.
Wie man PHP-Code nun am besten einrckt, verraten wir dir natrlich
auch. Schaue auf die CD, in den Pfad dokumente\code_einrueckung.
Lies die Datei code_einrueckung.pdf. Dort findest du die wichtigsten
Regeln fr das Schreiben von bersichtlichem PHP-Code. Der Autor folgt
dabei dem sogenannten PEAR-Standard, den er brigens im Nachfolge-
buch ausfhrlich erlutert.
371
Schickes Design: Die Ausgabe aller Daten

Das Auge isst mit: Gestalten mit Style Sheets
Zuerst fangen wir ausnahmsweise nicht mit Programmierung an. Es geht
um die Gestaltung! Schaue dazu in die Zeile oberhalb des </head>-
Ausschalttags. Hier bindest du eine externe Style-Sheet-Datei namens
weblog.css ein:
<link rel="stylesheet" type="text/css" href="css/weblog.css">
Im Prinzip handelt es sich ja um unsere phpkid.css. Allerdings habe ich
sie weblog.css genannt, erweitert und im Unterordner css abgelegt.
Und nun schaue doch einmal in diese CSS-Datei weblog.css hinein!
Hintergrundgrafik einbinden
Zuerst habe ich die Stilregel fr body erweitert, also die Gestaltungsvor-
schrift fr das gesamte Dokument:
body {
font-family: Verdana, Arial, Helvetica, sans-serif;
background-image: url('bgyellow.gif');
}

Neu hinzugekommen ist die zweite Zeile. Diese bindet eine Hintergrund-
grafik namens bgyellow.gif in die Seite ein. Diese Grafik erzeugt das
durchgehende Linienmuster. Du findest die Grafik brigens auf der CD zum
Buch. Sie liegt im Ordner css.
Feste Breite, Rahmen und Innenabstand
Das sieht doch bis hierhin schon einmal nicht schlecht aus, oder? Aber das
ist noch nicht alles. Ich arbeite mit einem weiteren Gestaltungstrick. Ich
kleide den gesamten Inhalt wie schon beim Gstebuch in einen DIV-
Container ein. Das einleitende <div> sieht so aus: <div id="wrapper">.
Es besitzt also eine id und auf die kann ich mich in der CSS-Datei bezie-
hen. Und zwar so:
/* DIV-Container mit der id wrapper gestalten */
#wrapper {
width: 600px; /* Breite 600 Pixel */
border: solid 1px; /* dnner Rahmen drumherum */
background-color: white; /* Hintergrundfarbe wei */
padding: 10px; /* Innenabstand 10 Pixel */
}

372
Weblog fr Kids: Das Mini-CMS

Kapitel
15
Diesmal begnge ich mich jedoch nicht mit der Angabe der Breite. Mit
Hilfe von CSS verpasse ich meinem Weblog einen durchgehenden schwar-
zen Rand und die Hintergrundfarbe Wei. Dadurch hebt sich der eigentli-
che Schreibbereich von der Hintergrundgrafik ab.
Damit du diese Stilregel besser verstehst, habe ich alle Erklrungen in
Kommentare eingebunden: /* */. Mehr zu den tollen Mglichkeiten von
CSS erfhrst du wie schon erwhnt in CSS fr Kids von David Sigos.

Sinnvolle Ordnerstruktur: Die index.php liegt im Ordner cms, die CSS-Datei und die Hilfsgra-
fik wurden in den Ordner css ausgelagert. Der Ordner edit enthlt die gut geschtzten
Zugangsdaten.
Schaue es dir an! Damit sieht dein Weblog doch zumindest von der Optik
her schon ganz prima aus! Und eine exakte Breite besitzt es auerdem. Das
ist auch deshalb wichtig, damit die Eintrge nicht ins Endlose quillen.
Datenbankabfrage: Der MySQL-
Teil im berblick
Widmen wir uns nun dem Rest des Dokumentes. Gleich schaust du dir die
Datenbankabfrage an. Es ist gar nicht schwer, denn die meisten Details
kennst du schon. Doch zuvor gucken wir auf die Zeilen, die sich oberhalb
dieser Abfrage befinden.
Blttere beim Lesen immer wieder zu meinem Beispiel-Quellcode zurck!
373
Datenbankabfrage: Der MySQL-Teil im berblick

Zugriffsdaten und Administrationsdatei
Ganz oben binde ich per include("edit/zugriff.inc.php"); die
ausgelagerten Zugangsdaten fr meine Datenbank ein. Diesmal liegt die
zugriff.inc.php im Unterordner edit. Diesen Ordner habe ich zustz-
lich mit einer .htaccess-Datei vor Zugriffen von auen geschtzt. Safety
first Sicherheit geht eben vor! (Wenn dein Hoster dabei mitspielt.)
Und so sieht die aufgemotzte zugriff.inc.php aus:
<?php
$db = @mysqli_connect("localhost", "root", "")
or die("Verbindung zu MySQL gescheitert!");
mysqli_set_charset($db, "utf8");
@mysqli_select_db($db, "team")
or die("Datenbankzugriff gescheitert!");
$user = "Hanno"; // Benutzername
$pass = "jrZuRdx_Zt5l"; // Passwort
?>

Neu hinzugekommen sind die Variablen $user und $pass. Dort sichere ich
den Nutzernamen und das Passwort fr deinen Zugriff auf unser Weblog.
Whle vor allem dein Passwort mit Bedacht!
Das Passwort habe ich mglichst sicher gewhlt ich empfehle eine
Kombination von Buchstaben und Zahlen mit gemischter Gro- und
Kleinschreibung. Es gilt die Regel: mglichst lang, aber gut zu merken.
Auch die nchsten drei PHP-Zeilen zhlen zu den Vorbereitungen fr einen
spteren Projektstand. Hier binden wir ein weiteres Modul ein.
<?php
include("admin.inc.php"); // Admin-Datei einbinden
?>

Richte diese Datei namens admin.inc.php schon einmal ein und lege sie
in den gleichen Ordner. Notiere dort lediglich Folgendes der eigentliche
Inhalt kommt spter.
<?php

?>

Spter wird diese Datei den Code fr das Eingabeformular aufnehmen.
374
Weblog fr Kids: Das Mini-CMS

Kapitel
15
Home-Link
Und nun schaue dir folgende Zeile an sie beherbergt den Home-Link:
<div>[ <a href="index.php">Home</a> ]</div>

Dieser Link wird links oben auf der Seite platziert und erscheint damit auf
jeder Seite. Dadurch kann der Besucher jederzeit die Startseite aufrufen
(index.php) und sieht so wieder die neusten Eintrge.
Die Parameter $start und $step
Die darauffolgenden Zeilen haben wir vom Prinzip her schon beim Gste-
buch von Kapitel 14 besprochen. Der Wert $start dient zum Festlegen des
ersten anzuzeigenden Datensatzes. Dieser Wert wird mit 0 initialisiert. Die
Variable $step nimmt die Zahl der gleichzeitig anzuzeigenden Eintrge
entgegen. Im Beispiel habe ich mich fr 2 entschieden.
Der Wert $start wird nach Klick auf einen Link namens ltere Eintrge
stets um den Wert $step erhht, im Beispiel also um 2. Diese Dynamik
erfolgt du ahnst es schon wieder durch die bergabe eines URL-
Parameters. Der Wert wird durch ?start=Zahl bergeben und mit
$_GET["start"] ausgelesen. Auch hier gibt es wieder den obligatori-
schen Check, ob es sich um eine Zahl handelt. Dafr dient der ebenfalls
schon besprochene regulre Ausdruck.
Aus ursprnglich 0 wird nach Klick auf den Link eine 2. Auf diese Weise
knnen die 2 nchstlteren Datenstze eingeblendet werden. Alles funktio-
nier vom Prinzip her also genauso wie beim Gstebuch aus Kapitel 14.
SQL-Abfragen
Danach kommen die SQL-Abfragen. Es sind ebenfalls sinngem die glei-
chen wie beim Gstebuch.
$sql1 = "SELECT * FROM cms";
$sql2 = "SELECT * FROM cms ORDER BY id DESC LIMIT $start, $step";

Auch hier ermittle ich mit der ersten Abfrage (Variable $sql1) die Anzahl
aller Datenstze. Die zweite Abfrage jedoch ($sql2) liest beim ersten Auf-
ruf nur die ersten 2 Datenstze ein. Die 2 das ist schlielich der voreinge-
stellte Wert aus $step.
Darunter gebe ich schon einmal die Gesamtzahl der Eintrge aus. Das Gan-
ze wird wieder in einer Variablen namens $zeilen gespeichert. Diese Vari-
375
News von Gestern? ltere Eintrge anzeigen!

able werden wir fr unsere Navigationsleiste noch bentigen. Die eigentli-
che Ausgabe der Daten erfolgt dann innerhalb unserer berhmten while-
Schleife. Das Prinzip ist das gleiche wie beim Gstebuch:
// while-Schleife Anfang
while ($row = @mysqli_fetch_assoc($result2)) {
$Eintrag = nl2br($row["Eintrag"]);
// Eintrge anzeigen
echo "<h3>$row[Headline]</h3>\n" . "<p>$Eintrag</p>" .
"<div><small>eingetragen von <b>$row[Name]</b> " .
"am <strong>$row[Datum]</strong></small></div><br><br>\n";
} // while-Ende

Zuerst wird die berschrift ausgegeben, dann der eigentliche Text des Ein-
trags. Name und Datum wiederum werden diesmal unter dem Eintrag an-
gezeigt, und zwar in kleiner Schrift. Dafr sorgt das Tag-Paar
<small></small>.
News von Gestern? ltere
Eintrge anzeigen!
Schaue nun zum Code-Abschnitt unterhalb von Link zu lteren Eintrgen
einblenden. Dieser spezielle Link erscheint immer dann, wenn weitere Ein-
trge im Archiv schlummern. Durch Klick auf diesen Link holst du die
im Beispiel sind es zwei jeweils nchstlteren Beitrge aus dem Archiv.
// Link zu lteren Eintrgen einblenden
$start = $start + $step;
echo "<p>";
if ($start < $zeilen) { // if-Anfang
echo "[ <a href=\"index.php?start=$start\">&lt;&lt;
ltere Eintrge</a> ]";
}
echo "[ <a href='#wrapper'>nach oben</a> ]</p>\n";

Die erste Programmzeile addiert zum Startwert $start erst einmal $step
hinzu (im Beispiel wird 0 zu 2). Die zweite prft nun, ob dieser neue Start-
wert kleiner ist als die Gesamtzahl der Eintrge ($zeilen). Ist die Bedin-
gung wahr? Gibt es also weitere Eintrge, die angezeigt werden mssen?
Dann wird der Link ltere Eintrge erzeugt, der die Seite neu aufruft und
die nchstlteren Eintrge ausgibt. Damit aber der neue Startwert bei der
376
Weblog fr Kids: Das Mini-CMS

Kapitel
15
nchsten Abfrage bermittelt wird, wird der Startwert als Parameter ange-
hngt. Wenn der Nutzer also die nchsten zwei Werte anzeigen will, ruft
der Link folgende Adresse auf:
index.php?start=2

Beim darauffolgenden Mal (falls so viele Eintrge vorhanden sind), sieht
der Link dann so aus:
index.php?start=4

Die nchste Zeile ist zwar nicht unbedingt ntig. Doch ich nutze gleich die
Gunst der Stunde und fge einen Verweis nach oben ein.
echo "[ <a href='#wrapper'>nach oben</a> ]</p>\n";

Wenn der Surfer auf diesen Link klickt, landet sie oder er wieder ganz oben
auf der Seite. Dafr sorgt #wrapper, der interne Verweis auf dem <div>-
Container mit der id wrapper. Probiere es aus!

Blickst du durch? Wenn du beim Gstebuch mitgekommen bist, drfte dir
dieser Code zumindest bis hierhin nicht mehr so groe Schwierigkeiten
bereiten. (Einfach ist es aber trotzdem nicht, das gebe ich zu.)
Was bedeuten die Zeichen &lt;&lt; vor dem Text ltere Eintrge?
Das ist reine Optik! Mit diesen sogenannten Entitten erzeugst du zwei
Zeichen kleiner als: <<, also zwei kleine Pfeile.
Damit ist das Basis-Weblog fertig! Wenn du mchtest, kannst du das Pro-
jekt an dieser Stelle abbrechen. Neue Beitrge gibst du einfach ber php-
MyAdmin ein. Das Ergebnis bis hierhin findest du wie schon erwhnt im
Ordner cms_version1.
Mit Hilfe des
Parameters start
werden ltere Eintrge
eingeblendet.
377
Passwortschutz mit Cookie

Passwortschutz mit Cookie
Du willst weitermachen? Immer zu, es gibt viel zu tun! Im nchsten Schritt
erstellst du den Passwortschutz, also den Login-Bereich. Im Beispiel soll
ein Nutzer namens Hanno eintragsberechtigt sein. Das Passwort lautet
dabei jrZuRdx_Zt5l. Wir hatten beides ja schon einige Seiten zuvor in
der Datei zugriff.inc.php notiert.
Fr das Einloggen verwendest du ein Login-Formular mit zwei Formular-
feldern. Es soll aber nicht sofort ins Auge fallen. Aus diesem Grund habe
ich es dezent mit CSS formatiert. Die Formularfelder besitzen dnne,
hellgraue Rahmenlinien und einen transparenten Hintergrund. Sie sind
kaum zu erkennen. Der Submit-Button ist einfach nur ein Button ohne
Beschriftung. Die Schriftgre habe ich ebenfalls runtergeregelt.
Schaue in die dritte Stilregel der Datei weblog.css in die Regel, die
mit #logform input beginnt. Die id des Formulars heit logform.

Du bist mit CSS noch nicht so vertraut? Dann verweise ich erneut auf das
schon erwhnte CSS-Buch aus unserer Kids-Buchreihe.
Der Quellcode fr das Formular
Und hier zeige ich dir den Quellcode fr das Formular. Notiere den folgen-
den Code zwischen dem letzten ausschaltenden </div>-Tag und dem ab-
schaltenden </body>-Tag. Also ganz am Ende der Seite:
<form action="index.php" method="post" id="logform">
<input type="text" name="usr">
<input type="password" name="pwd">
<input type="submit" value="">
</form>

Das Login-Formular
wird dezent am Fu
der Seite versteckt.
378
Weblog fr Kids: Das Mini-CMS

Kapitel
15
Das Formular stellt fr dich inzwischen keine Hrde mehr da. Es besitzt
eine id namens logform. Die ist aber nur dazu da, damit das Formular per
CSS angesprochen und gestaltet werden kann. Ansonsten gibt es zwei Fel-
der namens usr und pwd. Dort trgst du deine Kenndaten ein. Daraus wer-
den nach Absenden die Variablen $_POST["usr"] und $_POST["pwd"]
und deren Inhalt kann man wunderbar auswerten. Doch wo und wie?
Ein Cookie als Merkwimpel
Wir werten diese beiden Variablen am Anfang des Skriptes aus! Wenn die
Daten korrekt sind, speichern wir den Eingeloggt-Zustand in einem
Cookie. Das Cookie dient dann praktisch als Merkwimpelchen. Nur bei
Vorhandensein dieses Cookies erscheint spter das Eingabeformular. Nur
wenn das Cookie existiert, werden die Daten in die Datenbanktabelle ge-
schrieben. Und damit das Cookie nicht ausspioniert werden kann, bleibt es
ein Sitzungscookie ohne Zeitangabe. Alles im Interesse der Sicherheit!
Das Ziel ist klar, doch nun zum Weg! Schreibe den Code zum Erzeugen des
Cookies. Notiere die Zeilen ganz oben im allerersten <?php ?>-Bereich.
Setze sie ein unterhalb von include("edit/zugriff.inc.php"); ...
und oberhalb von ?>. Und so sehen diese Zeilen aus:
if (!empty($_POST["usr"]) && !empty($_POST["pwd"])) {
if ($_POST["usr"] == $user && $_POST["pwd"] == $pass) {
// Nutzer hat sich eingeloggt? Cookie erzeugen!
setcookie("wlog", "we37jXp");
echo "<h3>[ <a href='index.php?form=1'>Daten
eintragen</a> ]</h3>";
}
}

So kryptisch diese Zeilen auf den ersten Blick auch aussehen sie sollten
dir einleuchten. Wir prfen, ob $_POST["usr"] und $_POST["pwd"]
nicht leer sind. Ein zweiter if-Block testet auf bereinstimmung mit Nut-
zernamen ($user) und Passwort ($pass) aus der zugriff.inc.php. (Da-
her haben wir die zugriff.inc.php auch ganz zuoberst eingebunden
damit diese Variablenwerte an dieser Stelle schon zur Verfgung stehen!)
Bei bereinstimmung setzt das Skript ein Sitzungscookie mit dem Namen
wlog und dem Wert we37jXp. Warum steht der Cookie-Code eigentlich
ganz oben? Weil ein Cookie am Seitenanfang gesetzt werden muss. Ver-
gleiche mit dem Cookie-Kapitel 9, wenn dir das noch unklar ist!
Du findest den Sachstand brigens im Ordner cms_version2.
379
So bindest du die Beitrge ein

So bindest du die Beitrge ein
Als Nchstes bentigen wir das Formular zum Eintragen der Daten. Und
dabei mache ich dich noch auf ein Detail der eben erwhnten Cookie-
Zeilen aufmerksam. Es handelt sich um diesen Link:
echo "<h3>[ <a href='index.php?form=1'>Daten
eintragen</a> ]</h3>";

Er erscheint nach erfolgreichem Einloggen und sieht so aus:

Besonders spannend ist der URL-Parameter form=1. Den lesen wir gleich
aus und reagieren darauf. Und zwar mit Einblenden des Eingabe-Formulars.
Dabei wird allerdings auch unser Cookie ein Wrtchen mitzureden haben.
Sonst htte das mit Sicherheit rein gar nichts zu tun!
Und wo wird das Formular aufgebaut? Na in der admin.inc.php, die du
schon als leere Datei vorbereitet hast!
Quellcode der admin.inc.php
Zuerst zeige ich dir den Quelltext der admin.inc.php auf einen Blick.
Wenn du mchtest, kannst du gleich lostippen. Diese merkwrdige Syntax
mit <<< besprechen wir danach ganz ausfhrlich.
<?php
// Formularerzeugung:
if (isset($_GET["form"]) && isset($_COOKIE["wlog"]) &&
$_COOKIE["wlog"] == "we37jXp") {
echo <<<FORMULARBEREICH
<p>Hallo <b>{$user}</b>, nimm deinen Eintrag vor!</p>
<form action="index.php" method="post">
<input type="hidden" name="Name" value="$user">
<strong>Headline</strong>:<br>
Der Link bergibt einen
URL-Parameter namens
form mit dem Wert 1.
380
Weblog fr Kids: Das Mini-CMS

Kapitel
15

<input type="text" name="Headline" size="50"><br>
Text (<small>HTML mglich</small>):<br>
<textarea cols="65" rows="15" name="Eintrag">
</textarea><br>

<input type="submit" value="Eintrag abschicken!">
</form>
FORMULARBEREICH;
}

// Eintrag der Daten
if (isset($_COOKIE["wlog"]) && $_COOKIE["wlog"] == "we37jXp"
&& !empty($_POST["Headline"]) && !empty($_POST["Eintrag"])) {

$Name = mysqli_real_escape_string($db, $_POST["Name"]);
$Headline = mysqli_real_escape_string($db, $_POST["Headline"]);
$Eintrag = mysqli_real_escape_string($db, $_POST["Eintrag"]);
$datum = date("d.m.Y, H:i") . " Uhr";
$sql = "INSERT INTO cms " .
"VALUES ('', '$Name', '$Headline', '$datum', '$Eintrag')";
mysqli_query($db, $sql);
echo "<h3>[ <a href='index.php'>Ausloggen</a> ]</h3>";
}
?>
Die erste if-Abfrage
Die erste lange Zeile ist gar nicht so schwer wie sie aussieht. Hier wird die
Variable $_GET["form"] auf Existenz geprft also der eben besprochene
URL-Parameter. Und die existiert nur, wenn der Nutzer auf Daten eintragen
geklickt hatte. Das ist aber nur der Einstieg. Auch unser eben gesetztes
Cookie muss existieren und den richtigen Wert besitzen. Erst dadurch errei-
chen wir die bei solchen Projekten dringend notwendige Sicherheit!
HTML in PHP mit heredoc
Doch was kommt danach? Was ist das fr ein merkwrdiges Gebilde?
echo <<<FORMULARBEREICH

Das ist eine ganz raffinierte Geschichte! Es handelt sich um den sogenann-
ten heredoc-Operator, der hier eingeleitet wird. Danach kannst du ganz
gewhnlichen HTML-Code notieren, und das innerhalb von PHP!
381
HTML in PHP mit heredoc

Diesen Operator schaltest du ein und nach getaner Arbeit wieder aus.
Dafr nutzt du das gleiche Schlsselwort, das du auch beim Einschalten
verwendet hast. Im Beispiel habe ich mir den Namen FORMULARBEREICH
ausgedacht. Die Ausschalt-Zeile muss deshalb auch FORMULARBEREICH;
lauten. Die gesamte heredoc-Syntax sieht im Beispiel also so aus:
echo <<<FORMULARBEREICH
beliebiger HTML-Code
FORMULARBEREICH;

Das Kunstwort heredoc ist die Abkrzung fr Here Document, Hier
beginnt das Dokument. Im Klartext: Du kannst innerhalb dieses
heredoc-Paares ganz normalen HTML-Quellcode schreiben. Das erspart
das echo vor jeder Zeile! Es gengt, wenn du in der einleitenden Zeile
echo <<<FREIERNAME schreibst und das Ganze am Schluss mit
FREIERNAME; beendest. Die Zeichenfolge FREIERNAME steht fr einen
frei von dir zu whlenden Namen. Dieser Name sollte nirgends innerhalb
des Quellcodes vorkommen.
Ich finde diesen heredoc-Operator ziemlich genial, weil du auf diese Art
und Weise PHP und HTML noch unkomplizierter miteinander mischen
kannst.
Du hast Probleme mit deinem heredoc-Abschnitt? Es funktioniert nicht
so, wie es soll? Beachte, dass die entsprechenden heredoc-Zeilen kei-
nesfalls eingerckt werden drfen. Du darfst auch keine Leerzeichen vor
oder nach einem dieser Operatoren setzen! Vergiss nicht das abschlie-
ende Semikolon hinter dem abschaltenden heredoc-Operator. Nach
der Zeile echo <<<FREIERNAME darf allerdings kein Semikolon gesetzt
werden. Und wie gesagt auch kein Leerzeichen! Nicht einmal aus Ver-
sehen!
Zugriff auf Variablen innerhalb von heredoc
Wie kannst du innerhalb von heredoc auf PHP-Variablen zugreifen?
Schlielich arbeitest du mit einem lupenreinen HTML-Bereich? Wie ge-
wohnt! Betrachte den heredoc-Bereich einfach als langen String, der fast
so reagiert, als stnde er innerhalb von doppelten Anfhrungszeichen. Fa-
zit: Notiere die Variable einfach da, wo du mchtest! (Du darfst sie sogar in
einfache oder doppelte Gnsefchen einkleiden!)
382
Weblog fr Kids: Das Mini-CMS

Kapitel
15
<p>Hallo <b>$user</b>, nimm deinen Eintrag vor!</p>

In dieser Zeile wird der Name aus der Variablen $user ausgelesen und in
einen freundlichen Begrungs-Satz geschrieben:

Und hier wird derselbe User in ein verstecktes Formularfeld geschrieben.
Das beste: Ich kann dabei doppelte (oder einfache) Gnsefchen verwen-
den, ohne diese vorher mit hsslichen Backslashs entwerten zu mssen.
Den Variablen macht das alles ebenfalls nichts aus:
<input type="hidden" name="Name" value="$user">

Der Sinn der Sache: Der Tagebuchschreiber muss nicht noch einmal seinen
Namen eingeben. Der Name wird einfach im Formularfeld zwischenge-
speichert und danach trotzdem in die Datenbanktabelle eingetragen.
Die Syntax zum Eintragen
Du hast den Tagebucheintrag in das Formular eingegeben? Dann mssen
die Daten natrlich noch abgeschickt werden. Schlielich sollen sie im
Endeffekt in der Datenbanktabelle landen. Das gelingt durch Klick auf die
Schaltflche Eintrag abschicken.
Damit wird das Dokument erneut aufgerufen. Fr die Eingabe selbst sorgt
nun der zweite Teil der Datei admin.inc.php. Dieser Teil wird schlielich
nur ausgefhrt, wenn die beiden Variablen $_POST["Headline"] und
$_POST["Eintrag"] nicht leer sind. Also immer nur dann, wenn ein Ta-
gebuchschreiber auch etwas in die Formularfelder eingetragen hat. Zuvor
jedoch erfolgt die Prfung, ob das besagte Cookie existiert.
// Eintrag der Daten
if (isset($_COOKIE["wlog"]) && $_COOKIE["wlog"] == "we37jXp"
&& !empty($_POST["Headline"]) && !empty($_POST["Eintrag"])) {
Freundliche Begrung:
Auch innerhalb von
heredoc werden Vari-
ablen interpretiert!
383
Mehr gefllig? Hier klicken!

Damit ist auch dieser Bereich bestens abgesichert.
Die folgenden Zeilen sorgen mit Hilfe der entsprechenden SQL-Anweisung
fr den Eintrag in die Datenbanktabelle cms. Nicht ohne die Werte vorher
zu escapen. (ber die Wichtigkeit von mysqli_real_escape_string()
haben wir uns im vorigen Kapitel ja lang und breit unterhalten.)
Um das Skript nicht weiter zu verkomplizieren, verzichte ich auf weitere
berprfungen der Werte. Mindestlnge, bereinstimmung mit einem
Suchmuster all das ist bei diesem Formular nicht ntig. Schlielich bist
du der einzige Nutzer und kommst erst nach dem Einloggen an das Formu-
lar. Und welchen Sinn wrde es ergeben, dein eigenes Weblog zu hacken?
Doch wozu ist diese Zeile von Nutzen?
echo "<h3>[ <a href='index.php'>Ausloggen</a> ]</h3>";

Das ist eine Art Sicherheitsabfrage! Denn auch du als gebter und einge-
weihter Nutzer knntest aus Versehen auf den AKTUALISIEREN-Schaltknopf
klicken. Ein Doppeleintrag wre die Folge! Durch die gro dargestellte Zeile
Ausloggen wird dieses Verlangen jedoch unterbunden.
Wer einmal der Verfhrung dieses Ausloggen-Links nachgegeben hat,
sieht wieder die Ursprungsfassung der Gstebuchseite. Die Reload-Gefahr
ist gebannt!
Diese Fassung des Weblogs findest du im Ordner cms_version3.
Mehr gefllig? Hier klicken!
Fast fertig! Das Weblog ist aber noch nicht ganz perfekt! Angenommen, die
Tagebuchschreiber gehren zur Spezies der ausufernden Poeten. Laber,
laber, laber du weit schon. Das tut vielleicht dir als Schreiber gut, da du
dir deinen ganzen Kummer endlich mal von der Seele schreiben kannst.
Doch ob das jeden Leser interessiert?
Soll der Leser gleich am Anfang mit der vollen Breitseite des gesamten
langen Artikel-Eintrags erschlagen werden? Nein! Ein paar Stze als An-
reier mssen gengen! Das bewahrt die bersicht. So kann der Betrachter
vorher anhand der ersten Stze besser entscheiden, welche Beitrge wirk-
lich lesenswert sind.
Deshalb habe ich zum krnenden Abschluss eine besondere Raffinesse ein-
gebaut. Arbeite mit einer automatischen Begrenzung der Artikellnge!
384
Weblog fr Kids: Das Mini-CMS

Kapitel
15

Nach 250 Zeichen wird der Text automatisch abgeschnitten.
Erst nach Klick auf den Link Alles lesen wird der gesamte Beitrag aufgeru-
fen! Dieser kann dann in voller Pracht dargestellt werden. Zuerst zeige ich
dir, welche nderungen ich im Quellcode der Datei index.php vorgenom-
men habe. Wir beginnen mit dem Abschneiden des Resteintrags.
Der Quellcode im berblick
Schaue in deine index.php. Bearbeite zuerst den Ausgabeteil innerhalb
der while-Schleife. Der ursprngliche Bereich sieht folgendermaen aus:
// while-Schleife Anfang
while ($row = @mysqli_fetch_assoc($result2)) {
$Eintrag = nl2br($row["Eintrag"]);
// Eintrge anzeigen
echo "<h3>$row[Headline]</h3>\n" . "<p>$Eintrag</p>" .
"<div><small>eingetragen von <b>$row[Name]</b> " .
"am <strong>$row[Datum]</strong></small></div><br><br>\n";
} // while-Ende

Und nun siehst du den gleichen Bereich mit den eingebauten nderungen.
// while-Schleife Anfang
while ($row = @mysqli_fetch_assoc($result2)) {
$Eintrag = nl2br($row["Eintrag"]);
// Eintragslnge krzen
if (strlen($Eintrag) > 250) {
$Eintrag = substr($Eintrag, 0, 250);
$Eintrag .= "... <br>";
385
Die Funktionen strlen() und substring()

$Eintrag .= "[ <a href='index.php?id=$row[id]'>" .
"Alles lesen</a> ]";
}
// Eintrge anzeigen
echo "<h3>$row[Headline]</h3>\n" . "<p>$Eintrag</p>" .
"<div><small>eingetragen von <b>$row[Name]</b> " .
"am <strong>$row[Datum]</strong></small></div><br><br>\n";
} // while Ende

Versuche, die nderungen so nachzuvollziehen. Versuche es! Du kannst
dafr auch die Datei index.php aus dem Ordner cms_version4 ffnen.
Dort habe ich exakt diese nderungen fr dich schon eingebaut.
Die Funktionen strlen() und
substring()
Nehmen wir den neuen Quellcode nun etwas genauer unter die Lupe. Dabei
spielen zwei ganz interessante Funktionen eine wichtige Hauptrolle.
Doch ehe diese neuen Funktionen die Bhne betreten, beginnt unser Ab-
schnitt mit einer Ouvertre, der Einleitung. Denn zuerst fange ich den
Haupt-Eintrag aus der Datenbank in einer Variablen namens $Eintrag
auf. Das erleichtert die bersicht!
Auerdem kann ich auf diese Weise gleich die Zeilenumbrche mit sichern.
Dafr sorgt wieder die Funktion nl2br().
$Eintrag = nl2br($row["Eintrag"]);

Nach diesem Vorspiel hat nun endlich die Funktion strlen() ihren groen
Auftritt. Diese Funktion macht dabei nichts weiter als die Lnge einer Zei-
chenkette zu ermitteln. Die Syntax sieht so aus:
strlen("String")

Diese Funktion gibt die Lnge eines Strings zurck. Dabei werden bri-
gens auch Leerzeichen mitgezhlt. Du kannst den String direkt innerhalb
der runden Klammern notieren. Viel hufiger wirst du jedoch eine Vari-
able zum Prfen bergeben. Und genau das macht die Funktion auch in
unserem Skript: strlen($Eintrag).
386
Weblog fr Kids: Das Mini-CMS

Kapitel
15
In der Zeile if (strlen($Eintrag) > 250) { wird geprft, ob der
Eintrag grer als 250 Zeichen ist. Nur dann soll schlielich die Krzung
erfolgen. Beim Krzen selbst erscheint eine weitere String-Funktion auf
der Bhne, und zwar die Funktion substr(). Diese schneidet gnadenlos
ganze Stcke aus unschuldigen Strings. Es ist eine Funktion mit drei Ar-
gumenten. Die Syntax sieht folgendermaen aus:
substr("String", Startposition, Lnge)

Gestartet wird beim Zhlen wieder bei der 0 die Arrays lassen gren.
Der erste Buchstabe eines Strings entspricht dabei der 0. Du mchtest aus
der Variablen $Eintrag die Zeichen zwischen 0 und 250 ausschneiden?
Dann sieht die Funktion so aus:
substr($Eintrag, 0, 250)

Und schon ergibt die folgende Zeile einen Sinn:
$Eintrag = substr($Eintrag, 0, 250);

Aus der Variablen $Eintrag schnippelst du die ersten 250 Zeichen heraus
und speicherst diese neue, verkrzte Zeichenfolge wieder in der Variablen
$Eintrag. So einfach ist das!
Jetzt folgt nur noch etwas Kosmetik, etwas Schminke, um in der Bh-
nensprache zu bleiben: Die folgende Zeile hngt ein paar Punkte an den
verkrzten Eintrag an und setzt danach einen Zeilenumbruch, ein
break. Alles aus optischen Grnden, damit der Eintrag nicht so abge-
hackt wirkt: $Eintrag.="... <br>";
Die nchsten beiden Zeilen erzeugen den Link Alles lesen. Dabei wird wie-
der zum einen die Hauptseite aufgerufen, die index.php. Diesmal hngt
jedoch der zustzliche Parameter id mit der entsprechenden id des Web-
log-Eintrags am Seitennamen dran:
$Eintrag .= "[ <a href='index.php?id=$row[id]'>" .
"Alles lesen</a> ]";

Du ahnst sicher wieder, dass hier eine neue GET-Variable im Spiel ist!
387
Die Funktionen strlen() und substring()


Variablenbergabe: Dieser Wert kann mit $_GET["id"] ausgelesen werden.
Die restlichen Zeilen geben den Weblog-Eintrag aus. Dabei wird natrlich
die neue Variable $Eintrag verwendet:
"<p>$Eintrag</p>" .

Probiere es aus. Zur Erinnerung: Du findest den aktuellen Stand auch im
Ordner cms_version4. Fehlt da etwa noch etwas?
Die letzte SQL-Abfrage erstellen
Tatsache, der Text wird gekrzt angezeigt. Die Pnktchen erscheinen. Auch
der Link Alles lesen ist da. Alles tutti paletti? Mitnichten! Denn nach Klick
auf den Link Alles lesen passiert erst einmal berhaupt nichts! Logisch!
Es fehlt schlielich der letzte Teil des Skriptes. Es fehlt der Teil, der den
passenden Eintrag zur id ausgibt. Also unseren kompletten, ungekrzten
Beitrag!
Na dann ran an die Buletten! Fge zwischen diesen Passagen:
if (isset($_GET["start"])) {
if (preg_match($muster, $_GET["start"]) == 0) {
$start = 0; // Bei Manipulation Rckfall auf 0
} else {
$start = $_GET["start"];
}
}
hier neuen Code einfgen ...
$sql1 = "SELECT * FROM cms";

folgenden Abschnitt ein:
if (isset($_GET["id"])) {
if (preg_match($muster, $_GET["id"]) == 0) {
die("<p>Abbruch wegen Manipulation!</p></div></body></html>");
} else {
$id = $_GET["id"];
}
388
Weblog fr Kids: Das Mini-CMS

Kapitel
15

$sql = "SELECT * FROM cms WHERE id=$id";
$result = mysqli_query($db, $sql);
$row = @mysqli_fetch_assoc($result);
echo "<h3>$row[Headline]</h3>\n" .
"<p>" . nl2br($row["Eintrag"]) . "</p>" .
"<div><small>eingetragen von <b>$row[Name]</b> am " .
"<strong>$row[Datum]</strong></small></div><br>\n";
echo "[ <a href='javascript:history.back()'>Zurck</a> ]";
} else {

Vergiss nicht, den zustzlichen else-Zweig wieder zu schlieen. Setze
deshalb ber der Zeile
mysqli_close($db);

eine schlieende geschweifte Klammer:
}
mysqli_close($db);

Alles klar? Den entsprechenden SQL-Teil msstest du dir inzwischen gut
erschlieen knnen:
$sql = "SELECT * FROM cms WHERE id=$id";

Ich arbeite mit einer WHERE-Klausel. Dabei gebe ich nur den Datensatz
aus, der der jeweiligen id entspricht. Und auch die folgenden Zeilen sind
inzwischen hoffentlich klar. Doch was verbirgt sich hinter dieser Zeile?
echo "[ <a href='javascript:history.back()'>Zurck</a> ]";

Hier arbeitet der Autor mit einem Trick, um das Skript nicht noch weiter
zu verkomplizieren. Ein einfacher JavaScript-Link fhrt wieder zurck zur
vorigen Seite. Dafr sorgt javascript:history.back(). Das Schls-
selwort javascript: besagt, dass eine JavaScript-Anweisung folgt. Die
eigentliche Anweisung steckt in history.back(), also in gehe einen
Schritt in der History zurck. Das entspricht dem Klick auf den BACK-
Button. Wenn du diesen Code hinter dem Attribut href notierst, fhrt
dich das wieder zurck zu der Seite, die du vorher auf deinem Bildschirm
hattest. Simpel und wirkungsvoll zugleich!
389
Schlussbemerkung


Nach Klick auf Zurck landet der Besucher wieder auf der vorherigen Seite.
Diese Version des Skriptes findest du im Ordner cms_version5 auf der
Buch-CD. Ich habe zustzlich die Einrckung noch etwas angepasst. Denn
auch der Inhalt eines else-Zweiges sollte schlielich etwas eingerckt
werden.
Schlussbemerkung
Du hast es geschafft! In diesem Kapitel hast du ein richtiggehendes Weblog
programmiert. Damit bist du fast ohne es zu merken in die Geheimnisse
von Content Management eingedrungen. Du kannst Inhalte managen.
Du gibst Artikel (Tagebucheintrge usw.) ein, bewahrst diese in einer Da-
tenbank auf und sorgst fr die attraktive Ausgabe.
Zusammenfassung
0 Du weit, wie du eine Seite mit Style Sheets attraktiv gestalten kannst.
Du arbeitest mit Rahmeneffekten und Farben.
0 Du kennst den Operator heredoc, mit dem du auf simple Weise HTML-
Abschnitte in PHP einbindest.
0 Du weit, dass du innerhalb von heredoc wie gewohnt auf PHP-
Variablen zugreifen kannst.
390
Weblog fr Kids: Das Mini-CMS

Kapitel
15
0 Du kennst die Funktion strlen("String") zur Ermittlung der Lnge
eines Strings.
0 Du verwendest die Funktion substring("String", Startposi-
tion, Lnge), mit dem du einen bestimmten Teilbereich eines Strings
ausgeben kannst.
0 Du kennst die JavaScript-Anweisung history.back(), die den Besu-
cher zurck zur vorher besuchten Seite fhrt.
Ein paar Fragen
1. Was bedeutet das Wort Content?
2. Welche Funktion ermittelt die Lnge eines Strings?
3. Aus welcher Programmiersprache stammt denn die Anweisung
history.back() und was bewirkt sie?
und ein paar Aufgaben
1. Bisher wird das Einlogg-Cookie nicht gelscht. Das ist im Prinzip nicht
schlimm, denn es verfllt nach dem Schlieen des Browserfensters.
Trotzdem mchtest du mehr Sicherheit. Richte es also so ein, dass das
Cookie nach Absenden der Daten gleich mit gelscht wird. Tipp: Das
tust du unterhalb der Stelle, an der du das Cookie setzt.
2. Wir haben zwar mit mysqli_real_escape_string() dafr gesorgt,
dass die Daten vor dem Eintrag in die Datenbanktabelle escaped wer-
den. Wir haben jedoch keine Rcksicht auf rckstndige Webhoster ge-
nommen, bei denen magic quotes noch eingeschaltet ist. Baue eine
zustzliche Routine ein, die diesen Schalter abfragt und im Zweifelsfall
ein doppeltes Escapen (fhrt zur Anzeige von Backslashs vor Anfh-
rungszeichen) verhindert.
3. Noch eine schwere Aufgabe! Schaue nach unten im Weblog: Fge in
den Bereich zum Blttern zu lteren Eintrgen ei-
nen weiteren Link ein, mit dem du auch wieder
nach vorne blttern kannst! berlege, wie der
entsprechende GET-Wert aussehen muss und
welche Bedingungen du formulieren musst. Tipp: Es ist nicht so kompli-
ziert wie beim Link zu den lteren Eintrgen! Wenn dus schaffst, bist
du schon sehr gut.
391



16
Aktivitten verwalten:
Wer kommt mit ins Kino?
Wer kommt mit ins Kino? Nehmen wir als Beispiel einen Filmklub! Nehmen
wir weiterhin an, dass du fr die Organisation verantwortlich bist. Du
schlgst die Termine vor. Du nimmst die Kartenwnsche deiner Kumpels
und Teammitglieder entgegen. Du besorgst zum Schluss die Karten und alle
sind glcklich und zufrieden. Wirklich alle? Du auch? Das Besorgen der
Tickets selber ist sicher das kleinere Problem. Doch die Vorarbeit? Die ist
sehr undankbar! Deine Kumpels bestrmen dich: Hast du mich schon auf-
geschrieben? Ich will auch ein Ticket. Denke an die Karte fr meine
Freundin. Wann findet der nchste Kinotreff noch mal statt?
Dieser Verwaltungskram nervt! Und am Ende stehst du mit den zu viel ge-
kauften Eintrittskarten da und bleibst auf dem Geld sitzen. Schluss mit den
Strichlisten, Schluss mit der Zettelwirtschaft! Self Service lautet die Devise.
Wozu gibt es schlielich Webformulare und Datenbanken? In diesem Kapi-
tel zeige ich dir, wie du
$ Informationen auf mehrere Tabellen aufteilst
$ die Adressliste alias Kundendatei einbindest
$ eine Tabelle fr die Veranstaltungen schreibst
$ die Bestellwnsche in einer weiteren Tabelle festhltst
$ mehrere Tabellen miteinander verbindest
$ Daten aus mehreren Tabellen gleichzeitig abfragst
392
Aktivitten verwalten: Wer kommt mit ins Kino?

Kapitel
16 Das Adressbuch bekommt
Gesellschaft
Du musst zufllig gerade keine Kinonachmittage organisieren? Das macht
nichts. Du kannst das Beispiel auch als Anmeldeformular fr einen Vortrag,
fr die Disko oder selbst als Basis-Skript fr einen Online-Shop verwenden.
Die Teammitglieder sind deine Kunden. Die Veranstaltungen werden zu den
Produkten. Wie auch immer im Endeffekt entsteht ein kleines Bestellsys-
tem, welches du beliebig ausbauen kannst.
Um deine Kunden musst du dich in unserem Fall nicht mehr kmmern.
Die liegen schon fest. Das sind die Klassenkameraden, Teammitglieder oder
Vereinskumpels. Also diejenigen, die wir in Kapitel 13 schon in unsere Ta-
belle adressen eingetragen haben. Okay, das war jetzt eine ganz unmiss-
verstndliche Aufforderung, schnell noch einmal in Kapitel 13 nachzu-
schlagen!
Adresstabelle und Kundennummer
Hier zeige ich dir fix noch einmal die Grundstrukur der Datenbanktabelle
adressen. Du siehst die Feldnamen und die ersten beiden Datenstze.
id Vorname Name Str PLZ Ort Tel EMail WWW Notizen
1 Hans Meier Waldweg 7 12345 Neustadt 234567 hans@lexi.
de
www.lexi.
de

2 Martina Weber Waldweg 2 12345 Neustadt 234568 martina
@lexi.de
mag
Kaugummis

Besonders wichtig ist hierbei die Spalte id, also die eindeutige Kennung
jedes Datensatzes. Zur Erinnerung: Dieses Datenfeld wird als Primrschls-
sel bezeichnet. Diese eindeutige Kennung teilst du deinen Klassenkamera-
den bzw. Kumpels mit. Betrachte diese Nummer als eine Art Nutzer-ID
bzw. Kundennummer wie dir gerade zumute ist. Nur wer seine Nutzer-
ID kennt, kann sich auch fr Veranstaltungen vormerken lassen bzw. Pro-
dukte bestellen. Und wer noch nicht in deiner Tabelle steht, sollte von dir
schleunigst nachgetragen werden!
Tipp fr die Weiterentwicklung: Du kannst das Adressen-Beispiel aus Ka-
pitel 13 auch so umndern, dass es als Anmeldeformular fr Neukunden
dient. Jedem Kunden wird nach Registrierung (= Eintrag in die Daten-
bank) seine Kundennummer (eben diese id) eingeblendet.
393
Das Adressbuch bekommt Gesellschaft

Datenbanktabelle mit den Veranstaltungen
Die Datenbanktabelle steht. Als nchstes bentigst du nun eine Tabelle, in
die du die Veranstaltungen eintrgst. Also die Kinofilme, Vereinsnachmitta-
ge, Klassenfahrten oder was auch immer. Du mchtest schlielich die Akti-
vitten prsentieren, deine Produkte.
Schau dir meinen Vorschlag an. Im Beispiel handelt es sich zwar nur um
die Produktprsentation eines Filmklubs. Wie du siehst, habe ich die
Struktur jedoch so gehalten, dass du sie leicht an deine Bedrfnisse anpas-
sen kannst.
id Titel Untertitel Beschreibung Preis
1 Film- bzw. Produkttitel,
max. 100 Zeichen
Hier kann eine kurze
Beschreibung hin (max.
200 Zeichen)
Dieser Platz ist fr eine
ausfhrliche Beschrei-
bung vorgesehen.
Zahlenwert, auch
mit Nachkomma-
stellen, z. B. 4

Fr diese Datenbanktabelle schlage ich den Namen produkte vor.
Die Wahl der Felder ist selbsterklrend. Auch bei dieser Tabelle gibt es wie-
der das obligatorische Schlsselfeld fr die eindeutige Kennung. Es heit
hier ebenfalls id.
Weiterhin plane ich ein Feld fr den Titel und eins fr den Untertitel. Das
verleiht mir mehr Flexibilitt. Die Beschreibung darf natrlich nicht fehlen,
sie bekommt den grten Platz. Und da Kinokarten in der Regel etwas kos-
ten, gibt es schlielich ein Feld fr den Preis. Das wars dann auch schon.
Die Struktur der Datenbanktabelle produkte
Halt, halt! Bisher habe ich dir zwar die Struktur der Tabelle erlutert. Aber
ehe du die Datenstze eintragen kannst, musst du die Tabelle erst einrich-
ten. Rufe phpMyAdmin auf, wie in den vorigen Kapiteln besprochen. Erzeu-
ge die Datenbanktabelle produkte. Bei dieser Gelegenheit entscheidest du
dich gleich fr die richtigen Felddatentypen.
Und mit diesen Befehlen erstellst du nun die Datenbanktabelle:
CREATE TABLE produkte (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Titel VARCHAR(100),
Untertitel VARCHAR(200),
Beschreibung TEXT,
Preis FLOAT
) DEFAULT CHARACTER SET utf8;
394
Aktivitten verwalten: Wer kommt mit ins Kino?

Kapitel
16
Die Felddatentypen sind dir gelufig? Ich verwende INT, VARCHAR und
TEXT. Fr den Preis empfehle ich auerdem den Datentyp FLOAT. Dieser
erlaubt eine Kommazahl mit ausreichender Genauigkeit.

Der SQL-Befehl wurde erfolgreich ausgefhrt die Tabelle existiert!
Ein paar Vorschlge fr die Datenbanktabelle
Und nun trgst du mit phpMyAdmin die Produkte in deine Filmtabelle
ein. Datum und Uhrzeit habe ich gleich mit in das Titelfeld hineingeschrie-
ben, um ein eigenes Feld zu sparen.
Wir wollen es nicht unntig verkomplizieren. Wenn du dir unsicher bist,
bernimmst du meine Daten exakt genau so. Du findest sie auch auf CD:
Schaue in die Datei filmklub.rtf unter beispiele/kapitel16. Die
etwas Mutigeren knnen natrlich eigene Beispiele whlen. Vielleicht lei-
test du ja keinen Filmklub, sondern den Handballverein?

id Titel Untertitel Beschreibung Preis
1 Momo, 12. Mai,
17:00 Uhr
Spielfilm nach dem
Roman von Michael
Ende, mit Mario
Adorf und Radost
Bokel, Deutschland
1986
Momo lebt in einem alten
Amphitheater und ist bei
den Bewohnern der Stadt
sehr beliebt. Doch dann
treffen die grauen Herren
in der Stadt ein und steh-
len die Zeit.
4
2 Moritz in der
Litfasule,
25. Mai,
17:00 Uhr
Spielfilm nach dem
Roman von Christa
Kozik, Deutschland
1983
Wie ein kleiner Junge vor
der Welt der Erwachsenen
flieht und in einer Litfa-
sule auf eine sprechende
Katze trifft.
3
3 Gritta von Rat-
tenzuhausbeiuns,
1. Juni, 20:00 Uhr
Mrchenfilm mit
Nadja Klier und
Hermann Beyer,
Deutschland 1984
Liebenswerte, sehr auf-
wendige Verfilmung des
Mrchenromans von Betti-
na und Gisela von Arnim.
3
395
Ist das noch normal? Daten aufteilen!


Trage die Daten mit phpMyAdmin in die Datenbanktabelle ein.
Ist das noch normal? Daten
aufteilen!
Halten wir fest: Fr dein Bestellsystem stehen dir bisher folgende Daten-
banktabellen zur Verfgung:
0 adressen (deine Kundenliste)
0 produkte (die Produkttabelle)
Das ist schon einmal sehr sinnvoll. Damit trennst du Kunden und Produkte
auf ideale Weise voneinander und schaffst dadurch eine klare Struktur.
Auch die Idee, die id der Tabelle adressen praktisch als Kundennummer
zu verwenden, ist so einfach wie genial. hnlich halten wir es mit den
Filmveranstaltungen. Auch hier wird die id zur Kennung, zu einer Art Pro-
duktnummer.
Daten in Teiltabelle zerlegen
Und genau an dieser Stelle fngt Datenbankdesign endlich an, so richtig
spannend zu werden: Du arbeitest nicht nur mit einer, sondern gleich mit
mehreren Teiltabellen. Warum? Auf diese Weise sicherst du, dass alle diese
Daten nur einmal erfasst werden mssen. Nehmen wir einmal die Adressen.
Stell dir vor, es gbe diese zentrale Adresstabelle nicht.
Stell dir weiterhin vor, die Kunden mssten ihre Adresse bei jeder Bestel-
lung neu eingeben. Was da fr ein Chaos entsteht! Dadurch bekommst du
lange und unbersichtliche Listen. Vielbesteller z. B. sind ganz oft in der
Liste enthalten jedes Mal mit einer neuen id. Wo bleibt da die eindeutige
396
Aktivitten verwalten: Wer kommt mit ins Kino?

Kapitel
16
Kennung? Aber es kommt noch schlimmer! Denke auch an Verschreiber. Der
Kunde schreibt bei der zehnten Bestellung den Nachnamen in der Eile aus
Versehen klein? Schon ein falsches Zeichen sorgt schlimmstenfalls fr kun-
terbunte Verwechslungen mit anderen Personen!
Wie bitte, ich soll hier nicht schwarz malen? Die Gefahr besteht bei deiner
Hand voll Teammitglieder nicht? Bei Datenbanken musst du stets das
groe Ganze vor Augen behalten! Welcher Betreiber eines groen Online-
shops kennt schon alle seine Kunden persnlich? Bei hunderten oder tau-
senden von Adressen fhrt schon die kleinste Unstimmigkeit zum komplet-
ten Chaos!
Merke: Bei groen Datenbankprojekten wird man stets mit mehreren
Teiltabellen arbeiten. Dadurch erspart man sich die unsinnige Mehrfach-
erfassung von Daten. Auf diese Weise knnen Fehlerquellen von vornher-
ein ausgeschlossen werden. Eine Adresse lsst sich leichter updaten,
wenn sie genau einmal statt zehnmal in deiner Datenbank auftaucht.
Produktlisten knnen bequem bearbeitet und erweitert werden, wenn es
eine separate Tabelle dafr gibt. Dieser Vorgang des Zerlegens wird auch
als Normalisieren bezeichnet. Man redet davon, die Tabelle in ihre Ato-
me zu zerlegen. Und diese galten noch bis vor einer Weile zumindest
wollte uns das unser Chemielehrer damals weismachen als unteilbar.
Auch die Bestellungen mssen in eine
separate Tabelle!
Kunden und Produkte sind ja ganz schn und gut. Die haben wir von vorn-
herein in separaten Tabellen gespeichert. Doch was machst du mit den
Bestellungen? Auch dafr richtest du natrlich eine separate Liste ein.
Diese Tabelle nennst du im Beispiel
0 bestellungen
Sie dient im Beispiel einzig und allein dem Zweck, die Bestellungen festzu-
halten. Dich interessiert folgendes:
0 Wer hat sich angemeldet (Kunde)?
0 Welches Event/Produkt wurde ausgewhlt (Produkt)?
0 Wie oft wurde das Produkt gebucht (Anzahl)?
0 Wann wurde die Bestellung aufgegeben (Datum)?
397
Ist das noch normal? Daten aufteilen!

In der Krze liegt die Wrze. Auch in dieser Tabelle speicherst du nur das
Ntigste. Es wre Unsinn, hier noch einmal die gesamten Produktdaten
mit Titel, Untertitel und Beschreibung zu notieren. Es wre quatsch, alle
Besteller in voller Tabellenpracht noch einmal aufzulisten. Normalisie-
ren (Zerlegen) lautet die Devise! Wozu haben wir denn unsere pfiffigen
id-Angaben? Statt alle Produktdaten zu notieren, reicht die id der Da-
tenbanktabelle produkte. Dort sind schlielich alle Details hinterlegt!
Auch von den Kundendaten interessiert dich nur die id. Die volle Adres-
se steckt schlielich in der Tabelle adressen.
Hier zeige ich dir nun meinen Entwurf der Tabelle bestellungen. Beachte,
dass ich auch dieser Tabelle wieder eine eindeutige Kennung verpasse.
Auch hier gibt es also einen eigenen Primrschlssel namens id:
Fr die fremden IDs habe ich mir dagegen einen anderen Feldnamen aus-
gedacht, damit es nicht zu Verwechslungen kommt:
id aid pid Anzahl Datum
1 Feld id aus Tabelle
adressen
Feld pid aus Tabelle
produkte
Ganzzahl Datumsstempel kann mit Funktion
date() erzeugt werden

Es handelt sich bei diesen Fremd-IDs um die beiden Felder aid (adressen
id) und pid (produkte id). Der zustzliche Buchstabe a bzw. p steht also fr
die Tabelle adressen bzw. produkte.
Die Tabelle bestellungen vorbereiten
Ran an phpMyAdmin. Mit folgenden SQL-Befehlen bereitest du nun die
letzte Tabelle vor. Diese richtest du, wie alle Tabellen, in der Datenbank
team ein.
CREATE TABLE bestellungen (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
aid INT,
pid INT,
Anzahl INT,
Datum VARCHAR(30)
) DEFAULT CHARACTER SET utf8;

Diesmal hat der Felddatentyp INT seinen groen Auftritt. Die entsprechen-
den Schlsselfelder (der eigene Primrschlssel bzw. die Schlsselfelder der
anderen Tabellen) sowie die Anzahl sind schlielich Ganzzahlen.
398
Aktivitten verwalten: Wer kommt mit ins Kino?

Kapitel
16
Zur Verdeutlichung habe ich schon zwei Datenstze eingetragen. Das musst
du natrlich noch nicht tun. Schlielich weit du nicht unbedingt vorher,
wer sich nun fr welchen Film interessiert.
id aid pid Anzahl Datum
1 1 1 2 05.05.2010, 12:15
2 2 3 1 15.05.2010, 14:22
Beziehungskiste So hngen die Daten
voneinander ab
Mache dir ruhig einmal klar, wie diese drei Tabellen voneinander abhngen.
Zur Veranschaulichung habe ich eine kleine Abbildung erstellt:

Die Datenbanktabelle bestellungen hngt direkt von den Tabellen
adressen und produkte ab. Alle Tabellen gehren also zusammen.
Der Vorteil liegt auf der Hand: Es werden keine Daten doppelt gesichert. Es
gibt genau eine Tabelle fr die Kunden, genau eine Tabelle fr die Produkte
und genau eine Tabelle fr die Bestellungen!
In diesem Beispiel sprechen Datenbankexperten brigens von einer 1:n-
Beziehung. Einem Kunden knnen n Bestellungen zugeordnet werden.
(Mge er mglichst oft deine Kinofilme buchen!) Ein Film bzw. Produkt
kann theoretisch unzhlige Male gebucht werden. Zumindest gilt das,
solange Vorrat bzw. Sitzpltze reichen.
Jede Tabelle hat ihre
eigenen Aufgaben.
399
Nicht vergessen: Das Eingabeformular

Nicht vergessen: Das
Eingabeformular
Deine drei Tabellen fr das Bestellsystem sind fertig. Hervorragend! Es fehlt
allerdings noch eine Klitzekleinigkeit. Wie gelangen die Daten in die Tabelle
bestellungen? Natrlich durch eine Webseite, auf der du die Veranstal-
tungen prsentierst. Und durch das entsprechende Eingabeformular.
Auch hier heit es: Planen, planen, nochmals planen. Wie gehen wir vor?
Diesmal schlage ich zur Abwechslung eine andere Struktur vor. Du arbei-
test nicht mit einer, sondern mit drei PHP-Seiten. Auf der ersten Seite
kann der Besucher seine Bestellung aufgeben.
Diese Seite nenne ich:
0 index.php
Durch diese Benennung erscheint die Seite brigens wieder genau dann,
wenn du den entsprechenden Ordner im Browser aufrufst! Nach Klick auf
den Button JETZT ANMELDEN werden die Auswahldaten an eine zweite Seite
geschickt namens
0 order.php
Dort besttigt der Kumpel seine Auswahl. Dann muss sie oder er Benutzer-
ID (Kundennummer) und Nachnamen eingeben. Diese Seite schickt alle
Daten zum Schluss an eine weitere Seite namens:
0 input.php
Hier werden letztendlich die Daten nach erfolgreicher berprfung in die
Tabelle eingetragen! Soweit die Theorie. Das Ganze setzen wir jetzt ge-
meinsam in die Praxis um!
Projektordner und Datei index.php
>
Richte dir einen eigenen Projektordner ein namens order. Diesen
platzierst du im Beispiel direkt unter dem Ordner C:\xampp\htdocs.
>
Kopiere die schon in den vorigen Kapiteln verwendete Datei
zugriff.inc.php in einen extra Ordner namens edit. Diesmal be-
ntigst du nur die Zugriffsdaten fr MySQL, keinen Benutzernamen
und kein Kennwort. Nimm die zugriff.inc.php aus Kapitel 14!
400
Aktivitten verwalten: Wer kommt mit ins Kino?

Kapitel
16
>
Bereite auerdem eine Seite namens index.php vor. Ich empfehle
folgendes Grundgerst:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="de">
<head>
<title>Veranstaltungen des Filmklubs</title>
<meta http-equiv="content-type" content=
"text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="css/order.css">
</head>
<body>
<div id="wrapper">
<h1>Kommst du mit ins Kino?</h1>
<p>Bitte entscheide dich fr die gewnschte Veranstaltung
und whle die <b>Anzahl der Karten</b>! Halte auerdem
deine <b>Benutzer-ID</b> bereit!</p>
... Hier kommt der PHP-Teil hin!
</div>
</body>
</html>

Wie du bemerkst, lehne ich mich an das bewhrte Layout des Content Ma-
nagement Systems aus dem vorigen Kapitel an. Auch hier arbeite ich mit
einer externen CSS-Datei, die wieder im Unterordner css liegt. Sie heit
diesmal order.css. Es handelt sich dabei um eine abgespeckte Variante
der weblog.css aus dem vorigen Kapitel. Wir geben hier die exakte Breite
des DIVs vor wieder mithilfe der id wrapper. Auf die Hintergrundgrafik
habe ich jedoch verzichtet. Schaue einfach mal in die order.css rein!
Auch diesmal gehe ich nach der Taktik vor: Schritt fr Schritt, Seite fr
Seite. Und das Testen nicht vergessen!
Der PHP-Teil im berblick
Auf zum nchsten Schritt. Fge nun den PHP-Teil ein. Hier zeige ich dir
meinen Vorschlag. Diesen findest du natrlich wie auch das gesamte
Projekt im entsprechenden Kapitel-Ordner auf der CD.
Inzwischen drfte es dir nicht mehr schwer fallen, den Code zu durch-
schauen. Wie schon bei den vorhergehenden MySQL-Beispielen werden die
Eintrge aus der Datenbank ausgelesen und optisch prsentiert.
401
Nicht vergessen: Das Eingabeformular

Aus Bequemlichkeit arbeiten wir dabei wieder mit der heredoc-Syntax.
Erinnerst du dich? Im vorigen Kapitel habe ich dich darber aufgeklrt.
Der Heredoc-Bereich wird mit echo <<<FORMULARBEREICH eingeleitet
und mit FORMULARBEREICH; abgeschlossen. Der Bereich wirkt wie ein
String. Um hier Array-Variablen auslesen zu knnen, lsst du normaler-
weise die Gnsefchen um den key weg. Um die id des Produkts zu
ermitteln, schreibst du $row[id]. Aber es gibt noch einen Trick. Setze
die Variable in geschweifte Klammern: {$row['id']}. Dann knnen die
Gnsefchen um den Array-Key bleiben egal ob doppelt oder einfach.
Und hier zeige ich dir den entsprechenden Quelltext. Fge ihn an der Stelle
ein, die wir weiter oben extra dafr freigelassen hatten. Auf Einrckungen
verzichten wir im Beispiel mit Rcksicht auf den Heredoc-Bereich.
<?php
include("edit/zugriff.inc.php");
$sql = "SELECT * FROM produkte";
$result = mysqli_query($db, $sql);
$zeilen = mysqli_num_rows($result);
echo "<p>$zeilen Eintrge:</p>\n";
// WHILE AUF
while ($row = @mysqli_fetch_assoc($result)) {
// HEREDOC beginnt
echo <<<FORMULARBEREICH
<h2>{$row["Titel"]}</h2>
<div><strong>{$row["Untertitel"]}</strong><br>
{$row["Beschreibung"]}<br>
Kosten: <b>{$row["Preis"]} Euro</b></div>
<form action="order.php" method="post">
Anzahl:
<input type="text" name="Anzahl" size="3" value="1">
<input type="hidden" name="id" value="{$row['id']}">
<input type="hidden" name="Titel" value="{$row['Titel']}">
<input type="submit" value="Jetzt anmelden &gt;&gt;"
name="sm1">
</form>
<hr>
FORMULARBEREICH;
// HEREDOC ENDE
} // WHILE ZU
mysqli_close($db);
?>
402
Aktivitten verwalten: Wer kommt mit ins Kino?

Kapitel
16

Die Auswahl des Filmes alias Produkts erfolgt durch ein Formular. Das For-
mular erfasst Anzahl und ID. Die ID und der Titel werden dabei jeweils in
ein verstecktes Formularfeld geschrieben:
<input type="hidden" name="id" value="{$row['id']}">
<input type="hidden" name="Titel" value="{$row['Titel']}">


Der SUBMIT-Button bekommt ganz absichtlich einen Namen verpasst.
<input type="submit" value="Jetzt anmelden &gt;&gt;"
name="sm1">

Diese Anweisung name="sm1" dient vor allem der Wiedererkennung auf
der nchsten Seite. Denn nach Klick auf JETZT ANMELDEN reicht das Formular
seinen Inhalt schlielich an die Seite order.php weiter. Und diese nchste
Seite schauen wir uns nun gemeinsam an!
Die Filme werden
bersichtlich auf der
Seite index.php
prsentiert.
403
Bitte besttige: Name und Nutzer-ID

Bitte besttige: Name und
Nutzer-ID
Jetzt folgt der nchste Schritt. Richte eine Besttigungsseite ein! Es geht
um die Datei order.php.
Die Datei order.php
Bereite die Seite order.php vor. Diese nimmt, wie schon erwhnt, die ID,
die Anzahl und den Titel des Produktes entgegen.
Zur Kontrolle blendest du hier die letzteren Angaben noch einmal ein. Der
Nutzer besttigt dann seine Wahl durch Eingabe seiner Benutzer-ID und
den Nachnamen.

Hier zeige ich dir den gesamten Quellcode zwischen den Tags
<body></body>. Besonders interessant ist wieder der PHP-Teil.
<div id="wrapper">
<?php
// Auf submit geklickt?
if (isset($_POST["sm1"])) {
$muster = "/^[0-9]+$/"; // reg. Ausdruck fr Zahlen
if (preg_match($muster, $_POST["Anzahl"]) == 0
|| preg_match($muster, $_POST["id"]) == 0
|| $_POST["Anzahl"] < 1) {
die("<h3><a href='javascript:history.back()'>Eingabe " .
"berprfen!</a></h3></div></body></html>");
}

Der Benutzer muss
sich nun verbindlich
anmelden.
404
Aktivitten verwalten: Wer kommt mit ins Kino?

Kapitel
16

// Besttigungsformular erzeugen
echo <<<FORMULARBEREICH
<h2>Auswahl bitte besttigen!</h2>
<p>Hallo, du hast dich fr folgende Veranstaltung
entschieden:</p>
<p>{$_POST["Anzahl"]} x <strong>{$_POST["Titel"]}</strong></p>
<p>Bitte besttige diese Auswahl mit deinen Daten:</p>
<form method="post" action="input.php">
<input type="hidden" name="Anzahl" value="{$_POST['Anzahl']}">
<input type="hidden" name="pid" value="{$_POST['id']}">
<p>Deine <b>Benutzer-ID</b>: <input type="text"
name="aid" size="3">
Dein <b>Nachname</b>: <input type="text" name="Name">
</p>
<input type="button" value="&lt;&lt; Zurck zur Auswahl"
onclick="location='index.php'">
<input type="submit" value="Jetzt verbindlich anmelden
&gt;&gt;" name="sm2">
</form>
FORMULARBEREICH;
} else { // Surfer kommt zufllig auf die Seite
echo "<h3><a href='index.php'>Zur Startseite!</a></h3>";
}
?>
</div>
Der Quelltext im berblick
Blickst du durch den Code durch? Es gibt weder spektakulre Besonderhei-
ten noch irgendwelche Neuerungen. Nicht einmal eine SQL-Abfrage, denn
die ist auf dieser Zwischenseite nicht ntig. Auerdem habe ich alle wich-
tigen Abschnitte mit Kommentaren eingeleitet. Probiere das Skript bis hier-
her ruhig einmal aus. Dir ist doch noch nicht alles klar? Gut, besprechen
wir schnell das Wichtigste!
Zuerst prft das Skript, ob das Formular berhaupt abgeschickt wurde.
Pfiffigerweise hatten wir dem SUBMIT-Button aus der index.php schlie-
lich den Namen sm1 verpasst. Du fragst diesen Namen ab und reagierst
darauf. Der Hauptcode der Seite soll schlielich nur dann ausgefhrt wer-
den, wenn das Formular abgeschickt wurde.
if (isset($_POST["sm1"])) {
...

405
Bitte besttige: Name und Nutzer-ID

Doch was passiert, wenn das nicht der Fall ist? Surfer, die die Seite
order.php zufllig aufgerufen haben, bekommen dank dieser Abfrage
lediglich den else-Zweig zu Gesicht. Sie sehen einen Link, der zurck zur
Hauptseite weist.
} else { // Surfer kommt zufllig auf die Seite
echo "<h3><a href='index.php'>Zur Startseite!</a></h3>";
}

Doch nun zum eigentlichen interessantem Teil, zu den Codezeilen, die un-
terhalb der if-Abfrage folgen.
Zur Sicherheit: Werte berprfen
Auch hier folgt wieder etwas Sicherheit! Wir berprfen, ob die Werte fr
Anzahl und id Zahlen sind. Bei id ist das sicher der Fall. Es sei denn, jemand
manipuliert das Formular. Aber bei Anzahl knnte es Probleme geben. Ein
Witzbold knnte einen Buchstaben tippen. Das wird mit diesem Test unter-
sucht und unterbunden. Auerdem darf die Anzahl der Karten nicht 0 sein!
$muster = "/^[0-9]+$/"; // reg. Ausdruck fr Zahlen
if (preg_match($muster, $_POST["Anzahl"]) == 0
|| preg_match($muster, $_POST["id"]) == 0
|| $_POST["Anzahl"] < 1) {
die("<h3><a href='javascript:history.back()'>Eingabe " .
berprfen!</a></h3></div></body></html>");
}

Im Zweifelsfall bekommt der Nutzer den Link Eingabe berprfen zu sehen.
Er wird auf die Startseite zurckgefhrt und das Skript bricht ab.
Bei einem echten Onlineshop im Internet wrde man jetzt aus Sicher-
heitsgrnden ggf. noch weitere Tests fahren. Man wrde prfen, ob die
bermittelte id berhaupt in der Datenbanktabelle vorkommt. (Sie kann
ja durch Formularmanipulation geflscht worden sein.) Das gleiche wr-
de man fr den bermittelten Titel tun. Denn alle Werte, die von einer
Seite an die nchste bergeben werden, knnen theoretisch von Hackern
manipuliert werden. Man wrde den Warenkorb auch eher in einer
Session direkt auf dem Webserver ablegen, um solche Manipulationen
auszuschlieen. (Sessions besprechen wir brigens im Nachfolgeband.)
Im Beispiel gengen die von uns eingesetzten Tests, um das Skript nicht
unntig zu verkomplizieren. Sie sind schon relativ gut. Ich wollte bei dir
jedoch ein erweitertes Sicherheitsbewusstsein wecken!
406
Aktivitten verwalten: Wer kommt mit ins Kino?

Kapitel
16
Der Heredoc-Bereich
Schauen wir uns nun die Passage zwischen echo <<<FORMULARBEREICH
und FORMULARBEREICH; an.
Hier bekommt der Benutzer seine Auswahl noch einmal zu sehen. Die Fel-
der Anzahl, id und Titel des Films wurden schlielich nicht umsonst von
der index.php an die order.php bergeben. Anzahl und ID sind dabei
nur auf der Durchreise, diese Angaben werden zum Schluss noch ben-
tigt. Wir reichen sie dann erneut mit versteckten Formularfeldern weiter.
Auerdem erzeugst du die Formularfelder, in welche der Benutzer seine
ID und seinen Nachnamen eingibt. Die ID des Kunden (Feld id) wird fr
die Datenbanktabelle bestellungen bentigt. Der Nachname (Feld
Name) dient lediglich als zustzliche Kontrolle. Denn sonst wre die
Wahrscheinlichkeit des Missbrauchs zu gro. Der Benutzer knnte auf
gut Glck eine Zahl raten und im Namen eines anderen Kunden eine
Karte buchen. (Auch hier fhrt man in der Praxis noch strengere Tests!)
Diese Angaben werden zusammen mit id und Anzahl des Produktes an die
nchste Seite weitergeleitet. An die Seite input.php. Doch wenn der Be-
nutzer mit seiner Auswahl nicht zufrieden ist?
Gib den Besuchern die Mglichkeit zur Korrektur! Im Beispiel sorgt ein
JavaScript-Button genau fr diesen Zweck. Dieser Schaltknopf fhrt zurck
zur Startseite:
<input type="button" value="&lt;&lt; Zurck zur Auswahl"
onclick="location='index.php'">

Die Anweisung onclick="location='index.php'" sorgt dafr, dass bei
Klick auf diesen Button wieder die Seite index.php aufgerufen wird!
Wer kommt mit? Aus zwei mach
drei!
Nun zum Hhepunkt, zur Seite input.php. Hier entsteht wenn alles
glatt gegangen ist der Datenbankeintrag. Hier wird die Datenbanktabelle
bestellung gefttert. Bei dieser Gelegenheit bauen wir wieder ein paar
zustzliche if-Abfragen ein, damit keine sinnlosen Eintrge in der Daten-
bank landen.
407
Wer kommt mit? Aus zwei mach drei!

Die Datei input.php
Zuerst zeige ich dir den Quelltext der input.php. Du siehst den gesamten
Bereich zwischen den Tags <body></body>.
<div id="wrapper">
<h2>Eintrag in die Datenbank bertragen</h2>
<?php
// alle Felder ausgefllt?
if (!empty($_POST["sm2"]) && !empty($_POST["aid"]) &&
!empty($_POST["Name"])) {
$muster = "/^[0-9]+$/"; // reg. Ausdruck fr Zahlen
if (preg_match($muster, $_POST["aid"]) == 0
|| preg_match($muster, $_POST["pid"]) == 0
|| preg_match($muster, $_POST["Anzahl"]) == 0) {
die("<h3><a href='javascript:history.back()'>Eingabe " .
"berprfen!</a></h3></div></body></html>");
}
include("edit/zugriff.inc.php");
// Adresse anhand der id ermitteln
$sql = "SELECT * FROM adressen WHERE id=$_POST[aid]";
$result = mysqli_query($db, $sql);
$row = @mysqli_fetch_assoc($result);

// Ist der Nachname korrekt?
if ($row["Name"] == $_POST["Name"]) {
$datum = date("d.m.Y, H:i"); // Datum mit Uhrzeit

// Daten eintragen in bestellungen
$sql = "INSERT INTO bestellungen VALUES " .
"('','$_POST[aid]','$_POST[pid]','$_POST[Anzahl]','$datum')";
mysqli_query($db, $sql);
// Erfolgsanzeige
if (mysqli_affected_rows($db) > 0) {
echo "<h3>Hallo $row[Vorname] $row[Name]: Eintrag
erfolgreich!</h3>";
} else {
echo "<h3>Hallo $row[Vorname] $row[Name]: Eintrag
nicht erfolgreich!</h3>";
}
echo "<a href='index.php'>zurck zur Startseite</a>";
} else { // Keine bereinstimmung von Nachname und id
echo <<<FORMULARBEREICH
<p>Bitte gib die <b>korrekten</b> Daten an!</p>
408
Aktivitten verwalten: Wer kommt mit ins Kino?

Kapitel
16

<form action="order.php" method="post">
<input type="button" value="&lt;&lt; Zurck"
onclick="history.back()">
</form>
FORMULARBEREICH;
}
mysqli_close($db);
} else { // mind. ein Feld nicht ausgefllt
echo <<<FORMULARBEREICH2
<p><b>Alle</b> Felder mssen ausgefllt werden!</p>
<form action="order.php" method="post">
<input type="button" value="&lt;&lt; Zurck"
onclick="history.back()">
</form>
FORMULARBEREICH2;
}

?>
</div>
Der Quelltext im berblick
Uff! Lass dich nicht von der langen Codewste beunruhigen. Auch in
diesem Skript steckt nichts wirklich Bahnbrechendes!
Zuerst prfen wir, ob der Benutzer auch tatschlich ber das Formular der
Seite order.php auf die input.php gelangt ist. Auf der Seite order.php
hatten wir zu diesem Zwecke den SUBMIT-Button des Formulars wieder
durch einen Namen gekennzeichnet. Diesmal lautete dieser name="sm2".
Bei dieser Gelegenheit wird zustzlich gleich mit getestet, ob die Felder
aid und Name nicht leer gelassen wurden.
// alle Felder ausgefllt?
if (!empty($_POST["sm2"]) && !empty($_POST["aid"]) &&
!empty($_POST["Name"])) {
...

Wenn mindestens eine der Teilbedingungen unwahr ist, wird der Benutzer
zurck zur Ausgangsseite geschickt:
} else { // mind. ein Feld nicht ausgefllt
...

409
Wer kommt mit? Aus zwei mach drei!

Danach prft wieder unser obligatorischer regulrer Ausdruck auf Fehlein-
gaben und schickt den Benutzer ggf. wieder zur vorherigen Seite zurck.
Betroffen sind $_POST["aid"], $_POST["pid"] und $_POST["Anzahl"],
alles mssen Zahlwerte sein. Genau diese Werte verarbeiten wir weiter
unten in SQL-Abfragen. Dank dieser berprfung sparen wir uns auch wei-
tere Escape-Manahmen durch mysqli_real_escape_string().
Alle weiteren Abschnitte dazwischen sind durch Kommentare gut doku-
mentiert. Schau zuerst zum Bereich:
// Adresse anhand der id ermitteln

Hier holst du den kompletten Adressdatensatz aus der Tabelle adressen.
Schlielich muss der Nachname gegengeprft werden.
// Ist der Nachname korrekt?

In diesem Abschnitt vergleichst du nun den Namen aus dem Formular mit
dem Namen aus der Adresstabelle. Nur bei einer bereinstimmung geht es
weiter, dafr sorgt eine if-Abfrage. Dann wird z. B. das Datum mit Uhrzeit
erzeugt und in der Variablen $datum abgespeichert. Diese Angabe benti-
gen wir schlielich in unserer Datenbank bestellungen.
Sollte es hier eine Unstimmigkeit geben, springt das Skript zum else-
Zweig:
// Keine bereinstimmung von Nachname und id

Der Nutzer sieht folgendes Bild:

Als nchstes folgt dieser Abschnitt:
// Daten eintragen in bestellungen

Hier werden die Daten endlich in die Tabelle bestellungen eingetragen.
Das gelingt wieder mit der Grundsyntax
Nachname und ID
stimmen nicht berein?
Noch einmal probieren!
410
Aktivitten verwalten: Wer kommt mit ins Kino?

Kapitel
16
INSERT INTO bestellungen () VALUES ()

Dabei lassen wir die normalerweise folgenden runden Klammern hinter
bestellungen einfach wieder weg ich habe diese Stelle fett hervorge-
hoben. Da alle Felder betroffen sind, muss man die Feldnamen nicht extra
angeben. Du erinnerst dich noch?
Nicht weglassen darfst du das runde Klammernpaar fr die Werte, die den
jeweiligen Feldern zugeordnet werden. Beachte, dass alle Werte in Gnse-
fchen eingekleidet werden mssen. Ich wei, dass hier eine groe Feh-
lerquelle lauert. Deshalb habe ich es an dieser Stelle wiederholt.
Abfrage mit Erfolgsanzeige
Die eigentliche Abfrage findet hier statt:
mysqli_query($db, $sql);
// Erfolgsanzeige
if (mysqli_affected_rows($db) > 0) {
echo "<h3>Hallo $row[Vorname] $row[Name]: Eintrag
erfolgreich!</h3>";
} else {
echo "<h3>Hallo $row[Vorname] $row[Name]: Eintrag
nicht erfolgreich!</h3>";
}

Hier kommt wieder mysqli_affected_rows() zum Einsatz und infor-
miert ber den erfolgreichen oder erfolglosen Eintrag. Dabei spreche ich
den Benutzer gleich noch persnlich an schlielich stehen die Werte der
entsprechenden Datenbankfelder in $row[Vorname] und $row[Name] zur
Verfgung.

Und wie vermeidest du Doppeleingaben? Durch einen Unique Index, der
sich auf die Felder aid und Datum bezieht. Das wird deine Aufgabe werden
mehr dazu also im Aufgabenbereich auf Seite 418 (letzte Aufgabe)!
Alles klar, der Daten-
bankeintrag war
erfolgreich.
411
SQL fr Profis: Von Joins und Funktionen

SQL fr Profis: Von Joins und
Funktionen
So weit, so gut: Dein Bestellsystem steht! Die Kunden in spe knnen ihre
Buchungen vornehmen. Du bist ungeduldig und mchtest testen? Gib doch
einmal ein paar Bestellungen zum ben ein! (Du kannst die Tabelle
bestellungen nach der Generalprobe einfach wieder lschen und neu
anlegen.) Du brauchst lediglich die Liste deiner Teammitglieder, damit du
deren ID einsehen kannst. Versetze dich ruhig mal in die Haut von deinen
Kumpels und buche mal die eine, mal die andere Veranstaltung.
Abfrage zur Ermittlung der Bestelldaten
Doch wie wertest du die Tabelle aus? Das ist eine lange Geschichte so
wrde Kptn Blaubr diesen Abschnitt sicher einleiten. Ich versuche, das
Ganze etwas krzer zu fassen: Lerne fortgeschrittenes SQL!
>
ffne phpMyAdmin und rufe die Tabelle bestellungen auf. Klicke
auf ANZEIGEN bzw. klicke im linken Bereich auf das kleine Symbol.
>
Was siehst du hier? Nicht viel. Sortiere deshalb die Bestellungen nach
der pid, nach der Produktkennung. Das gelingt durch Klick auf den
entsprechenden Spaltenkopf.

Trotzdem ist diese Anzeige noch nicht aussagekrftig genug. Dich interes-
sieren vor allem folgende Dinge:
0 Wie viele Bestellungen gibt es pro Film?
0 Wer genau hat was bestellt?
412
Aktivitten verwalten: Wer kommt mit ins Kino?

Kapitel
16
Auerdem mchtest du statt der Film-ID und Personen-ID sicher gerne Titel
und Namen wissen. Denn auch ein noch so guter Organisator hat nicht alle
IDs im Kopf.
COUNT() Anzahl der Bestellungen ermitteln
Alle diese Probleme lsen wir durch SQL-Abfragen, und zwar direkt in
phpMyAdmin. Suche das Feld, in welchem du SQL-Befehle in deiner Daten-
bank ausfhren kannst. Und nun probierst du einfach folgende Anweisung:
SELECT COUNT(*) FROM bestellungen WHERE pid=1

Neu ist hierbei die Funktion
COUNT()

Diese Funktion zhlt alle Zeilen. Im Ergebnis wird dir mitgeteilt, wie viele
Bestellungen es fr den Film mit der id 1 insgesamt gegeben hat. Und tat-
schlich gibt diese Befehlskette nun aus, wie viele Schler den Film schon
gebucht haben.
SUM() Summe der Bestellungen
Zugegeben, fr den Kartenkauf hilft dir diese Funktion nicht weiter. Es
kommt durchaus vor, dass der eine oder andere Kunde gleich mehrere Kar-
ten bestellt. Schlielich dient unser Feld Anzahl diesem Zweck!
Du brauchst eine andere Funktion, die Funktion SUM(). Mit dieser Funktion
ermittelst du die Summe eines ausgewhlten Bereichs.

Wir wollen die Summe der Anzahl der Bestellungen ermitteln. Und zwar
nur fr den Film Nr. 1. In diesem Fall schreibst du:
SELECT SUM(Anzahl) FROM bestellungen WHERE pid=1

Die Funktion SUM()
addiert alle Zahlen
eines Feldes.
413
SQL fr Profis: Von Joins und Funktionen

Und schon hast du in Windeseile ermittelt, wie viele Karten du besorgen
musst.

Das Abfrageergebnis besteht lediglich aus einer Zahl.
Wie gehst du am besten in der Praxis vor? Du gibst deinen Teilnehmern
einen Stichtag mit auf den Weg. Am Ende des Stichtages lschst du den
entsprechenden Film einfach aus der Datenbank produkte. Dann ist es
nicht mehr mglich, weitere Bestellungen anzunehmen. Und niemand
kann sich hinterher beschweren!
Tabellen durch einen Join verbinden
Nun interessiert dich jedoch, wer genau hier Karten bestellt hat. Und wie
viele dazu! Du willst aber nicht bei jeder aid von Hand in der Adressenta-
belle nachschauen.
Deshalb musst du zwei Tabellen miteinander verbinden to join, wie die
Englnder sagen wrden. Im Beispiel verbinden wir die Tabelle produkte
mit der Tabelle adressen. Du erstellst also einen Join zwischen deinen
Tabellen und zwar ohne t am Ende!
Wenn du zwei Tabellen miteinander verbinden mchtest, trennst du sie
einfach durch ein Komma voneinander! Das Komma steht fr eben die-
sen Join. Doch wie greifst du dann auf die Felder der einzelnen Tabellen
zurck? Es knnte doch zu Missverstndnissen kommen? Das gelingt,
indem du den Tabellennamen notierst und dann einen Punkt setzt. Erst
dann schreibst du den Feldnamen der entsprechenden Tabelle. Mchtest
du das Feld Name aus der Tabelle adressen ermitteln? Dann schreibst
du adressen.Name statt Name. An das Feld pid aus der Tabelle
bestellungen gelangst du ber bestellungen.pid!
Die folgende Abfrage ermittelt, wer genau nun welche Karten fr Film 1
bestellt hat. Dafr musst du mehrere Bedingungen durch AND miteinander
kombinieren.
414
Aktivitten verwalten: Wer kommt mit ins Kino?

Kapitel
16

SELECT * FROM bestellungen, adressen WHERE
bestellungen.pid=1 AND bestellungen.aid=adressen.id

Diese Befehlsfolge liest sich so: Whle alle Zeilen aus den Tabellen
bestellungen und adressen bei denen gilt: Es handelt sich um Film 1
(bestellungen.pid=1). Auerdem mchtest du aus der Tabelle
adressen nur die Datenstze ausgeben, deren id in der Tabelle
bestellungen auftaucht (bestellungen.aid=adressen.id).
Erst mit dieser Kombination von WHERE-Klauseln sorgst du dafr, dass
auch wirklich nur die Kunden aufgelistet werden, die der entsprechenden
aid aus bestellungen entsprechen.
Zum Ausprobieren kannst du die zweite Bedingung einmal weglassen,
also den Abschnitt AND bestellungen.aid=adressen.id. Nanu, was
passiert denn jetzt? Du bekommst viel mehr Zeilen zu Gesicht, wobei
sich die Zeilen noch dazu dauernd wiederholen! Das liegt daran, dass
deine Adressliste sicher recht lang ist. MySQL beschrnkt die Anzahl der
auszugebenden Adressen nicht mehr, da die zweite einschrnkende Be-
dingung fehlt. Im Gegenteil: Das Programm wiederholt die gefundenen
Eintrge so lange, bis die Liste aufgefllt ist.
Und nun probiere einmal diesen SQL-Befehl:
SELECT bestellungen.Anzahl, adressen.Name FROM
bestellungen, adressen WHERE bestellungen.pid=1 AND
bestellungen.aid=adressen.id

Richtig, dieses SQL-Monster gibt nur die jeweilige Anzahl der Karten aus
und ordnet diese der betreffenden Person zu.

Ideal: So siehst du auf einen Blick, wer wie viel bestellt hat.
415
SQL fr Profis: Von Joins und Funktionen

Du mchtest zustzlich noch den Namen des Filmes sehen? Dann knntest
du eine SQL-Abfrage wie folgt schreiben:
SELECT bestellungen.Anzahl, adressen.Name, produkte.Titel
FROM bestellungen, adressen, produkte WHERE
bestellungen.pid=1 AND bestellungen.aid=adressen.id AND
bestellungen.pid=produkte.id

Damit hast du gleich drei Tabellen auf einmal miteinander verbunden. Ist
das nicht der Hammer? Es ist wirklich erstaunlich, wie viel man mit fortge-
schrittenen SQL-Befehlen machen kann.
Experimentiere ruhig ein wenig mit diesen neuen SQL-Mglichkeiten he-
rum! Verbinde die Tabellen und frage bestimmte Kriterien ab. Nur so be-
kommst du die ntige bung. Dabei ist es gar nicht schlimm, wenn bei
der Abfrage etwas schief geht. Wie wre es z. B. mit einer Berechnung
des Gesamtpreises der gebuchten Tickets? Oder mit den Kosten, bezogen
auf einen Nutzer?
Ausgabe als PHP-Dokument
Sicher mchtest du nicht ewig in phpMyAdmin arbeiten. Erstelle doch ein-
mal eine PHP-Seite, in welche du die entsprechenden SQL-Befehlszeilen
einbaust. Mein Vorschlag ermittelt erst einmal Anzahl und Namen der
Teilnehmer fr den Film mit der id 1:
Ich zeige dir wie immer nur den Bereich zwischen den Tags <body>
</body>. Das Dokument nenne ich im Beispiel summary.php und lege es
ebenfalls im Verzeichnis order ab:
<h2>Wer kommt mit?</h2>
<?php
include("edit/zugriff.inc.php");
// Anzahl und Namen der Teilnehmer fr Film 1
$sql = "SELECT bestellungen.Anzahl, adressen.Name
FROM bestellungen, adressen WHERE bestellungen.pid=1
AND bestellungen.aid=adressen.id";
$result = mysqli_query($db, $sql);
echo "<table border='1' cellspacing='0'>";
// while-Schleife Anfang
while ($row = mysqli_fetch_assoc($result)) {
echo "<tr>"; // Zeile erzeugen
416
Aktivitten verwalten: Wer kommt mit ins Kino?

Kapitel
16

// foreach Anfang:
foreach ($row as $key => $value) {
echo "<td>$value&nbsp;</td>\n";
} // foreach Ende
echo "</tr>"; // Zeile schlieen
} // while Ende
echo "</table>\n"; // Tabelle schlieen
mysqli_close($db);
?>



Den PHP-Code kannst du inzwischen sicher gut verstehen. Wenn nicht,
blttere zurck zum Kapitel 13. Es ist exakt das gleiche Prinzip, welches wir
fr die Ausgabe der Adressen verwendet haben.
Schlussbemerkung
Das Kapitel fing noch ganz gemtlich an, das gebe ich zu. Das Zerlegen von
greren Datenbanken in Teiltabellen klingt sinnvoll und verstndlich. Doch
am Schluss wurde es richtig haarig. Scheinbar gengen die paar am Anfang
gelernten SQL-Befehle bei weitem nicht aus.
Fr fortgeschrittenes SQL stehen dir viele weitere Befehle, Befehlskombi-
nationen und Funktionen zur Verfgung. Davon konnte ich dir zumindest
einen kleinen Ausschnitt vorstellen.

Eine einfache Tabelle
gibt alle abgefragten
Datenstze aus.
417
Zusammenfassung

Zusammenfassung
0 Du weit, dass du groe Datenbankprojekte in mehrere Teiltabellen
aufteilen solltest. So vermeidest du die Doppeleingabe. Du kennst den
Begriff Normalisieren, also das Zerlegen von Datenbanktabellen in Teil-
module.
0 Du kennst die Bedeutung der Primrschlssel. Dadurch, dass ein Primr-
schlssel nur einem Datensatz zugeordnet ist, kannst du ihn z. B. als
Kundennummer oder Produktnummer verwenden.
0 Du weit, dass du mit Hilfe der Primrschlssel Relationen (Verbindun-
gen) zwischen den Datenbanktabellen aufbaust. Du speicherst fremde
Primrschlssel als Platzhalter fr den gesamten Datensatz.
0 Du kennst den Begriff 1:n-Beziehungen. Einem Kunden knnen z. B. n
Bestellungen zugeordnet werden.
0 Du kennst die SQL-Funktionen COUNT() und SUM(), mit denen du Zeilen
zhlen und Werte zusammenrechnen kannst
0 Du kennst die Technik des Joins, also des Verbindens mehrerer Tabellen.
Um zu sinnvollen Abfrage-Ergebnissen zu gelangen, musst du mehrere
WHERE-Klauseln durch AND verknpfen.
Ein paar Fragen
1. Welches Datenfeld nimmt man gerne fr eine Kunden- oder Produkt-
nummer?
2. Wie nennt man das Aufteilen von groen Datenbank-Listen in mehrere
Teiltabellen?
3. Welche SQL-Funktion ermittelt die Summe der Werte eines Feldes?
und ein paar Aufgaben
1. Verndere das letzte Skript (summary.php) so, dass zustzlich noch der
Vorname des Bestellers ausgegeben wird. Speichere es unter dem Na-
men summary1.php.
2. Blende weiterhin den Filmtitel als berschrift ein. Dafr schreibst du
am besten eine eigene SQL-Abfrage, die die Tabelle produkte abfragt.
Nenne das Dokument summary2.php.
418
Aktivitten verwalten: Wer kommt mit ins Kino?

Kapitel
16
3. Noch eine schwere Aufgabe! Erweitere die summary.php um ein For-
mularfeld, in welches du die id des Filmes eingibst. Nach Abschicken
des Formularinhalts soll die Buchungsbelegung des jeweiligen Films
angezeigt werden. Denke auch an eine berprfung der Eingabe es
muss ein Zahlwert sein. Zeige bei Fehleingaben an: Eingabe berprfen.
Speichere unter dem Namen summary3.php.

Frage bequem alle Filme auf Auslastung ab.
4. Sorge dafr, dass Doppeleintrge in der Datenbanktabelle bestellun-
gen zuverlssig vermieden werden. Das gelingt durch einen Unique In-
dex, in den du die Felder aid und Datum einbeziehst.

Das sieht der Nutzer bei einem versehentlichen Reload aber erst nachdem du den
Unique Index gesetzt hast!
Hier zeige ich dir als kleinen Tipp den SQL-Code fr diesen Unique In-
dex. Falls du Lust hast, es mal von Hand zu probieren:
ALTER TABLE bestellungen ADD UNIQUE (
aid,
Datum
)


419



17
Automatisch Geburts-
tagsgre versenden

Jetzt kommt das Highlight des Buches! Erweitere das Adressbuch aus Kapi-
tel 13! Fge ein Feld fr den Geburtstag ein. Schicke jedem deiner Kontakte
einen elektronischen Geburtstagsgru. Per E-Mail und ganz vollautoma-
tisch. Und natrlich ganz individuell.
In diesem Kapitel zeige ich dir zum krnenden Abschluss, wie du
$ eine Tabelle um ein Feld erweiterst
$ einen Pseudo-Cronjob (Skriptstart per Timer) einrichtest

Wie auch immer im Endeffekt entsteht ein pfiffiges kleines System, das
ganz zuverlssig Geburtstagsgre verschickt.
Wichtig: Dieses Skript arbeitet mit der Funktion mail(). Daher funktio-
niert es nur auf dem Webserver des Dienstleisters. Du kannst es also nur
ausprobieren, indem du das Skript vorher auf den Server ldst. Beachte
weiterhin, dass dein Dienstleister das Versenden untersttzen muss.
420
Automatisch Geburtstagsgre versenden

Kapitel
17 MySQL und dein Dienstleister
Das folgende Skript macht offline nicht viel Sinn. Ich setze voraus, dass du
dich beim Dienstleister angemeldet hast. Rufe das hier installierte Tool
phpMyAdmin auf, um die Datenbank adressen zu bearbeiten. Bei wel-
chem Dienstleister bist du angemeldet?
Beim Dienstleister Neue Medien Mnnich (www.all-inkl.com) whlst du
www.deinedomain.de/mysqladmin
Gib nun Benutzernamen und Passwort ein. Es sind die gleichen Daten, die
du zum Einloggen in das Kundenmen bentigst. Schon bekommst du Zu-
griff auf phpMyAdmin zum Zeitpunkt des Schreibens sogar in der neues-
ten Version!
In diesem Skript kommt wieder die Funktion mail() zum Einsatz. Ohne
zustzliche Parameter hat die Funktion Probleme mit Umlauten. (Einige
dieser zustzlichen Angaben lernst du im Praxisbuch kennen.) Aus die-
sem Grund kodieren wir die PHP-Seite nicht als UTF-8, sondern wieder
als ISO-8859-1. Genau so, wie wir es in Kapitel 8 gehalten haben. Denke
auch daran, den Zeichensatz der Datei anzupassen. In PSPad whlst du
FORMAT|ANSI. In Notepad++ lautet der Befehl KODIERUNG|KONVERTIERE ZU
ANSI. Zumindest in Notepad++ kannst du die Kodierung noch feiner ein-
stellen. Whle KODIERUNG|ZEICHENSATZ|WESTEUROPISCH|ISO-8859-1.
ALTER TABLE: Neue Spalte mit
ADD COLUMN
ffne die Tabelle adressen, wie im Kapitel 13 gezeigt! Fge hier die neue
Spalte ein. Dazu bedienst du dich des Befehls
ALTER TABLE tabellenname ADD COLUMN feldname ...

Die neue Spalte wird dabei automatisch am Schluss der Tabelle angehan-
gen. Das neue Feld soll im Beispiel Geburtstag heien. Hier trgst du den
jeweiligen Geburtstag ein. Du bentigst fr das Datum eine Lnge von 10
Zeichen. Im Beispiel lautet der komplette SQL-Befehl also folgendermaen:
ALTER TABLE adressen ADD COLUMN Geburtstag VARCHAR(10)
421
Vorberlegung: Pseudo-Cronjob einrichten


Einfgen einer neuen Spalte, hier in einer neuen Version von phpMyAdmin.
Trage nun die Geburtstage ein. Whle folgendes Format:
TT.MM.JJJJ

Im Klartext: Die Tages- und Monatszahl muss stets zweistellig angegeben
werden. Und zwar mit einer fhrenden Null wie 01.07.1970. Das Jahr be-
kommt dagegen vier Stellen! Als Trenner zwischen den Werten dient der
Punkt.
Behalte dieses Format bei, denn das Skript basiert auf dieser Schreibweise.
Wir verwenden deshalb den Punkt als Trenner, um das Datum spter mit
der Funktion explode() in seine Einzelteile zerlegen zu knnen.
Vorberlegung: Pseudo-Cronjob
einrichten
Das wars im Prinzip schon. Nun folgen ein paar Vorberlegungen und da-
nach zeige ich dir mein Skript.
Was muss das Geburtstags-Skript knnen? Nicht viel: Das Skript soll die
Adressdatenbank einmal tglich nach Geburtstagen durchforsten. Bei einer
Datumsbereinstimmung verschickt das Skript je zwei E-Mails. Eine E-Mail
an das Geburtstagskind und eine Erinnerungsmail an dich.
Denn nichts ist peinlicher, als wenn sich das Geburtstagskind fr die
Glckwnsche bedankt und du mal wieder berhaupt keine Ahnung hast.
So weit, so gut. Bleibt ein Haken brig. Wie bringst du das Skript dazu,
einmal am Tage deine Datenbank abzuklappern? Zu diesem Zweck ben-
tigst du eigentlich einen sogenannten Cronjob.
422
Automatisch Geburtstagsgre versenden

Kapitel
17 Ein Cronjob ist ein Skript, das zu einer bestimmten Zeit (Cronos ist grie-
chisch und heit Zeit) automatisch gestartet wird. Es ist eine Art Timer,
der z. B. tglich 02:00 Uhr dein Geburtstagsskript ausfhrt. Der Haken:
Die meisten Webhoster erlauben es dir nicht, solche Cronjobs einzurich-
ten. Der Grund ist einfach: Cronjobs werden direkt auf dem Server aus-
gefhrt und knnen diesen komplett lahm legen, wenn dein Skript feh-
lerhaft ist.
Ich vermute mal, dass dir genau wie mir keine Cronjobs zur Verfgung
stehen. Was machen wir da? Meine Idee: Platziere das Skript unsichtbar
auf irgendeiner Seite deiner Prsenz. Auf einer mglichst hufig besuchten
Seite. Sobald ein Besucher kommt, wird dein Skript aufgerufen.
Sobald ein Besucher kommt, wird das Skript aufgerufen? Gibt es dann
bei 20 Besuchern 20 Geburtstags-Mails? Natrlich nicht! Wir halten den
ersten Aufruf des Tages fest, indem wir den aktuellen Wochentag in ei-
ner Textdatei speichern. Das Skript vergleicht beim nchsten Mal, ob die-
ser Wochentag schon eingetragen ist. So sorgen wir dafr, dass das
Skript pro Tag nur ein einziges Mal aufgerufen wird. Es wird praktisch
durch den ersten Besucher ausgelst!
Zugegeben, eine genaue Zeitsteuerung lsst sich damit nicht erreichen.
Trotzdem sorgen wir dafr, dass das Skript einmal pro Tag startet. Einzige
Voraussetzung: Mindestens ein Besucher verirrt sich auf deine Seite. Oder
du rufst deine Seite im Zweifelsfalle selber auf, indem du sie besuchst.
So klappts: Das Geburtstags-
Skript
Genug der Vorbemerkungen! Zeit, dass ich dir den kompletten Quelltext
prsentiere. Es gibt weder Neuerungen noch irgendwelche Besonderheiten.
Textdatei tag.txt
Zuerst richtest du eine normale Textdatei ein. Tippe am besten den Wo-
chentag von gestern ein. Oder irgendeinen anderen Wochentag auer dem
heutigen. Wenn heute der 12. Mai ist, schreibst du eine 11.
423
So klappts: Das Geburtstags-Skript

Diese Datei nennst du tag.txt und ldst sie auf den Server. Denke auch
an den schon oft besprochenen Befehl chmod zum Aufheben des Schreib-
schutzes, siehe Seite 254.
Include-Datei zugriff.inc.php
Weiterhin brauchen wir die schon aus den vorigen Kapiteln bekannte In-
clude-Datei zugriff.inc.php. Dort liegen deine aktuellen MySQL-Zu-
gangsdaten. Lade sie mit auf den Server. Entferne jedoch vorher Zeile 2,
damit der Zeichensatz der MySQL-Verbindung auf ISO-8859-1 bleibt.
Der Quelltext
Doch nun zum Hauptjob. Ich zeige dir das komplette Skript im berblick.
Baue es in eine deiner am strksten besuchten PHP-Seiten ein. An welcher
Stelle? Das ist egal!
Packe das Skript praktisch an eine beliebige Stelle. Schlielich arbeitet das
Programm vollkommen im Hintergrund, der Besucher der Seite bekommt
davon nichts mit!
<?php
$tag = date("d");
// Tageszahl mit Wert aus Datei vergleichen
$datei = "tag.txt";
$fp = fopen($datei, "r+");
$aw = fgets($fp, 3);
rewind($fp);
if ($aw == $tag) {
// bereinstimmung?
$writemail = false;
} else {
fputs($fp, $tag);
$writemail = true;
}
fclose($fp);
// Mailskript nur ausfhren, wenn neuer Tag
if ($writemail) {
include("zugriff.inc.php");
$monat = date("m");
$jahr = date("Y");
$absender = "meine@adresse.de";
// Betreff fr Kontakt
$betreff1 = "Herzliche Glckwnsche zum Geburtstag";
424
Automatisch Geburtstagsgre versenden

Kapitel
17

// Betreff fr sich selbst
$betreff2 = "Geburtstagsmail verschickt an:";
// Nur die wichtigen Felder abfragen
$sql = "SELECT Vorname, Name, EMail, Geburtstag FROM
adressen ORDER BY Geburtstag";
$result = mysqli_query($db, $sql);
$zeilen = mysqli_num_rows($result);
// alle Zeilen der Tabelle durchgehen:
while ($row = mysqli_fetch_assoc($result)) {
$geb = explode(".", $row["Geburtstag"]);
if ($geb[0] == $tag && $geb[1] == $monat) {
$alter = $jahr - $geb[2];
// Text der E-Mail
$mailtext = "Hallo $row[Vorname] $row[Name]!\n\n" .
"Ich gratuliere dir sehr herzlich zu deinem\n" .
"$alter. Geburtstag und wnsche dir viel Glck\n" .
"und alles Gute im persnlichen als auch im\n" .
"beruflichen Leben!\n\n" .
"Bleibe gesund!\n\n" .
"Dein Johann-Christian :-)";
// Mails verschicken, inkl. Kontrollmail
if (mail($row["EMail"], $betreff1 , $mailtext,
"From: $absender")) {
mail($absender, "$betreff2 $row[Vorname]
$row[Name]", $mailtext, "From: $row[EMail]");
} // if Mail schlieen
}
} // while schlieen
mysqli_close($db);
} // if writemail schlieen
?>
Das Skript kurz erlutert
Wollen wir das Beispiel gemeinsam kurz noch einmal durchgehen? Im ers-
ten Teil ermittle ich die aktuelle Zahl des Wochentags, und zwar zweistel-
lig. Dafr sorgt die Zeile $tag = date("d");
Danach wird die Datei tag.txt geffnet und der Wert aus dieser Datei
wird in der Variablen $aw gesichert. In einer if-Abfrage vergleiche ich den
aktuellen Wochentag aus $tag mit diesem Wert. Nur wenn es keine ber-
einstimmung gibt, wird die Flag-Variable $writemail auf true gesetzt.
Dann wird gleichzeitig der aktuelle Tag in die Datei tag.txt geschrieben.
425
So klappts: Das Geburtstags-Skript

Stelle dir eine Flag-Variable wie ein kleines Fhnchen vor, das du im Er-
folgsfalle hisst. Im Misserfolgsfalle bleibt die Fahne einfach unten. Diese
Schalterstellung liest du spter aus und reagierst darauf. Im Buch hast
du die Technik mit den Flag-Variablen brigens schon hufig genutzt. Ich
wollte das Kind an dieser Stelle nur noch einmal beim Namen nennen!
Bei einer bereinstimmung beider Werte lautet der Wert von $writemail
dagegen false. Das Skript wurde an diesem Tag also schon ausgefhrt!
Die nchsten Zeilen sind auch nicht weiter kompliziert. Nur wenn
$writemail auf true steht wenn also das Skript an diesem Tag noch
gar nicht durchgefhrt wurde wird der Hauptteil ausgefhrt: if
($writemail) {.
Dann definieren wir einige weitere Variablen, ermitteln den aktuellen Mo-
nat, das Jahr, schreiben unsere Absender-Adresse ein, bereiten den Betreff
vor usw. usf. Schaue einfach in meine PHP-Kommentare. Interessant ist,
dass wir bei der SQL-Abfrage nicht alle, sondern nur die wichtigen Daten-
bankfelder ermitteln mssen. Im Beispiel sieht der SQL-Befehl deshalb so
aus:
$sql = "SELECT Vorname, Name, EMail, Geburtstag FROM
adressen ORDER BY Geburtstag";

Der Rest drfte aus den vorigen Kapiteln bekannt sein. Zustzlich kommt
die ebenfalls schon in Kapitel 11 besprochene Funktion explode() zum
Einsatz
$geb = explode(".", $row["Geburtstag"]);

Diese Funktion zerlegt das Datum aus dem Feld Geburtstag anhand des
Trennzeichens in Tag, Monat und Jahr. Auf den Wochentag kann ich so z. B.
mit $geb["0"] zurckgreifen, auf den Monat mit $geb["1"] usw.
Nun erfolgt ein simpler Vergleich. Gibt es eine bereinstimmung von Wo-
chentag und Monat? Dann und nur dann wird die Geburtstagsmail
verschickt, und zwar gleich mit einer Kopie an dich selbst. Damit es beson-
ders persnlich wirkt, berechnet das Skript das Alter des Jubilars, speichert
es in der Variablen $alter und gibt es mit aus.
426
Automatisch Geburtstagsgre versenden

Kapitel
17

Das Skript erzeugt zwei Mails: Eine an das Geburtstagskind und eine an dich.
Hehe, ganz schn clever, findest du nicht?
Schlussbemerkung
Du hast es geschafft! Das Buch ist damit zu Ende. Mir hat es Spa ge-
macht, und dir? An dieser Stelle mchte ich dich zum Ausprobieren ermuti-
gen! Lerne noch mehr PHP, beschftige dich intensiver mit MySQL. Hinter-
frage die Lsungen aus diesem Buch, denn vieles kann man noch besser
machen oder anders lsen.
Du hast ein besonders gutes Skript erstellt? Du hast eine bessere Lsung fr
eine Problemstellung gefunden? Her damit! Hund Buffi, Nele, Tim (die Kin-
der links und rechts am Seitenkopf) und Autor Hanke freuen sich sehr ber
dein Feedback: Surfe zu www.phpkid.de und teile uns deine Meinung mit.
Vielen Dank und weiterhin viel Spa mit PHP und MySQL. Und denke dar-
an: Es gibt wichtigere Dinge im Leben als Computer und eine Fortset-
zung zu diesem Buch.
Und zum Schluss noch ein Sicherheitstrick!
Wie wichtig Sicherheit auf Webseiten ist, habe ich dir im Laufe des Buches
immer wieder vermittelt. Manchmal geben schlampig programmiert Skripte
sogenannte Notices aus, wir hatten uns darber ja schon auf Seite 146
unterhalten. In vielen Fllen erscheinen aber auch richtig heftige Fehler-
meldungen.
Das ist gut fr dich als Skriptautor. So weit du, an welcher Stelle das
Problem liegt. Das ist aber nicht gut fr die Sicherheit, denn auch Hacker
427
Zusammenfassung

bekommen durch diese Meldungen wertvolle Hinweise auf Variablen, Pfade
und andere Interna. Schiebe dem einen Riegel vor. Es gibt eine ganz einfa-
che Lsung!
Notiere am Anfang eines jeden PHP-Skripts folgende Codezeile:
error_reporting(0);

Dadurch wird die Anzeige jeglicher Fehler im Skript ausgeblendet! Das er-
spart auch das Setzen des Klammeraffen @ vor den Funktionsnamen.
Auf deinem lokalen System jedoch machst du es genau andersherum.
Schreibe einfach
error_reporting('E_ALL');

Das blendet die Anzeige aller Meldungen ein, also auch der Notices. So
wirst du vor schlampigem Programmieren bewahrt.
Vergiss jedoch keinesfalls, diese Zeile vor dem Hochladen auf den Web-
server durch error_reporting(0); zu ersetzen!
Zusammenfassung
0 Du kennst den SQL-Befehl zum Einfgen einer neuen Spalte. Die Syntax
lautet: ALTER TABLE tabellenname ADD COLUMN feldname ...;
0 Du weit, wie du einen Cronjob simulieren kannst. Baue das Skript in
eine Seite ein, die hufig aufgerufen wird. Sorge durch eine Sperre da-
fr, dass das Skript aber nur einmal pro Tag startet.
0 Du hast gelernt, dass du mit der Zeile error_reporting(0); die An-
zeige aller Fehlermeldungen unterdrcken kannst.
Ein paar Fragen
1. Was ist ein Cronjob, was bedeutet das Wort Cronos?
2. Warum werden Cronjobs normalerweise nur in sehr teuren Paketen zur
Verfgung gestellt? (Und oft auch erst, nachdem dein Dienstleister dein
Skript berprft hat?)
428
Automatisch Geburtstagsgre versenden

Kapitel
17 und ein paar Aufgaben
1. Noch ist das Skript nicht perfekt! Du hast einen Geburtstag eingegeben,
aber die Person besitzt keine E-Mail-Adresse? Dann macht das Verschi-
cken von Geburtstagsgren auch nicht viel Sinn. Fange diesen zustz-
lichen Fall ab. Das Skript soll die Mail nur dann versenden, wenn das
Feld EMail nicht leer ist.
2. Passe das Skript auch weiterhin auf deine Bedrfnisse an. Dir gefllt die
Anrede Hallo Vorname Name nicht? Nimm den Nachnamen einfach
weg.
3. Zum Schluss habe ich noch eine Aufgabe. Bilde dich weiter. Lies bei-
spielsweise das PHP-Manual. Du findest es als Hilfedatei auf der CD
zum Buch unter dem Pfad dokumente/php_manual.
429


Anhang A
Fr Eltern und Lehrer
Ihr Kind will programmieren lernen? Frs Internet? Groartig! Dabei sollten
Sie es unbedingt untersttzen!
0 Ihr Kind lernt das logische Denken.
0 Ihr Kind bereitet sich in idealer Weise auf das Berufsleben vor.
0 Programmieren macht ungeheuer viel Spa. (Und das ist und bleibt
wohl doch das Wichtigste!)
Helfen Sie Ihrem Kind bei der Installation eines lokalen Webservers. Natr-
lich nur, falls sie oder er es nicht schon selber schafft. Denn in manchen
Dingen ist uns die Jugend von heute doch schon weit voraus. Vielleicht
wollen Sie ja selber etwas PHP lernen und lassen sich von Ihrer Tochter
oder Ihrem Sohn hier und da etwas helfen?
Sie unterrichten Programmiersprachen an der Schule? Oder an einer an-
deren Bildungseinrichtung? Ich habe das Buch extra als Unter-
richtsmaterial verfasst. Ich hoffe, dass Sie genug Beispiele und bungen
fr mglichst spannenden und kurzweiligen Unterricht vorfinden.
Egal ob im Unterricht oder fr das Selbststudium: In diesem Buch lernt der
Nachwuchs (und dabei ist die Altersgrenze nach oben hin durchaus flie-
end!), wie dynamische und datenbankgesttzte Webseiten entstehen. Das
ist wichtig, denn lngst setzen die meisten groen Internet-Portale auf
diese Technik. Sie investieren also in die Zukunft Ihrer Tochter, Ihres Sohnes
oder Ihrer Schulklasse. (Oder in Ihre eigene!)
Apropos investieren. Vielleicht sind Sie ja auch bereit, die monatlichen
Kosten fr einen Dienstleister zu tragen, der PHP untersttzt? Denn man-
che der in diesem Buch beschriebenen Programme funktionieren nur dann,
wenn sie auf dem Webserver eines PHP-fhigen Dienstleisters ausgefhrt
werden. Ihr Kind wird schon wissen, was es sich in dieser Beziehung
wnscht.
Bei aller Begeisterung habe ich zum Schluss noch eine kleine Bitte: Achten
Sie auch darauf, dass Ihr Programmiernachwuchs gengend frische Luft
bekommt. Wer zu lange vor dem Computer hockt, bekommt eckige Augen
430
Fr Eltern und Lehrer

Anhang
A
und verliert den Kontakt zur Realitt. Glauben Sie mir, es gibt wichtigere
Dinge im Leben als Computer.
Ihr
Johann-Christian Hanke
www.phpkid.de
431


Anhang B
Hochladen der Seiten mit FTP
Du mchtest deine PHP-Seiten auf den Server laden? Nichts einfacher als
das! Zum Hochladen bentigst du ein FTP-Programm. FTP ist die Abkrzung
fr File Transfer Protocol. Es handelt sich um das bertragungsverfahren
von Dateien zwischen dem Webserver und deinem lokalen PC.
Das wohl bekannteste Programm dieser Art heit FileZilla.
Wir haben dir FileZilla mit auf die CD gepackt. Schaue in den Ordner
programme/filezilla und gehe in den Unterordner fr dein Betriebs-
system.
Die Installation sollte schnell und problemlos vonstatten gehen. Doppelkli-
cke in Windows auf die entsprechende Exe-Datei es ist die Datei
FileZilla_3.2.7.1_win32-setup.exe. Folge den einfachen Schritten.
Das Grundprinzip zum Verffentlichen
Zuerst zu den Grundlagen! Jeder Dienstleister gewhrt dir einen FTP-
Account. Also ein Konto, mit dem du Zugriff auf deinen Webspace be-
kommst und Dateien hochladen kannst. Du bekommst also
0 Benutzernamen (User-ID)
0 Passwort
Du nutzt diese Angaben, um dich mit dem Dienstleister zu verbinden.
Hoppla, du kennst deinen Benutzernamen und das Passwort nicht? Nor-
malerweise findest du diese Daten z. B. im Konfigurationsmen deiner
Webprsenz. Oder auf den Serviceseiten des jeweiligen Dienstleisters.
Im Zweifelsfalle rufst du einfach die Hotline deines Webhosters an!
432
Anhang B

Anhang
B
FileZilla konfigurieren
Ich gehe nun davon aus, dass du die Daten deines FTP-Accounts kennst.
Konfiguriere mit diesen Daten dein FTP-Programm, im Beispiel FileZilla.
>
Klicke auf die Schaltflche FFNET DEN SERVERMANAGER. Es ist die
Schaltflche ganz links.
>
Das Dialogfenster Servermanager erscheint. Whle die Schaltflche
NEUER SERVER, du findest sie im unteren Bereich. Links oben erscheint
ein Symbol mit dem Platzhalternamen Neuer FTP-Server.
>
Vergib einen eigenen Namen. Achte darauf, dass der eben erzeugte
Platzhaltername markiert ist. Klicke auf die Schaltflche UMBENENNEN.
Der Dateiname ffnet sich. Tippe dort einen frei whlbaren Namen
ein, beispielweise den Namen deiner Domain. Klicke neben das Feld,
damit der Name zugewiesen wird.
>
Richte nun mit den Daten deines FTP-Accounts den Zugang ein. Fan-
gen wir mit dem obersten Feld an: Bei SERVER muss in der Regel dein
Domainname stehen. Und zwar nach folgendem Schema:
www.deinedomain.de

>
So ist das beispielsweise bei der Firma Neue Medien Mnnich
(www.all-inkl.com), aber auch bei Hostern wie der 1&1 GmbH
(www.1und1.de).
>
Bei MultiMania dagegen gibst du im Feld SERVER Folgendes ein:
ftp.mitglied.lycos.de

>
Das Feld SERVERTYP lsst du so. Dort muss FTP File Transfer Protocol
stehen. Whle bei VERBINDUNGSART auerdem noch die Einstellung
Normal.

>
Jetzt wird dein Benutzername bentigt. Trage in das Feld BENUTZER die
entsprechende Zeichenfolge ein. Welche, musst du schon selber wis-
sen.
>
Nun folgt dein geheimes PASSWORT. Hier werden dir beim Eintragen
nur Sternchen angezeigt.
>
Wenn du magst, kannst du im Feld KOMMENTARE noch eine kurze Be-
schreibung zu diesem Zugang eintragen. Ntig ist das jedoch nicht.
>
Klicke auf die Schaltflche OK, damit die Daten gespeichert werden.
433
Hochladen der Seiten mit FTP


So richtest du FileZilla fr den Dienstleister MultiMania ein.
So einfach hast du die Verbindung schon eingerichtet. Auf Wunsch
kannst du nun weitere Konten anlegen. Klicke dafr wieder auf die
Schaltflche FFNET DEN SERVERMANAGER.
Hochladen live: FTP-Verbindung herstellen
So, nun geht es ans Hochladen der Dateien. Das ist ganz einfach. FileZilla
ist bei dir geffnet? Sehr gut! Whle nun die gewnschte FTP-Verbindung
aus. Auch das gelingt ber die Schaltflche SERVERVERWALTUNG FFNEN.
Klicke diesmal jedoch nicht direkt auf die Schaltflche du willst ja keinen
neuen Zugang einrichten. Whle den kleinen Pfeil rechts neben dieser
Schaltflche. Nun klappen alle Zugnge herunter, die du schon eingerichtet
hast.

Klicke auf den kleinen Pfeil und whle die gewnschte Verbindung aus.
434
Anhang B

Anhang
B
Das FTP-Programm verbindet sich nun mit dem Server. Du kannst auf dein
Verzeichnis zugreifen. Im linken Bereich siehst du stets den Inhalt der loka-
len Festplatte. Im rechten Bereich hast du Einblick auf deine Daten auf dem
Server.
Die richtigen Dateien markieren
Welche Dateien willst du auf den Server spielen? Bewege dich im linken
Bereich in deinen Projektordner. Navigiere hnlich wie im Windows-
Explorer. Doppelklicke einfach auf den gewnschten Ordner, um ihn zu
ffnen. Du mchtest eine Ordnerebene nach oben? Dann doppelklickst du
stattdessen auf den obersten Ordner, auf den mit den zwei Punkten! Nun
markierst du die entsprechende Datei, die du hochladen mchtest.
Du kannst auch mehrere Dateien und Ordner gleichzeitig markieren. Kli-
cke auf die erste Datei. Drcke nun die ()-Taste, halte sie gedrckt.
Whle jetzt die letzte Datei durch Anklicken aus. Automatisch werden
alle dazwischen liegenden Dateien gleich mitmarkiert. Das Auswhlen
nicht zusammenhngender Dateien und Ordner dagegen gelingt bei ge-
drckter Taste (Strg).
Von links nach rechts: Dateien hochladen
Und wie spielst du nun die Dateien auf den Server? Ganz einfach: Durch
Ziehen mit der Maus!
Beachte zuerst, dass rechts der Ordner eingestellt ist, den der Dienstleis-
ter als Stammordner fr dich zugewiesen hat. Bei MultiMania und Neue
Medien Mnnich musst du nichts verstellen. Hier ist es der voreingestell-
te Ordner. Bei der Domainfactory (www.domainfactory.de) musst du da-
gegen im rechten Bereich erst den Ordner webseiten aufrufen.
Manchmal heit der Ordner auch htdocs oder www.
435
Hochladen der Seiten mit FTP

Alles bereit zum Hochladen? Du hast links die richtigen Dateien und/oder
Ordner markiert? Ziehe den markierten Packen per Maus nach rechts und
lasse die Maustaste los.

berspiele selbst komplette Ordner mit der Mauszugtechnik Drag & Drop.
Kurz danach ist die Seite abrufbereit. Teste, ob die Links stimmen und die
Grafiken angekommen sind! Ziehe gerne auch mehrere Ordner auf einmal
mit Drag & Drop auf den Server. Von links nach rechts. Und sogar vom Win-
dows-Explorer aus. Probiere es einfach aus!
Beachte: Wenn du eine Datei ein zweites Mal hochldst, wird die alte Ver-
sion automatisch berschrieben.
Tipps und Tricks zu FileZilla
Und, hat es geklappt? FileZilla arbeitet wie ein Datei-Manager: Links siehst
du den Inhalt deiner lokalen Festplatte. Rechts bekommst du Einblick in die
Dateien/Ordner auf dem Server. Zum Navigieren in hher oder tiefer gele-
gene Ordner doppelklickst du so lange auf die entsprechenden Ordner bzw.
den Ordner mit den zwei Punkten, bis du auf der gewnschten Ebene ange-
kommen bist!
436
Anhang B

Anhang
B
Sortieren nach Alphabet, Gre oder Datum
Beachte auch die Spaltenkpfe, denn du kannst sie zum Sortieren verwen-
den! Du mchtest feststellen, welche Datei die neueste oder lteste ist? Du
willst deine Dokumente nach Alphabet oder Gre sortieren? Klicke auf
den betreffenden Spaltenkopf. Ein erneuter Klick dreht die Sortierreihenfol-
ge wieder um!
Ordner erstellen
Du mchtest dagegen einen neuen Ordner auf deinem Webserver anlegen?
Das gelingt durch Rechtsklick in einen freien Bereich. Whle den Befehl
VERZEICHNIS ERSTELLEN.
Daten lschen
Du mchtest eine Datei oder einen kompletten Ordner lschen? Markiere
das Element im rechten Bereich. Drcke die Taste [Entf].
Das Lschen eines Ordners gelingt nicht? Beachte, dass der zu lschende
Ordner in manchen Fllen erst leer sein muss. Sonst verweigert FileZilla
manchmal das Lschen. Lsche dann ggf. erst alle Dateien in diesem
Ordner. Probiere das Lschen des Ordners danach erneut!

437


Anhang C
Empfehlenswerte PHP-Editoren
Klar, ich bin ein Fan von PSPad. Dem Editor, den ich im Buch vorgestellt
habe. Doch vielleicht bevorzugst du ein anderes Programm?
Aptana Studio
Aptana Studio ist fr viele Profis erste Wahl, weil es so einen enormen
Funktionsumfang besitzt. Und das Beste: Es luft auch auf dem Mac oder
am Linux-PC. Die Bedienung ist hnlich komfortabel wie die von PSPad. Ich
habe dir Aptana Studio auf der CD unter programme/aptana abgelegt, im
Internet findest du es unter www.aptana.org/studio.
Notepad++
Du magst es schlank und schnell? Dann empfehle ich dir das Windows-
Programm Notepad++. Es besitzt zwar lngst nicht so viele Features wie
Aptana Studio oder PSPad, aber es erfllt seinen Zweck: hervorragende
Farbhervorhebung, Zeilennummerierung, Tools zum Konvertieren in UTF-8
und ANSI, eine Automatik zur Anzeige von Klammernpaaren usw. Beson-
ders wertvoll: Rechtsklicke auf die PHP-Datei im Windows-Editor und wh-
le EDIT IN NOTEPAD++. Die Heimatseite von Notepad++ findest du unter
http://notepad-plus.sourceforge.net/de/site.htm.
Weaverslave
Bis vor kurzem war ich noch ein groer Fan von Weaverslave, dem PHP-
Editor von Thomas Weinert aus Kln. Besonders gut gefllt mir hier die
Farbhervorhebung, HTML- und PHP-Bereiche lassen sich deutlicher vonein-
ander unterscheiden als in anderen Editoren. Leider untersttzt Weaversla-
ve kein Unicode, du kannst also keine in UTF-8 kodierten Dateien bearbei-
ten. Das Programm liegt auf der CD unter programme/weaverslave.
PHPEdit
Auerdem habe ich dir einen Oldtimer auf CD gelegt, die Freeware-
Variante von PHPEdit aus Frankreich. Mir gefllt das Programm deshalb so
gut, weil es den PHP-Code automatisch einrckt. Es liegt unter dem Pfad
programme/phpedit. Die allerneuste (kommerzielle) Version von PHPEdit
bekommst du unter www.phpedit.com.

438
PHP und MySQL lernen

Anhang
c
PHP und MySQL lernen
Du mchtest mehr erfahren ber PHP? Du suchst tolle Web-Ressourcen
zum Nachschlagen?
Umfangreiche Referenz auf SELFPHP
Kennst du die SELFPHP? Es handelt sich um ein hervorragendes, ganz um-
fangreiches Nachschlagewerk zu allen Befehlen und Funktionen von PHP.
Surfe zu www.selfphp.de und schau dich um.
Die offizielle PHP-Seite
Die offizielle PHP-Seite findest du unter www.php.net. Dort gibt es viele
Informationen zu neuen PHP-Versionen und Foren, wo du um Rat nachsu-
chen kannst. Leider sind die meisten Seiten auf Englisch.
Das offizielle PHP-Handbuch
Du suchst einen alternativen Funktions- und Befehlsberblick? Dann emp-
fehle ich dir die deutsche bersetzung des offiziellen PHP-Handbuchs! Du
findest diesen Text zum einen auf der CD, zum anderen auf:
0 www.php-homepage.de/manual
Du mchtest dir das Dokument direkt auf den PC herunterladen, und zwar
in der neuesten Fassung? Dann surfe doch einmal zu folgender Adresse:
0 www.php.net/download-docs.php
Hier findest du dieses Handbuch z. B. als HTML-Version, als PDF-Dokument
und als Version fr den Palm Pilot. Ich nutze dieses Handbuch sehr gerne
zum Nachschlagen! Dabei greife ich stets auf die handliche Version im
HTML-Help-Format zurck. Du findest sie auch auf der Buch-CD unter dem
Pfad dokumente\php_manual.
Das offizielle MySQL-Handbuch
Du mchtest dich intensiver mit MySQL, seinen Mglichkeiten, Datentypen
und Problemen beschftigen? Dann steht dir unter folgender Adresse das
ins Deutsche bersetzte offizielle Handbuch zur Verfgung:
0 http://dev.mysql.com/doc/refman/5.1/de/
439


Stichwortverzeichnis
$
! 162
$_COOKIE 242
$_GET 141
$_POST 141
$_SERVER['PHP_SELF'] 164
.htaccess 342
{ } 117
++ 158
== 119
A
Abbruchbedingung fr Schleifen 194
Absatz 36
action 140
ACTION 61
ADD COLUMN 420
Addieren der Bestellungen 412
addslashes() 351
Adressdatei 295
Adress-Datenbank erweitern 420
Adressen eintragen 307
Aktualisieren von Datenstzen 316
All-inkl.com 73
ALTER TABLE 420
and 121
Apache
installieren 75
installieren, Windows XP/2000 76
Vorteile 75
Array $_POST 230
Arrays 134
assoziativ 129
assoziative Formulardaten 141
aus kommaseparierter Textdatei
266, 274
Datenstze als assoziatives Array
321
einzelner Index-Wert 130
Elemente zhlen 128
foreach 195
fr Cookies 242
fr Tage 126
Index-Wert 126
Kurzform 128, 131
berblick 125
assoziative Arrays 129
fr Cookies 242
Aufgabenteilung JavaScript und PHP
231
Aufzhlungspunkte 43
Austauschen von Zeichen 218
Auswahl begrenzen 315
auto_increment 297
B
Back-Button nachbilden 388
Backslash als Escape-Zeichen 103
Backslashes entfernen 211
Begrenzen der Artikellnge 383, 384
Begrung nach Tagsezeit 124
Berechnungen 157
Bestellsystem 391
Bestell-Tabelle 396
Bestellungen anzeigen 403
Beziehungen zwischen Tabellen 413
Bild in HTML einfgen 40
Blcke markieren 117
Blog 366
Bloggen 366
BODY 36
Bold 38
Bookmark 141
break 194
Break 39
Breite mit width 57
Browservorschau 35
Bruchzahlen, Dezimaltrenner 161
440
Stichwortverzeichnis

C
CAPTCHA
Bildchen 291
per Berechnung 343
CHAR 305
chmod 253
chmod 666 254
chmod 777 254
CMS 365
Content Management System 365
Cookies
Ablaufdatum 244
als assoziatives Array 242
Einfhrung 235
Einstellungen 239
fr Passwortschutz 377
fr Umfrage 272
Lebensdauergarantie 243
lschen 245
setzen 241
Sicherheitsrisiko? 236
sind problematisch 238
Speicherort 237
Zhlstopp fr Counter 256
count() 128
COUNT() 412
Counter 247
mit Zhlstopp 256
CREATE TABLE 302
Cronjob 421, 422
CSS 49
Attribute und Werte 52
Breite festlegen 57
Datei erstellen 51
Kommentare 55
Musterbeispiel 55
D
DATE 306
DATE und VARCHAR() 336
date() 112, 133
Datei anzeigen 284
Datei auslesen 284
Dateien
am Trennzeichen zerlegen 266
Arbeit mit 247, 266
auf Webserver berfhren 434
Modus 250
Dateiendung manipulieren 153
Dateiendungen einblenden 28
Dateigre
ermitteln 265
Dateizeiger 250
Daten ausgeben 90
Datenbank
anlegen 299
Datenbankfelder 301
Datenstze 296
Datentypen 304, 305
Feldnamen 296
phpMyAdmin 298
Planung 296
Speicherordner 309
berblick 295
Datenbank aufteilen 395
Datenbank und Datenbanktabelle 296,
299
Datenbank, Spalte hinzufgen 420
Datenbankdesign, schlechtes 396
Datenbankfelder definieren 301
Datenbanktabelle fr Gstebuch 336
Datenbanktabellen, mehrere 395
Datenbanktabellen, Relationen 398
Datenstze
als Tabelle ausgeben 325
bei MySQL-Tabellen 296
entfernen 316
mit while ausgeben 321
per Formular eingeben 328
sortieren 315
updaten 316
zhlen 323
Datentypen 96
Datentypen fr MySQL 304, 305
DATETIME 306
Datum 111
Datum komplett auf Deutsch 135
Datum mit PHP ausgeben 204
Datumsformate 113
Dekrementieren 158
441
Stichwortverzeichnis

DELETE 316
Dezimaltrenner bei Bruchzahlen 161
Diagramm 267
fr Umfrage 267
Diagramm aus Sulen 169
die() 275
Dienstleister 71