Die Felder eines verschickten Formulares werden beim Laden der Empfängerseite (angegeben im action
des Formulars) automatisch in Variablen gleichen Namens verwandelt, auf die man im Verlauf
des Script-Hauptteils direkt zugreifen kann.
Will man auf
solche Variablen auch in Funktionen zugreifen, ohne sie global definieren zu müssen, kann
man ab PHP 4.2 die superglobalen Arrays $_GET und
$_POST, je nach Übergabeart, verwenden. In älteren PHP-Versionen heißen diese
Arrays $HTTP_GET_VARS bzw. $HTTP_POST_VARS und müssen außerhalb
des Script-Hauptteils explizit als global deklariert werden.
Nun ein kleines Beispiel. Die Eingaben, die auf der Seite eingabe.html eingetragen wurden, werden durch OK an die Datei ausgabe.php4 übermittelt. Durch diese werden sie dann ausgegeben.
Quelltext der Datei eingabe.html:
[language=HTML] <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> <html> <head> <title>Eingabe</title> </head> <body> <div align="center"> <form action="ausgabe.php4" method="post"> Feld1: <input name="feld1" size="60" maxlength="60"><br> Feld2: <input name="feld2" size="60" maxlength="60"><br> <input type="submit" value="OK"> <input type="reset" value="Abbrechen"> </form> </div> </body> </html>
Quelltext der Datei ausgabe.php4:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> <html> <head> <title>Ausgabe</title> </head><body> <?php printf("Feld 1:%s<br>Feld 2:%s", $feld1, $feld2); ?> </body> </html>
Natürlich kann die Seite zum Senden und die zum Auswerten auch genau dieselbe sein; in diesem Fall muß sie logischerweise eine PHP-Endung haben.
[language=HTML] <a href="datei.php4">Linktext</a>Wenn man jetzt der Datei die Werte Wert1 und 2 in den Variablen VAR1 und VAR2 übergeben will, sieht der Link folgendermaßen aus:
[language=HTML] <a href="datei.php4?var1=Wert1&var2=2">Linktext</a>
Allgemeiner formuliert: An das Verweisziel (in unserem Fall datei.php4) wird mit einem ? beginnend der Variablenname und mit einem Gleichheitszeichen der Wert angehängt; weitere Werte mit einem & statt ? . Es dürfen keine Leerzeichen dabei entstehen. Sonderzeichen in Werten, wie Umlaute, Leerzeichen, das Kaufmannsund- oder Fragezeichen, müssen nach einem bestimmten Schema kodiert werden, das URL-encoded genannt wird. PHP bietet mit den Funktionen urlencode und urldecode die Möglichkeit, Strings von und in dieses Format zu wandeln; beim Verschicken von Formularen wird quasi für jedes Feld urlencode aufgerufen und beim Bereitstellen der POST/GET-Daten in Dateien umgekehrt urldecode. Tabelle urlencoded listet die wichtigsten Sonderzeichen und ihre Kodierung auf.
|
Wenn man die übergebenen Werte verwendet, darf man nicht vergessen, daß
jeder die Werte beim Aufruf
verändern kann. Deshalb sollten die Variablen vor der Weiterverarbeitung auf korrekte Werte
hin überprüft werden.
Formulare zur Übermittlung von Daten (per POST oder GET) an sich sind schon ganz brauchbar, aber für wirklich interaktive, dynamische Formulare braucht es noch etwas mehr Verständnis von HTML, insbesondere den Formularelementen. Grundsätzlich hat jedes solcher Elemente einen Namen (name) und einen Wert (value). Der Name wird beim Verschicken des Formulars zum Namen der Variable bzw. des Indexes im Array, die den Wert des entsprechenden Formularelements annimmt. Im Wesentlichen sind folgende Elemente zu unterscheiden:
Das folgende Beispiel zeigt, wie die genannten Formularelemente eingesetzt werden
können und wie ihre Vorbelegung implementiert wird. Interessant ist dabei u.a.
die Verwendung zweier neuer PHP-Funktionen: is_array() prüft, ob eine
Variable ein Array ist,
und mit in_array() kann man feststellen, ob ein Wert (Parameter 1) in einem
Array (Parameter 2) enthalten ist.
Anstelle der statischen Arrays in den beiden Funktionen für die Ausgabe der Optionen können, in Verbindung mit einer Datenbank-Anbindung, natürlich auch Arrays, die aus einer SQL-Abfrage resultieren, verwendet werden. Solche Arrays erstellt man i.A. mittels einer while-Schleife.
functions.inc:
<?php /** * Beruf-Optionen ausgeben * * @param $beruf Bisheriger Wert */ function print_beruf_options($beruf=0) { $berufe= array("Angestellter", "Ödie", "Student/Schüler"); for ($i=0;$i<count($berufe);$i++) { printf("<option value=\"%d\"%s>%s</option>\n", ($i+1), ($beruf==($i+1) ? " selected" : ""), htmlentities($berufe[$i]) ); } } /** * Hobby-Optionen ausgeben * * @param $hobby Array bisheriger Werte */ function print_hobby_options($hobby) { if (!is_array($hobby)) $hobby = array(); $hobbies = array("Lesen", "Radfahren", "Schwimmen"); for ($i=0;$i<count($hobbies);$i++) { printf("<input type=\"checkbox\" name=\"hobby[]\" ". "value=\"%s\"%s> %s\n", htmlentities($hobbies[$i]), (in_array($hobbies[$i],$hobby) ? " checked" : ""), $hobbies[$i] ); } } ?>
daten.php4:
<?php include("./functions.inc"); ?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> <html> <head> <title>Persönliche Daten</title> </head> <body> <?php if ($sender) printf("Die Daten wurden von %s aus verschickt.", htmlentities($sender)); if (!isset($geschl)) $geschl = 'm'; ?> <form action="daten.php4" method="post"> <input type="hidden" name="sender" value="daten.php4"> Vorname: <input name="vorname" size="25" maxlength="60" value="<?php printf("%s", htmlentities($vorname)); ?>"><br> Name: <input name="name" size="25" maxlength="60" value="<?php printf("%s", htmlentities($name)); ?>"><br> Geschlecht: <input type="radio" name="geschl" value="m"<?php printf("%s", ($geschl=='m' ? " checked" : "")); ?>> männlich <input type="radio" name="geschl" value="w"<?php printf("%s", ($geschl=='w' ? " checked" : "")); ?>> weiblich<br> Beruf: <select name="beruf"> <option value="0"<?php echo (!isset($beruf) ? " selected" : ""); ?>>--- Bitte wählen ---</option> <?php print_beruf_options($beruf); ?> </select><br> Hobbies: <?php print_hobby_options($hobby); ?><br> <input type="submit" value="Weiter"> <input type="reset" value="Zurücksetzen"> </form> </body> </html>
Der Effekt dieser ganzen Abfragen und Zusatzangaben ist letztlich nicht nur, daß die Daten verschickt werden, sondern daß auch das Formular nach dem Verschicken wieder genau so aussieht, wie zuvor. In diesem Beispiel werden die verschickten Daten, bis auf das Ausfüllen des Formulars, nicht weiterverarbeitet. Anbieten würde sich für persönliche Daten z.B. das Anlegen oder Aktualisieren von Datensätzen einer entsprechenden Datenbank. Da im obigen Beispiel die Hobbies über Checkboxen realisiert wurden, die eine Auswahl ermöglichen, die aus mehreren Werten besteht, müßte dieses Feld datenbanktechnisch wohl relational definiert werden, also über eine Zusatztabelle, die die Beziehung zwischen persönlichen Daten und einer Hobbytabelle herstellt:
|
Es bietet sich also an, die gesamte Datenverarbeitung an den Beginn eines
PHP-Scriptes zu stellen und darauf zu achten, daß kein einziges anderes
Zeichen vor der ersten PHP-Marke (am Dateianfang) steht. Eine Weiterleitung
über HTTP-Header macht v.a. dann Sinn, wenn das Formular nach erfolgtem
Eintragen und Verschicken von korrekten Daten nicht mehr gebraucht
wird. In diesem Fall hat dies auch den Vorteil, daß
ein Reload der Seite keinen Effekt hat. Auch sonst sollte
man aber immer überprüfen, ob eine doppelte Eintragung durch falsche
bzw. mißbräuchliche Browserbenutzung möglich ist und entsprechende
Vorkehrungen bei der Konstruktion der Datenverarbeitung treffen (z.B.
nach gleichen Einträgen suchen, bevor ein INSERT versucht wird).
Die Erkennung, ob Daten verschickt wurden oder nicht, macht man i.A. davon abhängig, ob die Variable, die den gleichen Namen hat wie der Submit-Button des Formulars, das die Daten verschickt, gesetzt ist oder nicht. Zur Erinnerung: Ein solcher Submit-Button trägt dann, wenn er einen Namen hat, den Wert, der als value-Attribut angegeben wurde -- welcher in diesem Fall gleichbedeutend ist mit Button-Titel. In PHP spielt es dabei meist eine untergeordnete Rolle, ob man für die Überprüfung die Funktion isset(var) benutzt, die auf Existenz einer Variable testet, oder einfach direkt die Variable abfragt, denn in PHP ist jeder String außer dem leeren und 0 gleich dem bool'schen Wert TRUE.
Im folgenden Schema sei der Name des Submit-Buttons submit. Der
gesamte Datenverabeitungsblock kann natürlich auch über Funktions- oder
Methodenaufrufe (bei OOP, siehe Kapitel 19) erledigt
werden, dann ist jedoch unbedingt darauf zu achten, eine saubere
Parameterübergabe zu verwenden; hierbei bieten sich besonders assoziative
Arrays an.
<?php // ggf. Funktions-Include if ($submit) { // Daten prüfen, ggf. Fehlermeldungen erzeugen if (<Daten OK>) { // eigentliche Verarbeitung: // - neuen Datensatz anlegen // - bestehenden Datensatz aktualisieren // - bestehenden Datensatz löschen // und ggf. weiterleiten } else { // Fehlermeldung erzeugen // (in Variable schreiben) } } elseif ($fillform) { // alte Daten lesen und in Variablen speichern } // Frühestmögliche Ausgabe: ggf. HTML-Header-Include; // Fehler ausgeben ?> Hier das Formular (mit Werten) anzeigen <?php // ggf. HTML-Footer-Include ?>
Mit den Includes sind mögliche Einbindungen von Funktions- und
Klassendefinitionsdateien gemeint bzw. HTML-Ausgaben, die weitgehend
unabhängig von der Datenverarbeitung sind (HTML-Header und -Footer).
Falls Daten geändert werden sollen (im Beispiel angedeutet durch Abfragen
der bool'schen Variable $fillform), muß natürlich das Formular
ausgefüllt werden, d.h. entsprechende DB-Abfragen müssen gestartet und
ausgewertet werden, so daß danach die Variablen, die die Formularfelder
vorbelegen, sinnvolle Werte haben.
Ein schönes Beispiel für die Anwendung des hier gelesenen findet sich übrigens in Kapitel 15.