PHP-Workshop Teil 2: Warenkorb-Lösung per PHP-Middleware

Der 2. Teil des Workshops zeigt, wie der Warenkorb eines E-Shops mit PHP und mySQL programmiert wird.

Artikel erschienen in Swiss IT Magazine 2001/15

     

Während der erste Teil des PHP-Workshops die Installation von PHP und der mySQL-Datenbank sowie einfache Datenbankabfragen erläutert hat, werden im vorliegenden zweiten Teil weitere Funktionen der Middleware anhand einer Warenkorb-Applikation erklärt.



Grundlage ist hierfür wieder ein gewöhnliches HTML-Formular, in das die einzelnen Artikeldaten eingetragen werden können. Das Formular ruft sich selbst wieder auf, nachdem die Daten eingegeben oder geändert wurden und eine der beiden Schaltflächen angeklickt wurde.




Unterhalb der Eingabefelder wird die Artikelliste mit den aktuellen Produkten angezeigt, in der man nun durch Anklicken der Links "Edit" oder "Delete" den entsprechenden Artikel ändern oder löschen kann.



Innerhalb der einzelnen Eingabefelder wird der Wert des Feldes durch "value" vorgegeben. Um nach dem Versenden des Formulars wieder die gleichen Werte vorzufinden, muss hier der Inhalt der entsprechenden PHP-Variablen vorgegeben werden. Daher enthalten die Input-Felder alle eine entsprechende Angabe wie im folgenden Code am Beispiel des Feldes "fld_name".



Nach dem Abschicken des Formulars werden die Inhalte der Formularfelder in die gleichnamigen PHP-Variablen übertragen, so dass diese im aufgerufenen HTML-Code zur Verfügung stehen. Durch das Anzeigen über den echo-Befehl wird dieser Wert wieder als Voreinstellung für das Feld verwendet.



Im vorliegenden Beispiel wird in der action-Anweisung des Formulars die gleiche Datei verwendet, womit sich das Formular selbst aufruft.



Wenn der Code später auf einem Webserver eingesetzt wird, kann alternativ auch die Systemvariable $PHP_SELF verwendet werden. Leider funktioniert diese nicht korrekt in Verbindung mit Windows und dem Xitami Webserver, so dass hier jeweils der Dateiname direkt eingetragen wird. Wenn Sie jedoch mit dem Apache-Server auf Linux arbeiten, können Sie für die Formularaktion folgendes eintragen:



Aus Platzgründen soll auf die Artikelverwaltung selbst nicht näher eingegangen werden. Der kommentierte PHP-Code kann jedoch auf den Internetseiten für diesen Artikel heruntergeladen und für das Beispiel verwendet werden.


Beispiel Warenkorb

Um Artikel in einen Warenkorb zu transportieren, werden in der Praxis unterschiedliche Methoden verwendet. Am häufigsten findet man die Realisierung über Cookies. Dabei werden die Artikeldaten wie Artikelnummer und Anzahl in einem Cookie auf dem Rechner des Kunden gespeichert. Dieses Verfahren hat allerdings einige Nachteile. Zunächst gibt es in Europa eine gewisse Abneigung gegen Cookies, da insbesondere in Deutschland das Gerücht umgeht, man könne mit Cookies die Daten des Anwenders ausspionieren. Auch wenn dies so nicht richtig ist, gibt es viele Anwender, die die Cookie-Funktion des Browsers abgeschaltet haben. Ausserdem werden Cookies immer auf dem Rechner abgelegt, auf dem die Bestellung auch eingegeben wurde. Wechselt der Benutzer den Rechner während seiner Einkaufstour, so muss er gegebenenfalls seine Daten noch mal eingeben.



Da wir hier mit einer Datenbank arbeiten, liegt es nahe, diese auch als Warenkorb zu nutzen. Dazu muss der Browser des Kunden keine Cookies unterstützen, die eingegebenen Daten werden anhand seiner Benutzer-ID in der Datenbank wieder gefunden. Um das realisieren zu können, muss sich der Kunde natürlich zunächst bei unserem Shop anmelden.





