im PDF-Format herunterladen

Werbung
Studienarbeit Medien und Informationswesen
Design, Entwurf und Implementierung einer
KFZ-Sonderausstattungsabfrage als Webseite
bearbeitet durch Mario Schmidt, MI8, Matrikelnummer: 163932
erstellt im Sommersemester 2005 an der Hochschule Offenburg
betreut durch Prof. Dr. Volker Sänger
Inhaltsverzeichnis
Abbildungsverzeichnis
4
Listings
5
Tabellenverzeichnis
6
1. Allgemeines
1.1. Aufgabenbeschreibung . . .
1.2. Vorkenntnisse . . . . . . .
1.2.1. HTML, CSS & Co.
1.2.2. PHP . . . . . . . .
1.2.3. MySQL . . . . . . .
1.2.4. Apache . . . . . . .
1.2.5. Adobe Photoshop .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
7
7
7
7
8
8
8
8
2. Planung
2.1. Datenbankplanung . . . . . .
2.2. Webseiten-Design . . . . . .
2.3. Entwicklungsumgebung . . .
2.3.1. Entwicklungswebserver
2.3.2. Editor . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
9
9
12
13
13
14
.
.
.
.
.
.
.
.
.
16
16
17
18
22
22
23
24
27
29
3. Implementierung
3.1. MySQL Datenbankaufbau . . . . . .
3.1.1. Erstellung des Datenbestands
3.2. XHTML Seitenbeschreibung . . . . .
3.3. PHP Programmierung . . . . . . . .
3.3.1. Dateiordnung . . . . . . . . .
3.3.2. Datenbankklasse . . . . . . .
3.3.3. Datenverarbeitungsklasse . .
3.3.4. Mailklasse . . . . . . . . . .
3.3.5. Sonstige Programmierung . .
Inhaltsverzeichnis
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2
4. Ergebnis
4.1. Betatest . . . . . .
4.2. Das fertige Produkt
4.3. Schlußbetrachtung .
4.4. Ausblick . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
35
35
36
36
37
A. Anhang
38
A.1. Inhalte der CD-ROM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
A.2. Informationen zur benutzten Software . . . . . . . . . . . . . . . . . . . . . 38
Literaturverzeichnis
Inhaltsverzeichnis
39
3
Abbildungsverzeichnis
2.1.
2.2.
2.3.
2.4.
2.5.
2.6.
2.7.
erster Entwurf des ER-Schemas . . . . . . .
zweiter Entwurf des ER-Schemas . . . . . .
endgültiges ER-Schema . . . . . . . . . . .
Datenbanktabellen . . . . . . . . . . . . . .
unfertiges Designbeispiel 1 . . . . . . . . . .
unfertiges Designbeispiel 2 . . . . . . . . . .
Homesite HTML-Editor mit geöffneter Datei
.
.
.
.
.
.
.
9
10
11
12
12
13
15
3.1. unterschiedliche Darstellung in vier gängigen Browsern . . . . . . . . . . . .
3.2. Darstellung ´mit und ohne CSS . . . . . . . . . . . . . . . . . . . . . . . .
21
22
Abbildungsverzeichnis
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4
Listings
2.1. Konfiguration von Virtual Hosts bei Apache . .
3.1. Anlegen einer neuen Datenbank . . . . . . . .
3.2. Anlegen der Tabelle Sonderausstattungen . . .
3.3. Anlegen der Tabelle Polsterung . . . . . . . .
3.4. Anlegen der Tabelle Lackierung . . . . . . . .
3.5. Dokumententyp einer XHTML-Datei . . . . .
3.6. Blockelemente einer XHTML-Datei . . . . . .
3.7. CascadingStyleSheet-Datei . . . . . . . . . . .
3.8. Erstellung eines Datenbankobjekts . . . . . . .
3.9. Verarbeitung der SQL-Ergebnisse . . . . . . .
3.10. falsche Eingaben prüfen . . . . . . . . . . . .
3.11. SQL-Code generieren . . . . . . . . . . . . .
3.12. HTML-Code für die Ausgabe generieren . . . .
3.13. Die Methoden der Klasse: sendmail . . . . .
3.14. allgemeine Logik zum Inkludieren von Dateien
3.15. Anlegen eines data_handler-Objekts . . . . .
3.16. Fehlerüberprüfung der Eingaben . . . . . . . .
3.17. Absenden der Datenbankanfrage . . . . . . . .
3.18. Ausgabe der Ergebnisse . . . . . . . . . . . .
3.19. Mail über das Kontaktformular verschicken . .
Listings
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
14
16
16
17
17
18
18
19
23
23
24
25
26
27
29
30
31
31
32
33
5
Tabellenverzeichnis
3.1. Darstellung und Benutzbarkeit in verschiedenen Browsern . . . . . . . . . .
Tabellenverzeichnis
21
6
1. Allgemeines
Als Einführung wird eine allgemeine Aufgabenbeschreibung und die dazugehörige Ausgangssituation beschrieben. Welche Kenntnisse bestehen schon, was soll mit der Arbeit vertieft
beziehungsweise erlernt werden.
1.1. Aufgabenbeschreibung
Ziel der Arbeit ist es, eine Sonderausstattungsabfrage für Mercedes-Benz Fahrzeuge der
Baureihe W126 als Webseite zu erstellen. Diese soll datenbankbasierend sein.
Viele Liebhaber dieser Baureihe möchten nach dem (Gebraucht-)Kauf gerne den damaligen
Auslieferungszustand ihres Fahrzeuges wissen. Welche Sonderausstattungsmerkmale wurden
zusätzlich zur Serienausstattung vom Erstbesitzer bestellt. Hier gibt es zwei Möglichkeiten.
Man kann sich bei Mercedes die Datenkarte ausdrucken lassen oder man erwirbt eine so
genannte EPC-CD1 bei Mercedes. Gibt man nach Installation der CD im Programm eine
Fahrgestellnummer ein, bekommt man die Sonderausstattungscodes, mit denen der Wagen
das Werk verlassen hat, zurück. Leider sind dies nur die reinen (dreistelligen) Zahlencodes,
nicht mehr.
Genau hier setzt diese Studienarbeit an. Die Liebhaber fragen meist in einschlägigen Foren
im Internet nach, was diese Codes bedeuten. Wieder andere suchen per Hand die Aufschlüsselungen der Codes und antworten. Genau dieser Schritt soll automatisiert werden. Die Codes
werden in ein Formular eingegeben und zurück kommt die Beschreibung.
1.2. Vorkenntnisse
1.2.1. HTML, CSS & Co.
Sehr gute Grundkenntnisse in HTML 4.012 und CSS 23 , sowie fundierte Grundkenntnisse in
JavaScript sind vorhanden. Die Webseite soll XHTML 1.04 konform mit dem Dokumenttyp
Transitional erstellt werden. Dies stellt die erste Lernstufe dar. Parallel zur Entwicklung
wird der offizielle W3C HTML-Validator[7] benutzt, um die Seiten auf Fehler zu überprüfen.
Ebenso werden die CSS-Dateien mit dem offiziellen W3C CSS-Validator[6] überprüft.
1
„Electronic Parts Catalog-CD“
HyperText Markup Language 4.01
3
Cascading Style Sheets 2
4
eXtensible HyperText Markup Language 1.0
2
1. Allgemeines
7
1.2.2. PHP
PHP5 -Grundkenntnisse sind vorhanden. Bisher beschränkte es sich allerdings darauf, vorhandene Skripte für die eigenen Bedürfnisse anzupassen. Die strukturierte Programmierung soll
nun anhand dieser Arbeit erlernt werden.
1.2.3. MySQL
Die Kenntnisse im Bereich relationale Datenbanken beschränken sich auf das Wissen aus der
Vorlesung „Datenbanken“ und dem dazugehörigen „Labor: Datenbanken“. Mit dieser Arbeit
soll der praktische Umgang mit der relationalen Datenbank MySQL erlernt werden. Sie bietet
sich an, da PHP von Haus aus sehr viele Funktionen mit sich bringt, die speziell für die Arbeit
mit MySQL geschaffen wurden.
1.2.4. Apache
Im Umgang mit Webservern sind keine Kenntnisse vorhanden. Um angenehm entwickeln zu
können soll ein Apache Webserver aufgesetzt und konfiguriert werden. Der Zielserver für die
Veröffentlichung wird ebenfalls ein Apache Webserver sein.
1.2.5. Adobe Photoshop
Sehr gute Adobe Photoshop Kenntnisse sind vorhanden. Mittels Photoshop wird das Layout und Design der Webseite erstellt, welches danach mit XHTML (vgl. Abschnitt 1.2.1)
umgesetzt wird.
5
rekursives Akronym für „PHP: Hypertext Preprocessor“, ursprünglich „Personal Home Page Tools“
1. Allgemeines
8
2. Planung
In diesem Kapitel wird zuerst die Datenbankplanung dokumentiert. Danach wird gezeigt,
wie das (Web-)Design entstand, um dann noch kurz auf die zur Implementierung genutzte
Entwicklungsumgebung einzugehen.
2.1. Datenbankplanung
Am Anfang eines jeden datenbankbasierenden Projekts steht die Planung der eigentlichen
Datenbankstruktur. Von ihr hängt der weitere Verlauf der Implementierung, sowie die Komplexität direkt ab. Die Datenbankplanung ist somit einer der wichtigsten Schritte.
Dazu wird als erstes ein ER-Schema1 erstellt, um die Verknüpfungen der einzelnen Entities
untereinander überblicken zu können. Im ersten Entwurf werden eher zu viel, als zu wenig
Informationen eingebracht. Man verringert so die Gefahr, wichtige Details auszulassen und
diese zu übersehen. Das erste ER-Schema zu diesem Projekt sieht wie in Abbildung 2.1 aus.
Abbildung 2.1.: erster Entwurf des ER-Schemas
Von diesem ER-Schema ausgehend kann man nun im Ausschlußverfahren die unnötigen
Bestandteile herauskürzen. Im ersten Entwurf ist im Prinzip fast jeder Bestandteil eines Autos
1
Entity-Relationship Schema
2. Planung
9
beinhaltet. Man hätte damit eine Datenbank zum Speichern von Autos, mit den dazugehörigen Sonderausstattungsmerkmalen, entwerfen können. Durch Diskussion und Blick auf den
eigentlichen Sinn der Anwendung, wird das ER-Schema in Abbildung 2.2 entwickelt.
Abbildung 2.2.: zweiter Entwurf des ER-Schemas
Man erkennt, dass hier einiges verfeinert wurde. Bei der weiteren Diskussion des zweiten Entwurfs stellt sich heraus, dass zu viel Gewicht auf den Preis gelegt wird. Es wäre
ein vielfach höherer Programmieraufwand geworden dieses Schema zu implementieren. Da
das Hauptaugenmerk aber auf Sonderausstattungsmerkmalen liegt, muss hier also nochmals
nachgebessert werden. Statt mit einzelnen Tabellen für den Preis zu rechnen, werden Felder
für den Minimal- und den Maximalpreis eines Sonderausstattungsmerkmals eingeführt, sowie
ein Zusatzinfofeld, in dem weiterführende Informationen zum Preis oder auch des ganzen
Sonderausstattungsmerkmals gespeichert werden. So entsteht nochmals ein deutlich vereinfachtes ER-Schema welches in Abbildung 2.3 dargestellt wird.
Aus diesem ER-Schema entstehen die Tabellen, die später in der Datenbank implementiert
werden. Nachdem die Felder klar sind, müssen sinnvolle Spaltentypen gewählt werden.
• code wird mit dem Spaltentyp SMALLINT UNSIGNED ZEROFILL definiert, da hier positive Zahlen größer als 255 gebraucht werden. Falls ein Code ohne führende Null eingegeben wird, so wird sie automatisch eingefügt, um wieder einen dreistelligen Code
zu bekommen.
2. Planung
10
Abbildung 2.3.: endgültiges ER-Schema
• beschreibung und zusatzinfo wird mit dem Spaltentyp TEXT definiert, da hier Texte
variabler Länge gespeichert werden.
• bild und farbe werden mit dem Spaltentyp VARCHAR() definiert, da hier nur kurze
Zeichenfolgen gespeichert werden. Für bild sind maximal 200 Zeichen vorgesehen,
da hier URLs2 zu den Bildern des jeweiligen Sonderausstattungsmerkmals gespeichert
werden. Für farbe werden maximal 30 Zeichen vorgesehen, da hier kurze Farbnamen
der Lackierungen und Polster gespeichert werden.
• polsterart und lackart werden mit dem Spaltentyp SET(„“) definiert, da hier
bestimmte Worte gespeichert werden. Für polsterart sind die Worte Stoff, MB-Tex,
Amaretta, Leder und Velour vorgesehen. Für lackart sind die Worte Serien- und
Sonderlackierungen und Metallic Lackierungen vorgesehen.
• minPreis und maxPreis werden mit dem Spaltentyp MEDIUMINT UNSIGNED definiert,
da hier Preise gespeichert werden. Es werden nur positive Werte benötigt. Eingegeben
werden Pfennigbeträge3 , die vor der Ausgabe umgerechnet werden. Würde man FLOAT
als Spaltentyp benutzen, bekäme man unter Umständen bei Rechenoperationen falsche
Werte durch Rundungsfehler.
2
3
Uniform Resource Locator
Zu Bauzeiten des W126 gab es noch die Deutsche Mark. Die Werte sollen hier absichtlich erhalten bleiben
und werden somit nicht in Euro umgerecht. Besser wäre es später eine Euroumrechnungsfunktion zu
schreiben, die auf die Originalpreise zugreift.
2. Planung
11
Diese Tabellen sind in Abbildung 2.4 schematisch dargestellt.
Abbildung 2.4.: Datenbanktabellen
2.2. Webseiten-Design
Das eigentliche Design wird im Programm Adobe Photoshop entworfen (vgl. Abschnitt 1.2.5).
Das Design soll einfach, schlicht und vor allem benutzerfreundlich gehalten werden. Genauso
soll es aber auch modern und frisch erscheinen.
Es besteht anfangs die Frage, ob die Anwendung ein eigenes Browserfenster ausfüllen soll
oder nicht. Da die Anwendung aber relativ klein ist, wird sie so aufgebaut, dass man sie einerseits normal im Browser aufrufen kann und andererseits auch in einem Popupfenster benutzen
kann. Es werden mehrere Designs ausprobiert und sich am Ende für eines entschieden.
Zwei anfängliche Designbeispiele zeigen die beiden Abbildungen 2.5 und 2.6.
Abbildung 2.5.: unfertiges Designbeispiel 1
2. Planung
12
Abbildung 2.6.: unfertiges Designbeispiel 2
2.3. Entwicklungsumgebung
Im Folgenden wird die Entwicklungsumgebung, in der diese Studienarbeit erstellt wird, näher
betrachtet. Entwickelt wird auf einem Apple Rechner, der unter Mac OSX4 10.3.8 läuft. Da
Mac OSX auf Unix basiert hat das den entscheidenden Vorteil, auf der selben Grundplattform
entwickeln zu können, auf der das Programm später laufen soll. Desweiteren hat man so den
Vorteil direkt „auf dem Server“ arbeiten zu können. Folglich muss man nicht nach jeder
erfolgten Änderung in einem Skript, dieses einzeln auf den Server laden, um es zu testen.
Einfaches Speichern und Neuladen reicht aus.
2.3.1. Entwicklungswebserver
Mac OSX hat von Hause aus einen vorinstallierten Apache5 Webserver. Auf dem Entwicklungswebserver läuft Version 1.3.33, welche bis dato die aktuellste Version darstellt. Um die
Entwicklung zu erleichtern, müssen als erstes PHP (Version 4.3.6) und MySQL (Version
4.1.11-standard) installiert werden. Auf der Homepage6 des Schweizers Marc Liyanage können sehr einfach zu installierende PHP Packages für Mac OSX gefunden werden. MySQL
Packages können auf der offiziellen MySQL Homepage7 heruntergeladen werden. Aufgrund
der sehr guten Anleitung auf Marc Liyanages Homepage[5] stellte auch diese Installation kein
Problem dar.
Nachdem PHP und MySQL installiert sind, soll sicher gestellt werden, dass es möglich ist,
mehrere Webprojekte nebeneinander und störungsfrei auf dem Server zu entwickeln und zu
testen. Es werden mehrere sogenannte virtuelle Hosts konfiguriert. Dazu musste die Konfigurationsdatei httpd.conf des Webservers angepasst werden. Ein Beispiel für das Hinzufügen
4
Betriebssystem der Firma Apple
http://www.apache.org
6
http://www.entropy.ch
7
http://dev.mysql.com/downloads/mysql/4.1.html
5
2. Planung
13
eines virtuellen Host ist im Listing 2.1 zu sehen.
Listing 2.1: Konfiguration von Virtual Hosts bei Apache
1
2
3
4
5
< VirtualHost 127.0.0.1 >
ServerName dev1 . dd
DocumentRoot / Library / WebServer / dev1 . dd
ServerAdmin mario@skapunk . de
</ VirtualHost >
Zusätzlich müssen die angelegten virtuellen Hosts in der hosts-Datei des Rechners eingetragen werden und auf die IP 127.0.0.18 gesetzt werden. Ein Nameserver im Internet würde
die Top-Level-Domain .dd nicht finden und einen Fehler ausgeben. Gibt man nun im Browser
http://dev1.dd ein, wird man auf das entsprechende Verzeichnis geleitet und kann Dateien
aufrufen, wie auf einem Webserver im Internet auch.
Um später Änderungen direkt in der Datenbank vornehmen zu können, wird noch das
Programm phpMyAdmin9 in der Version 2.6.2 installiert. Damit ist es möglich, Datenbanken
über ein Webinterface direkt zu manipulieren. Es können auch, wie von der Konsole gewohnt,
SQL-Befehle eingegeben werden.
2.3.2. Editor
Als Editor für den HTML und PHP Code fällt die Entscheidung auf Homesite10 der Firma
Marcomedia. Er besticht vor allen durch seine Schnelligkeit im Umgang mit allerlei Textdateien und bringt auch keine unnötige WYSIWYG11 Oberfläche mit sich. Da man den Code
von Hand schreiben muss, kann die W3C Konformität (vgl. Abschnitt 1.2.1) deutlich leichter
erreicht und kontrolliert werden.
8
Loopback Device oder localhost, gemeint ist der eigene Rechner
http://www.phpmyadmin.net
10
http://www.macromedia.com/software/homesite/
11
WhatYouSeeIsWhatYouGet
9
2. Planung
14
Abbildung 2.7.: Homesite HTML-Editor mit geöffneter Datei
2. Planung
15
3. Implementierung
In diesem Kapitel wird die Vorgehensweise der Implementierung beschrieben. Hier werden
Codebeispiele gezeigt, die die Umsetzung näher erläutern und damit das Projekt wesentlich
dokumentieren.
3.1. MySQL Datenbankaufbau
In Kapitel 2.1 wird die Planung der Datenbankstruktur erläutert. Die aus dem erarbeiteten
ER-Schema entstandenen Tabellen werden nun in einer Datenbank angelegt. Dazu wird eine
neue Datenbank erstellt. Sie heisst w126sa. Der Einfachkeit halber werden die Befehle mit
phpMyAdmin durchgeführt.
Listing 3.1: Anlegen einer neuen Datenbank
1
CREATE DATABASE ’ w126sa ’;
Als nächstes werden die einzelnen Tabellen, wie sie im Abschnitt 2.1 beschrieben werden,
angelegt. Den Tabellennamen wird ein Präfix „sa_“ vorrangestellt. Dies geschieht aus dem
Grund, um später alle zur Anwendung gehörenden Tabellen leichter aufzufinden. Spätestens
wenn die Möglichkeit besteht, dass in einer Datenbank mehrere Anwendungen Tabellen anlegen muss man sich darüber Gedanken machen, wie man diese später unterscheiden kann. Will
man also zum Beispiel die Anwendung später entfernen, so müssen nur diejenigen Spalten
gelöscht werden, die das Präfix enthalten. Daraus folgt, dass natürlich jede Anwendung auch
ein eigenes und eindeutiges Präfix benutzt.
Listing 3.2: Anlegen der Tabelle Sonderausstattungen
1
2
3
4
5
6
7
8
9
CREATE TABLE ’ s a _s o n d e r ausstattung ’(
’ code ’ SMALLINT (3) UNSIGNED ZEROFILL NOT NULL ,
’ beschreibung ’ TEXT NOT NULL ,
’ bild ’ VARCHAR (200) NOT NULL ,
’ minPreis ’ MEDIUMINT UNSIGNED NOT NULL ,
’ maxPreis ’ MEDIUMINT UNSIGNED NOT NULL ,
’ zusatzinfo ’ TEXT NOT NULL ,
PRIMARY KEY ( ’ code ’)
);
Die beiden Tabellen für Polsterung und Lackart werden analog dazu angelegt. Die SQLBefehle sind im Listing 3.3 und 3.4 zu sehen. Nach dem alle drei Tabellen angelegt sind,
müssen als nächstes verwertbare Daten in die Spalten gefüllt werden. Anhand vorhandener Ori-
3. Implementierung
16
ginalpreislisten von Mercedes werden CSV-Dateien1 erstellt, die wiederum mit phpMyAdmin
importiert werden.
Listing 3.3: Anlegen der Tabelle Polsterung
1
2
3
4
5
6
7
8
9
10
CREATE TABLE ’ sa_polster ’(
’ code ’ SMALLINT (3) UNSIGNED ZEROFILL NOT NULL ,
’ farbe ’ VARCHAR (30) NOT NULL ,
’ polsterart ’
SET ( ’ Stoff ’ , ’MB - Tex ’ , ’ Amaretta ’ , ’ Leder ’ , ’ Velours ’)
NOT NULL ,
’ bild ’ VARCHAR (200) NOT NULL ,
’ minPreis ’ MEDIUMINT UNSIGNED NOT NULL ,
’ maxPreis ’ MEDIUMINT UNSIGNED NOT NULL ,
’ zusatzinfo ’ TEXT NOT NULL ,
PRIMARY KEY ( ’ code ’)
);
Listing 3.4: Anlegen der Tabelle Lackierung
1
2
3
4
5
6
7
8
9
10
CREATE TABLE ’ sa_lack ’(
’ code ’ SMALLINT (3) UNSIGNED ZEROFILL NOT NULL ,
’ farbe ’ VARCHAR (30) NOT NULL ,
’ lackart ’ SET ( ’ Serien - und
Sonderlackierung ’ , ’ Metalliclackierung ’) NOT
NULL ,
’ bild ’ VARCHAR (200) NOT NULL ,
’ minPreis ’ MEDIUMINT UNSIGNED NOT NULL ,
’ maxPreis ’ MEDIUMINT UNSIGNED NOT NULL ,
’ zusatzinfo ’ TEXT NOT NULL ,
PRIMARY KEY ( ’ code ’)
);
3.1.1. Erstellung des Datenbestands
Ein großer Teil der Arbeit bestand auch darin, die angelegte Datenbank mit Daten zu füllen.
Diese Daten sind überall verstreut im Internet zu finden. Eine relativ komplette Auflistung
der damaligen Preislisten ist auf der Webseite von Ingo Licha2 zu finden. Die Listen wurden
komplett in einer Tabelle zusammengefügt um danach Dubletten zu entfernen. Ebenso wurde
somit der Minimal- und Maximalpreis der verschiedenen Ausstattungsmerkmale ermittelt.
Die Bilder stammen zum großen Teil von Martin Makolskis Webseite3 . Hier sind ein paar
schöne Auflistungen zum Thema Lacke und Polster zu finden. Die Originalprospektfotos
1
CSV steht für Character Separated Values. Es handelt sich um tabellarisch strukturierte Daten die
durch ein spezielles Zeichen getrennt werden. Solche Dateien können in jedem beliebigen Texteditor
erstellt werden.
2
Die Webseite von Ingo Licha ist zu finden unter http://www.meinbenz.de
3
Martin Makolskis Webseite findet man unter http://www.mercedes500.de
3. Implementierung
17
stammen wiederum von Ingo Lischas Seite. Die restlichen Bilder stammen entweder aus dem
Internet oder aus dem eigenen Fotobestand, der bei verschiedenen Treffen entstand.
3.2. XHTML Seitenbeschreibung
Jede korrekte XHTML-Datei muss über einen richtig definierten Dokumententyp definiert
sein. Dies geschieht ganz am Anfang der jeweiligen XHTML-Datei.
Listing 3.5: Dokumententyp einer XHTML-Datei
1
2
3
4
5
<! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0
Transitional // EN "
" http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
< html xmlns = " http :// www . w3 . org /1999/ xhtml " >
< head profile = " http :// gmpg . org / xfn /1 " >
< title > W126 S o n d e r a u s st a t t u ng s a b fr a g e - Online SA - Codes
abfragen </ title >
< meta http - equiv = " Content - Type " content = " text / html ;
charset = UTF -8 " / >
Am Ende sieht man noch die Zeichencodierung, welche im diesem Fall als UTF-84 angegeben ist. Falls das Encoding nicht seitens des Servers erledigt wird, kann man so sicher gehen,
dass Sonderzeichen auch in anderen Ländern richtig übertragen werden. Die Verwendung in
einem Meta-Tag5 sichert die Abwärtskompatibilität in älteren Browsern, die mit XML6 Daten
nicht richtig umgehen können.
Danach wird die Grundstruktur des Designs in XHTML übertragen. Das Design besteht
aus einem Headerbereich. Die Navigation befindet sich links darunter. Der Contentbereich
füllt den Rest des Platzes auf. Wo früher bei solchen Designs mit Tabellen hantiert wurde,
wird das gesamte Layout nun mittels CSS positioniert. In der XHTML-Datei werden nur noch
die einzelnen Bereiche als sogenannte Blockelemente notiert. Soviel zu Theorie. In der Praxis
sieht es so aus, dass leider die vielen verschiedenen Browser die CSS-Standards des W3C
mehr oder weniger gut beherrschen.
In der Umsetzung werden dann die Blockelemente wie in Listing 3.6 beschrieben. Man
sieht, dass hier keinerlei Angabe zur Position oder Formatierung angegeben werden. Diese
sind komplett in der CascadingStyleSheet-Datei enthalten, die in Listing 3.7 (mit Kürzungen)
zu sehen ist.
Listing 3.6: Blockelemente einer XHTML-Datei
1
2
3
4
5
< body >
< div id = " header " >
< div id = " headerimg " >
< div id = " pagetitle " >
<! -- Header - Bereich -- >
4
populäre Kodierung für Unicode-Zeichen
Meta-Tags sind HTML-Elemente einer Webseite, welche Metadaten über diese Webseite enthalten.
6
XML ist die Abkürzung für Extensible Markup Language.
5
3. Implementierung
18
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</ div >
</ div >
</ div >
< div id = " wrapper " >
< div id = " navigation " >
<! -- Na vig ati ons ber eich -- >
</ div >
< div id = " contentwrapper " >
< div id = " content " >
<! -- Content - Bereich -- >
</ div >
</ div >
</ div >
</ body >
Listing 3.7: CascadingStyleSheet-Datei
1
/* Allgemeine CSS */
2
3
4
5
body {
margin : 0; font - family : Arial , Helvetica , Verdana ,
sans - serif ; font - size : 12 px ; background - color : # fff ;
text - align : left ;
}
6
7
[...]
8
9
/* Layout */
10
11
12
13
# header {
padding : 0; margin : auto auto ; height : 75 px ; width : 100%;
background : url ( " img / bg / header_bg . jpg " ) no - repeat top
center ; position : fixed ; z - index : 3;
}
14
15
[...]
16
17
18
19
# navigation {
background : # FFFFFF ; width : 110 px ; min - height : 200 px ; top :
75 px ; margin : 0; padding : 5 px 0 px 5 px 5 px ; font - size :
10 px ; position : fixed ;
}
20
21
22
23
# navigation ul {
margin : 0 px ; padding : 0 px ;
}
24
3. Implementierung
19
25
[...]
26
27
28
29
# contentwrapper {
position : absolute ; top : 75 px ;
right : auto ;
width : 500 px ;
}
left : auto ;
30
31
32
33
# content {
background : # fff ; padding : 5 px 5 px 5 px 5 px ; position :
absolute ; right : 0 px ;
width : 370 px ;
}
34
35
[...]
Als sehr guter Browser zur Entwicklung hat sich Mozilla Firefox7 herausgestellt. Er lässt
sich mittels Plugins zusätzlich für die Webentwicklung anpassen. Da auf Grund der starken
Stellung von Microsoft Windows, deren hauseigener Browser Internet Explorer oft benutzt
wird, wird speziell auch dort auf eine korrekte Darstellung geachtet. Genau hier lag auch
ein Hauptteil der Arbeit. Leider hat der Microsoft Internet Explorer eine sehr fehlerhafte
Implementierung von CSS2, weshalb man immer wieder Code ändern und anpassen muss,
damit ein Layout funktioniert. Man steckt erfahrungsgemäß in etwa die doppelte Zeit in die
Entwicklung hinein um Workarounds für diese Bugs zu finden. Ein paar Beispiele, die bei der
Entwicklung dieser Studienarbeit als Bugs im Internet Explorer aufgetreten sind.
• Text der kleiner als 11 Pixel groß ist, kann nicht fett dargestellt werden.
• Breiten- und Höhenangaben werden nicht mit Paddingangaben verrechnet, sondern
addiert. Dadurch erschwert sich die Positionierung erheblich.
• Gepunktete Linien (border-style: dotted;) werden falsch dargestellt, wie border-style:
dashed;.
• position: fixed; wird nicht unterstützt (Windows).
• a:hover; wird vom Internet Explorer 5.2 (Macintosh) und 5.5 (Windows) nicht richtig interpretiert. Fährt man über einen Link erscheínt kein Handcursor. Benutzt man
cursor: hand; funktioniert es wieder. Laut W3C gibt es aber in den CSS-Spezifikationen
keine solche Option und die Dokumente validieren so nicht mehr.
Um aber auf den meisten gängigen Browsern die Benutzbarkeit der Anwendung sicherzustellen, wird sie mit verschiedenen Browsern getestet und bewertet. Tabelle 3.1 gibt nähere
Auskunft über die Darstellung in den verschiedenen Browsern. In Abbildung 3.1 sieht man
die unterschiedliche Darstellung in vier gängigen Browsern.
7
Mozilla Firefox ist ein aus der Mozilla-Suite hervorgegangener Standalone-Browser. Download unter folgendem URL: http://www.mozilla-europe.org/de/products/firefox/
3. Implementierung
20
Tabelle 3.1.: Darstellung und Benutzbarkeit in verschiedenen Browsern
Gecko (Mozilla, Firefox, etc.) 1.0.4
Internet Explorer 6
Opera 8
Safari 1.2
Darstellung in % Benutzbarkeit in %
100
100
80
100
90
100
100
100
Abbildung 3.1.: unterschiedliche Darstellung in vier gängigen Browsern
3. Implementierung
21
Benutzer nicht CSS-fähiger Browser können dank der sauberen Trennung zwischen Layout
und Inhalt dennoch die Seite nutzen. Benutzt jemand beispielsweise Lynx8 als Browser sieht
er nur den reinen Text. Hier zeigt sich wie klar eine Seite strukturiert ist um sie auf solchen
Browsern anzuzeigen. Tabellenlayouts oder Frames bereiten hier bei der Navigation im Textbrowser arge Probleme. In Abbildung 3.2 sieht man die unterschiedliche Darstellung mit und
ohne CSS.
Abbildung 3.2.: Darstellung ´mit und ohne CSS
3.3. PHP Programmierung
In diesem Abschnitt werden die erstellten Klassen und sonstige Programmierlogik genauer
erklärt. Es werden keine Quellcodes komplett gelistet, da diese auch auf der beiliegenden
CD-ROM zu finden sind. Sollte es dem Verständnis dienen, werden natürlich kurze Auszüge
aus den Quellcodes eingebunden.
3.3.1. Dateiordnung
Komplette HTML-Seiten und CSS-Dateien werden alle im Root-Verzeichnis des Webservers
gespeichert. Alle Dateien die inkludiert werden oder zur Anwendung gehören, wie z.B. Klassendateien, werden im Unterverzeichnis /inc gespeichert. Dort sind sie durch ein Präfix
voneinander zu unterscheiden. „class.“ steht allen Klassendateien vor. Sie beinhalten fast
aussschließlich PHP-Code. „inc.“ steht für normale Dateien, die durch andere Dateien inkludiert werden. Sie beinhalten meist Teilstücke einer HTML-Seite und PHP-Code. „tpl.“
steht vor allen Dateien, die als Template benutzt werden. Sie enthalten nur HTML-Code,
der teilweise mit Platzhaltern versehen ist, damit später per Suchen und Ersetzen Inhalte
eingefügt werden können.
Die Bilder befinden sich im Unterordner img. Dort sind sie wiederum aufgeteilt in die
Unterordner bg (für Hintergrundbilder der Seite im allgemeinen), lacke (für alle Bilder der
verschiedenen Lacke), polster (für alle Bilder der verschiedenen Polster) und sa (für alle
Bilder der verschiedenen Sonderausstattungen).
8
Lynx ist ein textbasierter Browser, der keine Grafiken anzeigt. Er wird meist auf Terminals benutzt und ist
auf vielen Unixsystemen direkt verfügbar.
3. Implementierung
22
3.3.2. Datenbankklasse
Die Datenbankklasse ist für alle Verbindungen und Abfragen mit der Datenbank zuständig. Als Variablen des entstehenden Objekts werden eine Objektreferenz, der Benutzername,
das Passwort, die Serveradresse und der Datenbankname gesetzt. Die Konstruktormethode9
mysql füllt diese Variablen bei der Erstellung mit den entsprechenden Werten. So ist sichergestellt, dass die Zugangsdaten mit Instanzierung eines neuen Objekts vorhanden sind. Sie
haben den selben Namen wie die Klasse.
Listing 3.8: Erstellung eines Datenbankobjekts
1
/* Datenbankdaten */
2
3
4
5
6
$user
$pass
$server
$db
=
=
=
=
" username " ; // Benutzername
" password " ; // Passwort
" localhost " ; // Datenbankserver
" w126sa " ; // Datenbankname
7
8
include ( " class . mysql . php " ) ; // Datenbankklasse includen
9
10
$dbconnection = new mysql ( $user , $pass , $server , $db ) ; //
Konstruktor wird direkt mit den Werten aufgerufen
11
12
$dbconnection - > dbconnect () ; // Verbindung wird hergestellt
Die Methode dbconnect stellt die Verbindung zur Datenbank her und wählt dann eine Datenbank aus. Sie erwartet keine weiteren Argumente und bezieht ihre Informationen aus den
Variablen des Objekts. Tritt ein Fehler auf, wird eine Fehlermeldung, die die MySQL Fehlerbeschreibung beinhaltet, ausgegeben. Ansonsten wird die Referenz der Datenbankverbindung
in die Variable des Objekts gespeicherrt und true zurückgegeben.
Die Methode dbquery stellt Anfragen an die Datenbank. Als Argumente erwartet sie
SQL Code in einem String und die Referenz der Datenbankverbindung. Tritt ein Fehler bei
der Anfrage auf, so wird dieser mitsamt der MySQL-Fehlerbeschreibung ausgegeben. Ist die
Anfrage erfolgreich, wird ein mehrdimensionales Array gebildet. Es ist auf erster Ebene über
einen Index ansprechbar. In zweiter Ebene werden die Ergebnisse der Anfrage als assoziatives
Array gespeichert. Dieses Array wird am Ende zurückgegeben.
Listing 3.9: Verarbeitung der SQL-Ergebnisse
1
2
3
4
5
9
$count = 0; // Zaehlervariable fuer Datenarray
$data = array () ; // Datenarray
while ( $row = mysql_fetch_assoc ( $results ) ) { // Zeilen
auslesen
$data [ $count ] = $row ; // jede Zeile in den ( assoz .) Array
schreiben
$count ++;
Die Konstruktormethode wird mit der Erstellung eines neuen Objektes einer Klasse aufgerufen. Sie wird
also mindestens einmal innerhalb der Lebensdauer eines Objekts ausgeführt.
3. Implementierung
23
6
7
8
}
mysql_free_result ( $results ) ; // Ergebnisse freigeben
return $data ; // assoz . Array zurueckgeben
3.3.3. Datenverarbeitungsklasse
Die Klasse data_handler ist für alle Manipulationen an den Daten zuständig, die über die
SQL-Anfrage zurückgegeben werden. In ihr werden als Variablen, die vom Benutzer gesendeten Eingaben für Sonderausstattungscodes, Lackcode und Polstercode, sowie die Information
ob eine ausführliche Ausgabe gewünscht ist, gespeichert. Dies geschieht, wie auch schon bei
der Klasse mysql, mit Instanzierung eines neuen Objekts und des automatischen Aufrufs der
Konstruktormethode data_handler.
Die Methode codeCheck erwartet einen String als Argument, welcher die vom Benutzer
eingegebenen Codes beinhaltet. Diese werden auf Richtigkeit überprüft. Eingegeben werden
dürfen nur dreistellige Zahlenkombinationen. Die Eingaben werden um überflüssige Leerzeichen erleichtert und am Separator getrennt. Anschließend wird über einen regulären Ausdruck
die Richtigkeit der einzelnen Codes geprüft. Falls zudem mehr als ein Sonderausstattungscode
eingegeben wird, werden diese aufsteigend sortiert, bevor das Array mit den einzelnen Codes
zurückgegeben wird.
Listing 3.10: falsche Eingaben prüfen
1
2
$data = trim ( $this - > $string ) ; // ueberfluessige Leerzeichen am
Anfang und Ende entfernen
$sa_array = explode ( " " , $data ) ; // Eingabestring an
Leerzeichen trennen
3
4
5
6
7
8
9
for ( $i =0; $i < count ( $sa_array ) ; $i ++) {
if (! preg_match ( " /^\ d {3} $ / " , $sa_array [ $i ]) && ( $sa_array [0]
!= " " ) ) { // Test auf 3 - stellige Zahlen oder ob Array leer
ist
return FALSE ; // falls fehlerhafte Zahl gefunden ->
Abbruch
break ;
}
}
10
11
12
13
14
if ( count ( $sa_array ) > 1) { // Falls mehr als ein SA - Code im
Array
sort ( $sa_array ) ;
// Array sortieren
}
return $sa_array ;
Die Methode generateSql generiert den benötigten SQL-Code für die Methode dbquery
und erwartet drei Argumente. Das Array aus der Methode codeCheck, die Spalten die ausgewählt werden und die Angabe, aus welcher Tabelle diese Spalten gelesen werden. Der
3. Implementierung
24
vorhandene Teil des SQL-Codes wird Schritt für Schritt komplettiert. Zuerst werden die übergebenen Spalten angehängt. Danach wird geprüft ob eine ausführliche Abfrage gewünscht
ist und bei Bedarf weitere Spalten angehängt. Diese Spalten sind bei jeder ausführlichen Info
gleich und müssen daher nicht übergeben werden. Als nächstes wird die auszuwählende Tabelle angefügt. Jetzt werden die Elemente aus dem Array eingefügt. Es kann vorkommen, dass
das übergebene Array leer ist, weshalb dies auch nochmals geprüft wird. In der anschließenden for-Schleife werden die Elemente der Reihe nach angehängt. Danach wird der SQL-Code
als String zurückgegeben.
Listing 3.11: SQL-Code generieren
1
2
3
4
5
6
$sql = " SELECT code " . $select ; // SQL beginnen und $select
anhaengen
$full = " , bild , minPreis , maxPreis , zusatzinfo " ; // string
fuer vollinfo bei allen Tabellen
// SQL Full oder Light - Unterscheidung
( $this - > vollinfo == " on " ) ? $sql .= $full : $sql .= " " ; // bei
Vollinfo string anhaengen sonst nichts ("")
$sql .= " FROM " . $from . " WHERE " ; // SQL from mit
Tabellenname $from und where Bedingung beginnen
$anzahl = count ( $array ) ; // Anzahl der Codes im Array zaehlen
7
8
9
10
11
if (! isset ( $array [0][0]) ) {
// echo (" Array ist leer ! < br / >") ; // debug
return false ;
}
12
13
14
15
16
17
18
19
20
/* Array durchlaufen , mit normaler for - Schleife da
Unterscheidung noetig , ob eines oder mehrere vorhanden */
for ( $i = 1; $i <= $anzahl ; $i ++) {
if ( $i > 1) {
// falls mehr als ein Element ( SA Code )
vorhanden
$sql .= " OR " ; // $sql um " _OR " erweitern
}
$sql .= " code = " . $array [ $i -1]; // Bedingung an $sql
anfuegen
}
return $sql ;
In der Methode generateTable wird der Ausgabecode generiert. Es handelt sich hierbei
um eine Tabelle, die aus verschiedenen Templatedateien10 erstellt wird. Die Methode erwartet
zwei Parameter. Zuerst einen Array mit den Ergebnissen aus der Datenbankabfrage und
danach einen Teil des Names des gewünschten Templates. Der komplette Dateiname wird
als erstes in der Methode generiert. Auch hier erfolgt wieder eine Unterscheidung zwischen
10
Templatedateien sind Dateien die immer wieder verwendet werden können und nach außen hin gleich
aussehen, sich jedoch im Inhalt unterscheiden. Deshalb stehen dort oft Platzhalter für die Inhalte, die
dann vor der Ausgabe ausgetauscht werden.
3. Implementierung
25
kurzer und ausführlicher Ausgabe der Ergebnisse, da hierfür das entsprechende Template
geladen werden muss. Nachdem das Template in eine Variable eingelesen wird, werden die
Inhalte für die kurze Ausgabe durch Suchen und Ersetzen der Platzhalter eingefügt. Es folgt
eine Abfrage nach ausführlicher Ausgabe. Falls diese zutrifft, werden auch die restlichen
Werte ersetzt. Am Ende wird die fehlende Ummantelung der Tabelle hinzugefügt und die
komplette Tabelle zurückgegeben.
Listing 3.12: HTML-Code für die Ausgabe generieren
1
2
3
4
$html = " " ; // Variable fuer den HTML Code
// Dateifile zum includen zusammenstricken ( Unterscheidung :
Vollinfo / Kurzinfo )
$filename = " inc / tpl . $tpl " ;
( $this - > vollinfo == " on " ) ? $filename .= " _full . php " :
$filename .= " . php " ;
5
6
$rowtemplate = file_get_contents ( $filename ) ; // Template in
Variable einlesen
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
foreach ( $array as $sa ) {
if ( $tpl == " sa_codes " ) { // SA - spezifische Inhalte einfuegen
$row = str_replace ( " % code % " , $sa [ ’ code ’] , $rowtemplate ) ;
$row = str_replace ( " % beschreibung % " ,
htmlentities ( $sa [ ’ beschreibung ’ ]) , $row ) ;
}
if ( $tpl == " lack " ) { // Lack - spezifische Inhalte einfuegen
$row = str_replace ( " % code % " , $sa [ ’ code ’] , $rowtemplate ) ;
$row = str_replace ( " % farbe % " , htmlentities ( $sa [ ’ farbe ’ ]) ,
$row ) ;
$row = str_replace ( " % lackart % " ,
htmlentities ( $sa [ ’ lackart ’ ]) , $row ) ;
}
if ( $tpl == " polster " ) { // Polster - spezifische Inhalte
einfuegen
$row = str_replace ( " % code % " , $sa [ ’ code ’] , $rowtemplate ) ;
$row = str_replace ( " % farbe % " , htmlentities ( $sa [ ’ farbe ’ ]) ,
$row ) ;
$row = str_replace ( " % polsterart % " ,
htmlentities ( $sa [ ’ polsterart ’ ]) , $row ) ;
}
if ( $this - > vollinfo == " on " ) { // falls Vollinfo gewuenscht
ist weitere Inhalte einfuegen
$imgsize = getimagesize ( " . $sa [ bild ] " ) ; // Bildgroesse
auslesen
$row = str_replace ( " % bildgroesse % " , $imgsize [3] , $row ) ;
// Bildgroesse einfuegen
$row = str_replace ( " % bild % " , $sa [ ’ bild ’] , $row ) ; //
3. Implementierung
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
Bildpfad einfuegen
$row = str_replace ( " % minpreis % " ,
number_format (( $sa [ ’ minPreis ’ ]/100) , 2 , ’ , ’ , ’. ’) ,
$row ) ; // Minimalpreis einfuegen
$row = str_replace ( " % maxpreis % " ,
number_format (( $sa [ ’ maxPreis ’ ]/100) , 2 , ’ , ’ , ’. ’) ,
$row ) ; // Maximalpreis einfuegen
if ( $sa [ ’ zusatzinfo ’] == " " ) { // Falls ZusatzinfoString
leer ist
$row = str_replace ( " % zusatzinfo % " , " -" , $row ) ; // " -"
einfuegen
} else {
$row = str_replace ( " % zusatzinfo % " ,
htmlentities ( $sa [ ’ zusatzinfo ’ ]) , $row ) ; // Zusatzinfo
einfuegen
}
}
$html .= $row ;
}
// fertige Tabelle generieren
$table = ’ < table width ="100%" border ="0" > ’;
$table .= $html . " </ table > " ;
return $table ;
3.3.4. Mailklasse
Die Klasse sendmail ist für das Kontaktformular geschrieben und hat mit der eigentlichen
Aufgabenstellung nichts zu tun. Der Vollständigkeit halber sei sie aber hier auch aufgeführt
und erläutert.
Mit der Erstellung eines neuen sendmail-Objekts werden die vom Benutzer eingegebenen
Daten in den Variablen des Objekts gespeichert und die Mail grundlegend vorbereitet. Dabei
wird aus dem Konstruktor die Methode toggleRecipient aufgerufen. Der Empfänger der
Mail wird aus einem Zahlenwert ermittelt. Der Zahlenwert kann wie im vorliegenden Fall aus
einer Auswahlliste abgesendet werden oder ganz normal, als z.B. ein Wert aus einem versteckten Eingabefeld. Hier wird wert auf Flexibilität gelegt. In der Funktion wird die Betreffzeile
der Mail über den Zahlenwert im Originalobjekt gesetzt. Danach wird die richtige Empfängeradresse anhand des Zahlenwerts zurückgesendet. Zurück in der Methode sendmail werden
zusätzliche Kopfzeilen der eMail generiert. Die Methode checkAdress überprüft die eigegebene eMail-Adresse auf Gültigkeit. Mittels eines regulären Ausdrucks wird geprüft, ob eine
eMail-Adresse zumindest syntaktisch korrekt eingegeben wurde. Ist die Adresse korrekt, so
kann die eMail anschliessend mit der Methode sendNow verschickt werden.
Listing 3.13: Die Methoden der Klasse: sendmail
1
2
function sendmail ( $from , $name , $subject , $message ) {
$this - > from = $from ; // Absenderemailadresse speichern
3. Implementierung
27
$this - > message = $message ; // Nachricht speichern
$this - > to = $this - > toggleRecipient ( $subject ) ; // Empfaenger
und Betreff einfuegen
// Extra H e ad e ri nf o rm ationen generieren
$this - > xtra
= " From : $this - > from ( $this - > name ) \ r \ n " ;
$this - > xtra
.= " Content - Type : text / plain \ r \ n " ;
$this - > xtra
.= " Content - Transfer - Encoding : 8 bit \ r \ n " ;
$this - > xtra
.= "X - Mailer : PHP " . phpversion () ;
3
4
5
6
7
8
9
10
}
11
12
13
14
15
16
17
18
19
20
21
function toggleRecipient ( $subjectnumber ) {
// Em pfa eng era dre sse n und Betreffzeilen definieren
$mailadressen = array ( ’ mario@skapunk . de ’ ,
’ mario@skapunk . de ’ , ’ mario@skapunk . de ’ ,
’ mario@skapunk . de ’) ;
$betreffzeilen = array ( ’ Allgemein Anfrage ’ ,
’ Hilfe zur Webseite benötigt ’ ,
’ V erbe sse rung svo rsch lag ’ ,
’ Fehlende Codes gefunden ’) ;
$this - > subject = $betreffzeilen [ $subjectnumber ]; //
Betreffzeile speichern
return $mailadressen [ $subjectnumber ]; // Empfaengeradresse
zurueckgeben
}
22
23
24
25
26
27
28
29
30
function checkAdress ( $mailadress ) {
// Em pfa eng era dre sse n und Betreffzeilen definieren
$checkemail = eregi ( " ^ " . // Beginn der Zeichenkette
" [a - z0 -9]+([ _ \. -][ a - z0 -9]+) * " . // user : ein oder mehr
Zeichen + Zahlen , Unterstrich Punkt oder Minus
zusaetzlich so oft wie sie vorkommen erlaubt ( auch kein
mal )
" @ " . // @ Zeichen
" ([ a - z0 -9]+([\. -][ a - z0 -9]+) *) + " . // Domain : faengt mit
Buchstaben oder Zahl an . Dann kann selbiges plus
zusaetzlich Punkt und Minus kommen .
" \.([ a - z ]{2}| aero | arpa | biz | com | coop | edu | gov |
info | int | mil | museum | name | nato | net | org | pro ) " . // sld ,
tld
" $ " , $_POST [ ’ email ’ ]) ; // $ == Ende der Zeichenkette
31
32
33
34
35
36
if (! $checkemail ) {
return FALSE ; // eMailadresse nicht korrekt
exit ;
}
return TRUE ; // eMailadresse korrekt
3. Implementierung
28
37
}
38
39
40
41
42
43
44
45
46
function sendNow () {
// fertige Mail verschicken
if (! mail ( $this - > to , $this - > subject , $this - > message ,
$this - > xtra ) ) {
return FALSE ;
exit ;
}
return TRUE ;
}
3.3.5. Sonstige Programmierung
In diesem Abschnitt wird näher auf die Programmlogik ausserhalb der Klassen eingegangen.
Es wird kurz erklärt, wie die Klassen benutzt werden, um die Anwendung lauffähig zu machen.
Allgemeine Logik zur Inkludierung von Dateien
Es werden verschiedene Dateien nur in bestimmten Fällen gebraucht. Die Datenbankklassen
beispielsweise werden nur auf den Seiten eingebunden, auf denen auch wirklich ein Datenbankzugriff erforderlich ist. Am Beispiel der Datei index.php (also die Datei, die als erstes
beim Aufrufen der Webseite angezeigt wird) lässt sich das deutlich zeigen. Im Contentbereich
findet sich eine switch-Anweisung, die den entsprechenden Fall abfragt. Es wird geprüft ob
die Variable action existiert und ob sie einen bestimmten Wert enthält. Trifft das zu, so
heisst das gleichzeitig, dass eine Anfrage über das Formular abgesendet wurde und es werden
die benötigten Klassen inkludiert. Danach wird noch die Datei inc.abfrage.php eingebunden, welche die Suchergebnisse im Contentbereich platziert. Wurde noch kein Formular
abgeschickt, z.B. wenn die Seite das erste Mal aufgerufen wird, so tritt der default-Fall
ein. Hier wird die Datei inc.form.php inkludiert welche im Contentbereich das Formular
einblendet.
Listing 3.14: allgemeine Logik zum Inkludieren von Dateien
1
2
3
4
5
6
7
8
9
10
11
< div id = " content " >
<? php
switch ( TRUE ) {
case ( isset ( $_POST [ ’ action ’ ]) && $_POST [ ’ action ’] ==
’ anfrage ’) ; // Abfrage gestartet
include ( " inc / inc . dbdata . php " ) ;
include ( " inc / class . data_handler . php " ) ;
include ( " inc / inc . abfrage . php " ) ;
break ;
default ; // Abfrageformular anzeigen
include ( " inc / inc . form . php " ) ;
}
3. Implementierung
29
12
13
?>
</ div >
Ausgabe der Suchergebnisse
Wie im oberen Abschnitt erwähnt, ist die Datei inc.abfrage.php für die Ausgabe der
Suchergebnisse zuständig. Diese Datei wird nach Absenden des Formulars aufgerufen und hat
somit die Eigaben des Benutzers in den Umgebungsvariablen zur Verfügung. Diese werden
nun der Reihe nach behandelt.
Da die Fehlerbehandlung der Übersicht wegen auch in dieser Datei abläuft (und zwar
bevor die Abfragen an die Datenbank gesendet werden), wird zu Beginn eine Fehlervariable
definiert und auf den Wert 0 (entspricht FALSE) gesetzt. Ebenso werden zwei Variablen mit
Textinhalten gefüllt, die ausgegeben werden, wenn gar kein Ergebnis oder nur ein Teilergebnis
gefunden wird. Bevor jetzt ein neues data_handler-Objekt angelegt wird, muss noch das
Feld zur ausführlichen Ausgabe überprüft werden. Wird es im Formular nicht angewählt, so
steht auch keine Information darüber in den Umgebungsvariablen. Wird es angewählt, so
steht der Feldname (vollinfo) als auch der Status (on) zur Verfügung.
Listing 3.15: Anlegen eines data_handler-Objekts
1
2
3
4
error = 0; // Fehlervariable auf FALSE setzen
// Templatedateien in String einlesen
$keinErgebnis =
file_get_contents ( " inc / tpl . kein_ergebnis . php " ) ;
$teilergebnis = file_g et_contents ( " inc / tpl . teilergebnis . php " ) ;
5
6
7
8
9
10
11
// leeres Feld ’ vollinfo ’ abfangen
if ( isset ( $_POST [ ’ vollinfo ’ ]) && $_POST [ ’ vollinfo ’ ]== " on " ) {
// pruefen auf Existenz der Variable und Inhalt
$vollinfo = $_POST [ ’ vollinfo ’ ];
} else {
$vollinfo = " off " ;
}
12
13
$anfrage = new data_handler ( $_POST [ ’ sacodes ’] ,
$_POST [ ’ lackcode ’] , $_POST [ ’ polstercode ’] , $vollinfo ) ; //
neues Objekt fuer SA - Codes
Jetzt werden die Eingaben durch die Methode codeCheck, welche im Abschnitt 3.3.3
erklärt wird, auf Fehler überprüft. Das Ergebnis dieser Überprüfung wird in eine Variable des
Objekts geschrieben, welche gleich danach auf Richtigkeit überprüft wird. Tritt ein Fehler
auf, wird direkt eine Nachricht ausgegeben und die Fehlervariable auf 1 (also TRUE) gesetzt.
Sind Sa-Code-, Lack- und Polstereingaben überprüft, wird die Fehlervariable abgefragt. Ist
diese im Verlauf der Verarbeitung auf 1 gesetzt worden, so wird das Skript abgebrochen.
Anmerkung: Leere Eingaben sind ausdrücklich erlaubt, da es sein kann, dass ein Benutzer
z.B. nur einen Lackcode abfragen möchte, wobei die restlichen Felder leer bleiben. Aus diesem
3. Implementierung
30
Grund wird am Anfang ein Hinweis für eine Teilausgabe vorbereitet, der durchaus gewollt
sein kann.
Listing 3.16: Fehlerüberprüfung der Eingaben
1
// Empfangene Daten auf fehlerhafte Eingaben ueberpruefen
2
3
4
$anfrage - > sa_codes = $anfrage - > codeCheck ( ’ sa_codes ’) ; //
SA - Codes checken
// echo (" Inhalt sacodes : $sacodes < br / >") ;
5
6
7
8
9
if (! $anfrage - > sa_codes ) { // im Fehlerfall Meldung ausgeben und
$error auf 1 setzen damit das Skript abgebrochen wird
echo ( " < h2 class =\ " error \ " > Achtung </ h2 > <p > < strong > SA - Codes
fehlerhaft . </ strong > Bitte & uuml ; berpr & uuml ; fen Sie Ihre
Eingaben ! </p > " ) ;
$error = 1;
}
10
11
[...]
12
13
14
15
16
if ( $error ) {
echo ( " < br / > < br / > < h2 > Hinweis </ h2 > <p > Bitte gehen Sie
zur & uuml ; ck und korrigieren Sie Ihre Eingaben ! </p > " ) ;
return false ;
}
Als nächstes wird der benötigte SQL-Code generiert und die Anfrage an die Datenbank
gesendet. Falls keine Eingaben gemacht wurden, so wird auch keine Anfrage gesendet. Das
Absenden einer leeren Anfrage wäre unnötig.
Listing 3.17: Absenden der Datenbankanfrage
1
2
3
4
5
6
/ $sql = $anfrage - > generateSql ( $anfrage - > sa_codes , ’ ,
beschreibung ’ , ’ s a _s onderausstattung ’) ;
if (! $sql == " " ) { // falls kein SQL Code generiert wurde weil
keine Eingabe erfolgte keinen Query absenden
$sa_codes = $dbconnection - > dbquery ( $sql ,
$dbconnection - > conn ) ;
}
// weitere folgen ...
[...]
Es fehlt nun noch die endgültige Ausgabe der Suchergebnisse. Erneut wird über eine
switch-Anweisung zwischen den einzelnen Fällen unterschieden. Erstens könnte kein Ergebnis gefunden werden, so sind die Variablen leer und es wird eine dementsprechende Fehlermeldung ausgegeben. Zweitens könnte nur ein Teilergebnis dargestellt werden. Hier wird
geprüft, in welchen Fällen ein Ergebnis vorliegt und diese werden dann über die Methode
generateTable der Klasse data_handler ausgegeben. Zudem wird der Hinweis auf das
3. Implementierung
31
Teilergebnis ausgegeben. Und der dritte Fall, falls für alle Eingaben ein Ergebnis gefunden
wird, werden diese der Reihe nach ausgegeben.
Listing 3.18: Ausgabe der Ergebnisse
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
switch ( TRUE ) {
case ( empty ( $sa_codes ) && empty ( $lack ) && empty ( $polster ) ) ;
// alle Variablen sind leer
print $keinErgebnis ;
break ;
case ( empty ( $sa_codes ) || empty ( $lack ) || empty ( $polster ) ) ;
// einige Variablen waren leer
// die Gefundenen werden ausgegeben
if (! empty ( $lack ) ) {
echo ( " < br / > < h2 > Lackierung </ h2 > < br / > " ) ;
print $anfrage - > generateTable ( $lack , ’ lack ’) ;
}
if (! empty ( $polster ) ) {
echo ( " < br / > < h2 > Polsterung </ h2 > < br / > " ) ;
print $anfrage - > generateTable ( $polster , ’ polster ’) ;
}
if (! empty ( $sa_codes ) ) {
echo ( " < br / > < h2 > Sonderausstattungen </ h2 > < br / > " ) ;
print $anfrage - > generateTable ( $sa_codes , ’ sa_codes ’) ;
}
print $teilergebnis ;
break ;
default ; // zu allen Variablen ein Ergebnis gefunden
echo ( " < br / > < h2 > Lackierung </ h2 > < br / > " ) ;
print $anfrage - > generateTable ( $lack , ’ lack ’) ;
echo ( " < br / > < h2 > Polsterung </ h2 > < br / > " ) ;
print $anfrage - > generateTable ( $polster , ’ polster ’) ;
echo ( " < br / > < h2 > Sonderausstattungen </ h2 > < br / > " ) ;
print $anfrage - > generateTable ( $sa_codes , ’ sa_codes ’) ;
}
Absenden des Kontaktformulars
Wie schon bei der Datei index.php wird hier über eine switch-Anweisung überprüft, ob
das Formular abgesendet wurde oder nicht. Ist dies nicht der Fall, wird das Formular inkludiert und angezeigt. Ist das Formular abgesendet worden, wird zuerst geprüft, ob alle
Felder des Formulars ausgefüllt sind oder nicht, bevor dann, falls dies zutrifft, die Klasse
class.sendmail.php inkludiert wird. Danach wird ein neues Objekt angelegt und mit den
Werten aus den Umgebungsvariablen gefüllt. Es muss noch geprüft werden, ob die eingegebene eMail-Adresse syntaktisch korrekt ist, was über die Methode checkAdress geschieht.
Wird eine falsche Adresse erkannt, bricht das Skript mit einer Fehlermeldung ab. Ist die Adresse korrekt, wird versucht die eMail zu verschicken, was bei Erfolg eine Bestätigung hervorruft.
3. Implementierung
32
Sollte es Probleme beim Mailversand geben, wird eine Fehlermeldung ausgegeben.
Listing 3.19: Mail über das Kontaktformular verschicken
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
switch ( TRUE ) {
case ( isset ( $_POST [ ’ action ’ ]) && $_POST [ ’ action ’] ==
’ kontakt ’) ; // Abfrage gestartet
// Fehlerbehandlung
if ( $_POST [ ’ email ’] == " " || $_POST [ ’ name ’] == " " ||
$_POST [ ’ nachricht ’] == " " ) {
echo ( " < h2 class =\ " error \ " > Achtung </ h2 > <p > < strong > Bitte
alle Felder ausf & uuml ; llen . </ strong > Es wurden nicht
in allen Feldern Angaben gemacht . Bitte
& uuml ; berpr & uuml ; fen Sie Ihre Eingaben ! </p > " ) ;
break ;
}
include ( " inc / class . sendmail . php " ) ; // sendmail Klasse
inkluden
// Mailobjekt wird angelegt
$mail = new sendmail ( $_POST [ ’ email ’] , $_POST [ ’ name ’] ,
$_POST [ ’ betreff ’] , $_POST [ ’ nachricht ’ ]) ;
if (! $mail - > checkAdress ( $mail - > from ) ) { // eMailadresse
ueberpruefen
?>
< h2 class = " error " > Achtung </ h2 >
<p > < strong > Falsche eMailadresse . </ strong > Es wurde eine
eMailadresse mit falschem Format angegeben . Bitte
& uuml ; berpr & uuml ; fen Sie Ihre Eingaben ! </p >
<? php
break ;
}
if ( $mail - > sendNow () ) { // Mail verschicken geglueckt
?>
<h2 > Nachricht abgeschickt </ h2 >
<p > Ihre Nachricht wurde soeben versendet . Ich versuche
sie m & ouml ; glichst bald zu beantworten . </p >
<p > Sollte wider erwarten keine Antwort erfolgen , so kann
es sein , dass die eMail beim Versand in den Weiten
des Internets verloren gegangen ist . Bitte schicken
Sie einfach eine erneute Anfrage . </p >
<? php
} else {
?>
< h2 class = " error " > Nachricht nicht abgeschickt </ h2 >
<p > < strong > Es ist ein Fehler aufgetreten . </ strong > Die
eMail konnte leider nicht verschickt werden . Bitte
versuchen Sie es sp & auml ; ter erneut . </p >
<? php
3. Implementierung
33
return false ;
}
break ;
default ; // Abfrageformular anzeigen
include ( " inc / inc . kontakt . php " ) ;
29
30
31
32
33
34
}
3. Implementierung
34
4. Ergebnis
Im letzten Kapitel wird kurz auf das fertige Produkt eingegangen, um dann in der Schlußbetrachtung die gesetzten und erfüllten Ziele zu betrachten.
4.1. Betatest
Kurz nach Vollendung der Programmierarbeit habe ich die Seite öffentlich im W126-Forum
vorgestellt1 , mit der Bitte an die User, die Seite zu testen und mir eventuelle Verbesserungsvorschläge mitzuteilen. Das Feedback war mehr als positiv. Fehler in der Programmierung
sind hierbei keine in Erscheinung getreten. Der Datenbestand war noch nicht ganz vollständig oder leicht fehlerhaft. Bei so einer Menge an Daten war das durchaus zu erwarten und
es konnten somit noch einige Fehler ausgemerzt werden und neue Sonderausstattungscodes
hinzugefügt werden.
Beispiele für Änderungen nach dem Betatest:
• Der Farbcode 618 (Mimosengelb) wurde um die Zusatzinformation „Ab 07/81 war
diese Lackierung nicht mehr bestellbar.“ ergänzt.
• Der SA-Code 260 (Typenkennzeichen auf Heckdeckel, Wegfall) wurde mit Beschreibung und Bild ergänzt.
• Der SA-Code 630 (ECE-Warndreieck) wurde hinzugefügt.
• Der SA-Code 823 (Zusatzteile Abgasreinigung für Schweiz-Ausführung bei KAT-Ausrüstung.)
wurde hinzugefügt.
• Der Lackcode 923 (Lapisblau) wurde um die Zusatzinformation „Lieferbar von 10/79
bis 05/84.“ ergänzt.
• Der SA-Code 823 (Zusatzteile Abgasreinigung für Schweiz-Ausführung bei KAT-Ausrüstung.)
wurde hinzugefügt.
• Der SA-Code 823 (Zusatzteile Abgasreinigung für Schweiz-Ausführung bei KAT-Ausrüstung.)
wurde hinzugefügt.
• Der SA-Code 823 (Zusatzteile Abgasreinigung für Schweiz-Ausführung bei KAT-Ausrüstung.)
wurde hinzugefügt.
1
Das genaue Thema findet sich unter folgendem Link: http://f11.parsimony.net/forum16936/messages/125726.htm
4. Ergebnis
35
4.2. Das fertige Produkt
Das fertige Produkt dieser Studienarbeit kann man in Abbildung 3.1 betrachten. In jedem der
getesteten Browser funktioniert die geschriebene Applikation ohne Einschränkungen. Leichte
Unterschiede im Design sind auf die verschiedenen Rendering-Engines2 der Browser zurückzuführen. Da auf XHTML-konformen Code geachtet wurde, müssten die Browserhersteller auf eine korrekte Implementierung wertlegen. Die Anwendung kann unter der Adresse
http://w126.xmariox.com/sa/ ausprobiert werden.
4.3. Schlußbetrachtung
Es wurden konkret folgende Ziele zu Beginn der Arbeit festgelegt:
• Die Seiten sollen valides XHTML 1.0 mit dem Dokumententyp Transitional sein.
• Ebenso sollen die CSS-Dateien mit dem Validator des W3C validieren.
• PHP Code soll weitestgehend objektorientiert geschrieben sein.
• Die Daten werden in einer MySQL Datenbank gespeichert.
Hinzu kamen während der Arbeit, teils aus Interesse, teils der Vollständigkeit halber, folgende Ziele:
• Ein Apache-Webserver soll als Entwicklungsserver dienen und durch Virtual Hosts erreichbar sein.
• Um die Webseite komplett zu machen, soll eine Kontaktmöglichkeit für Benutzer geschaffen werden. Hierbei fiel zusätzlicher Programmieraufwand für eine Mailfunktion
an.
Wie man aus der vorangegangenen Lektüre dieser Dokumentation entnehmen kann, sind
alle oben erwähnten Ziele erfüllt worden. Dabei waren besonders das Anlegen der richtigen
MySQL-Tabellen ein wichtiger Schritt und Lerneffekt. Ebenso die für mich völlig neue, objektorientierte Art zu programmieren war anfangs gar nicht so einfach zu meistern. Die Theorie
in die Praxis umzusetzen, hört sich manchmal leichter an, als es wirklich ist. Gerade hier habe ich einen enormen Schritt nach vorne gemacht und mein Wissen erweitert. Mir fiel dabei
besonders auf, dass sehr viel Aufwand im Abfangen von Fehlern, z.B. durch falsche Eingaben
eines Benutzers, steckt. Die eigentliche Logik entsteht für konforme Eingaben recht schnell,
doch alle Fehler abzufangen und dazu eine entsprechende Meldung auszugeben, macht einiges
an Mühe.
Mit der vorliegenden Endversion der Anwendung bin ich sehr zufrieden. Sie erfüllt alle
meine Kriterien und Erwartungen, die anfangs aufgestellt wurden. Der Betatest (siehe 4.1)
hat zudem gezeigt, dass die Anwendung recht einfach zu pflegen ist.
2
Jeder Browser besitzt eine Rendering-Engine, um die HTML- bzw. CSS-Textdateien formatiert am Bildschirm auszugeben.
4. Ergebnis
36
4.4. Ausblick
Die Anwendung wird auch in Zukunft produktiv eingesetzt, was gleichzeitig bedeutet, dass sie
auch weiterentwickelt werden soll. Das betrifft einerseits die Inhalte der Datenbank, die unter
Mithilfe von verschiedenen Forenmitgliedern durch neue oder verbesserte Sonderausstattungscodes und Fotos erweitert werden soll und andererseits die Programmlogik. Hier bietet es sich
speziell an, eine Adminoberfläche zu programmieren, über die man die Datenbank bequem
verwalten kann. So entfällt der Schritt über PHPmyAdmin.
4. Ergebnis
37
A. Anhang
A.1. Inhalte der CD-ROM
Die beiliegende CD-ROM ist in die folgenden Bereiche untergliedert:
• /datenbank_dump/: SQL-Dump der Datenbank.
• /design_daten/: Photoshop- und Illustratordateien mit Designentwürfen.
• /dokumentation/: Dokumentation und Zeitplan im PDF-Format
• /webroot/: Kopie des Wurzelverzeichnisses von http://w126.xmariox.com/sa/.
Hier sind alle PHP-Skripte und HTML-Dateien enthalten.
Eine Datei namens read_me.txt im Stammverzeichnis enthält zusätzliche Informationen.
A.2. Informationen zur benutzten Software
• HTML- und Texteditor: Macromedia Homesite
• Bildbearbeitungsprogramm: Adobe Photoshop
• Vektorbearbeitungsprogramm: Adobe Illustrator
• ER-Schemata: DIA
• Datenbank: PHPmyAdmin
• Dokumentation: LATEX (MiKTeX und TeXnicCenter)
A. Anhang
38
Literaturverzeichnis
[1] diverse Autoren. PHP FAQ der IRC-Channels #php und #php.de. http://www.php-q.
net/.
[2] diverse Autoren. PHP FAQ der Newsgroups de.comp.lang.php.*. http://www.php-faq.
de/.
[3] diverse Autoren. Wikipedia - Die freie Enzyklopädie. http://de.wikipedia.org/.
[4] Paul Dubois. MySQL - Entwicklung, Implementierung und Referenz. Markt & Technik,
2000.
[5] Marc Liyanage. Mysql Database Server. http://www.entropy.ch/software/macosx/
mysql/.
[6] The W3C Validator Team.
css-validator/.
W3C CSS Validator.
http://jigsaw.w3.org/
[7] The W3C Validator Team. W3C HTML Validator. http://validator.w3.org/.
Literaturverzeichnis
39
Herunterladen