In bestimmten Fällen macht es auch Sinn, kein action anzugeben, nämlich dann, wenn das Zielscript dasselbe wie das aktuelle ist. Zu beachten ist dabei, daß in diesem Fall alle GET-Parameter des Scriptaufrufs, der zum Anzeigen des Formulars führte, implizit wieder übergeben werden - wenn das Formular also mit GET arbeitet, hat man nach dem Absenden sowohl die ursprünglichen als auch die neuen GET-Parameter!
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.1 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 (global $var;).
Nun ein kleines Beispiel. Die Eingaben, die auf der Seite `eingabe.html` eingetragen wurden, werden durch Drücken von OK an die Datei `ausgabe.php` übermittelt. Durch diese werden sie dann ausgegeben.
Quelltext der Datei `eingabe.html`:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> <html> <head> <title>Eingabe</title> </head> <body> <div align="center"> <form action="ausgabe.php" 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.php`:
<!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", $_POST["feld1"], $_POST["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.
Diese Variante (Formular und Auswertung in einer Seite) hat sich in vielen Situationen als praktisch erwiesen und wird deshalb auch häufig empfohlen. Siehe auch Kapitel 9.4.
<a href="datei.php">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:
<a href="datei.php?var1=Wert1&var2=2">Linktext</a>
Allgemeiner formuliert: An das Verweisziel (in unserem Fall `datei.php`) 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", "Oedie", "Student/Schueler"); 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.php:
<?php include("./functions.inc"); ?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> <html> <head> <title>Persönliche Daten</title> </head> <body> <?php // lokale Variablen setzen $vars = array("sender", "geschl", "vorname", "name", "beruf", "hobby"); foreach ($vars as $var) $$var = $_POST[$var]; if ($sender) printf("Die Daten wurden von %s aus verschickt.", htmlentities($sender)); if (!isset($geschl)) $geschl = 'm'; ?> <form action="daten.php" method="post"> <input type="hidden" name="sender" value="daten.php"> 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 booleschen Wert TRUE.
Im folgenden Schema sei $submitted true, falls das (hier nicht angegebene) Formular abgeschickt wurde. Das könnte man z.B. durch Abfragen des Submit-Buttons erreichen, dessen Beschriftung bekanntlich gleich seinem Wert ist. Wie alle anderen Formularwerte findet sich auch der des Submit-Buttons im passenden superglobalen, assoziativen Array, genau gesagt an der Indexposition mit Namen des name-Attributs des Submit-Buttons.
Der gesamte Datenverarbeitungsblock kann natürlich auch über Funktions- oder Methodenaufrufe (bei OOP, siehe Kapitel 20) 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 ($submitted) { // 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 booleschen 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 16.
if ($_POST['stueckmenge']==0) { // Formular für Bestellung ausgeben } else { // Bestellung aufnehmen }
Da hier nicht mittels === auf Typgleichheit überprüft wurde, wird das Formular immer ausgegeben werden (d.h. die Abfrage ist in dieser Form nutzlos) - POST- und GET-Werte sind immer Strings...