Die Benutzeranmeldung

Die Anmeldung eines Benutzers hat für einen Online-Shop mehrere Vorteile: Zunächst können alle Bestellungen direkt den Daten des registrierten Benutzers zugeordnet werden. Der Anwender muss nicht noch mal seine Bestelladresse eingeben, wenn die Bestellung fertig ist. Weiterhin kann der Shopbetreiber eindeutig feststellen, wie viele unterschiedliche Kunden auf seinen Seiten eingekauft haben oder zur Zeit gerade beim Einkaufen sind.



Leider ist das Internetprotokoll ein sogenanntes "zustandsloses" Protokoll. Das bedeutet, dass nach dem Abruf einer Seite alle Informationen über den Abrufer dieser Seite verlorengehen. Wird eine weitere Seite vom Server abgerufen, so kann nicht festgestellt werden, ob die Seite von der gleichen Person oder von jemand anders angefordert wurde. Das macht es recht schwierig, einen Kunden zwischen zwei Seitenabrufen wieder zu erkennen.




Eine mögliche Lösung wäre, die Benutzerkennung zusammen mit dem Passwort bei jedem Seitenabruf erneut in der URL mitzugeben und jedes Mal in der Datenbank zu überprüfen.



Obwohl dieses Verfahren manchmal praktisch angewandt wird, sollte es aus Sicherheitsgründen vermieden werden, denn die Daten in der URL werden jedes Mal unverschlüsselt über das Internet übertragen, so dass ein so übergebenes Passwort leicht ausgelesen werden kann. Erscheint das Passwort ausserdem noch in der URL-Zeile des Browsers, so wird hier ein zusätzliches Sicherheitsloch aufgerissen.



Im Idealfall sollte die Anmeldung immer über einen SSL-Server erfolgen, so dass die Übertragung verschlüsselt erfolgt. Das Anmeldeformular sollte immer mit der Methode "post" abgeschickt werden, damit das übergebene Passwort nicht in der URL-Zeile sichtbar wird. Werden auch die nachfolgenden Seiten über den SSL-Server bedient, so kann das Passwort auch in diesen Abrufen per "post" mitgeschickt werden.



In der Praxis wird es jedoch vermieden, das Passwort allzu oft zu übertragen. Nach der ersten Identifizierung des Kunden wird daher eine Session-ID erzeugt, die für nachfolgende Abrufe dann auch offen verwendet werden kann.



Diese Session-ID sollte nicht leicht zu erraten sein, was beispielsweise eine fortlaufende Nummer schon ausschliesst. Statt dessen wird gern ein md5-hash verwendet, der aus einem beliebigen String einen 32 Stellen langen Zufallsstring erzeugt.



Als Eingabe besteht beispielsweise die Möglichkeit, die aktuelle Systemzeit zu verwenden. Damit kann der Kunde durch seine Benutzer-ID und diese Session-ID eindeutig identifiziert werden. Die Session-ID wird bei der nächsten Anmeldung wieder neu vergeben und sollte beim Abmelden wieder entfernt werden.



Die weiteren Shopseiten sind so programmiert, dass der Anwender bei falscher Identifizierung keine Fehlermeldung erhält, sondern sofort zum Login weitergeleitet wird. Damit kann der Kunde auch einen Bookmark auf die eigentliche Shopseite setzen. Enthält der Bookmark eine Session-ID, die nach dem Ausloggen ungültig geworden ist, erscheint dann automatisch die Anmeldeseite.



Um die Anwendung zu testen, verwenden Sie einen der Test-User, die mit dem Skript install_user.php angelegt werden. Die Benutzer sind hier "admin" oder "test", jeweils mit der Kennung "password".




Das Bestellformular

Die Bestellung erfolgt nach dem Einloggen und der Verifizierung der Benutzerdaten durch Anklicken des "Bestellen"-Links in einer Artikelliste.



Der gesamte Bestellvorgang spielt sich in einem einzigen Formular mit dem Namen shop.php ab, das sich immer wieder selbst mit unterschiedlichen Parametern aufruft. Als zu transferierende Parameter müssen jedes Mal die Benutzer-ID und die Session übergeben werden, um den Kunden jedes Mal neu zu identifizieren. Bei jedem Seitenabruf werden diese Daten daher erneut mit dem Eintrag in der Datenbank verglichen.




Zusätzlich wird für jeden Kunden die Tabelle "Warenkorb" verwendet, um die ausgewählten Artikel einzutragen. Nach dem Klick auf "Bestellen" werden im Formular die Einzelheiten des gewählten Artikels noch mal angezeigt und der Kunde kann die gewünschte Anzahl eintragen.



Nach Bestätigung über die Schaltfläche "Bestellen" werden diese Daten dann dem Warenkorb hinzugefügt. Um das Beispiel einfach zu halten, wurde auf eine Prüfung von mehrfachen Einträgen verzichtet.



Nach jedem Bestellvorgang bekommt der Kunde den Inhalt seines Warenkorbes und die verfügbaren Artikel angezeigt. Soll eine Position aus dem Warenkorb entfernt werden, so genügt ein Klick auf den entsprechenden Link "Entfernen".



Eine Besonderheit ist zu erwähnen, die mit dem Cache des Browsers zusammenhängt: Wird nämlich ein Eintrag im Warenkorb geändert, so erscheinen die aktuellen Daten nicht immer korrekt beim erneuten Abrufen der Seite. Das hängt damit zusammen, dass der Webbrowser versucht, bereits geladene Seiten aus seinem Festplatten-Cache zu holen, anstatt sie noch einmal über das Internet abzurufen. Damit ist es praktisch unmöglich, einen neuen Datenbestand im Browser anzuzeigen, solange man die gleiche URL aufruft.



Zwar gibt es einen Meta-Tag, der das Caching verhindern soll, leider kommt es immer wieder vor, dass einige Browser diesen nicht korrekt beachten.



Daher wird in der Praxis ein einfacher, aber wirkungsvoller Trick angewendet, der sich bei allen dynamischen Seiten wie der Anzeige von Aktienkursen oder eben Warenkorbdaten bewährt hat: Man ändert einfach bei jedem Abruf die URL, so dass der Browser den Abruf als neue Seite interpretiert. Um dies zu erreichen, wird eine Variable zur URL mit angegeben, die jedoch tatsächlich nicht benötigt wird. In unserem Beispiel heisst sie "time" und wird mit der aktuellen Systemzeit vorbelegt. Da diese sich mit jeder Sekunde anders präsentiert, ändert sich dieser Teil der URL mit jedem Abruf.




Abschluss an der Kasse

Ist die Bestellung vollständig, begibt sich der Kunde zur "Kasse", um zu bezahlen. In unserem Beispiel wird dabei lediglich die Gesamtbestellung nochmals angezeigt und der Warenkorb geleert. Der Kunde hat nun die Möglichkeit, weiter einzukaufen und mit seinen aktuellen Login-Daten wieder zum Shop zu wechseln, oder sich endgültig auszuloggen. Beim Ausloggen wird dann die aktuelle Session-ID wieder aus der Tabelle entfernt.



Der Artikel zeigt, wie einfach sich ein Warenkorb als Grundlage für einen eigenen PHP-Shop implementieren lässt. Leider bietet der vorliegende Workshop nur begrenzt Raum für die komplette Darstellung des PHP-Codes, so dass in den Textkästen nur die wichtigsten Module näher erläutert werden können.




Der komplette Quellcode für die Warenkorb-Anwendung liegt auf der InfoWeek-Site vor und ist so dokumentiert, dass die Besonderheiten innerhalb des Codes nochmal hervorgehoben wurden. Das vorliegende Projekt kann auch gut als Grundlage für weitere Entwicklungen verwendet werden.



Artikel kommentieren
Kommentare werden vor der Freischaltung durch die Redaktion geprüft.

Anti-Spam-Frage: Vor wem mussten die sieben Geisslein aufpassen?
GOLD SPONSOREN
SPONSOREN & PARTNER