======Formulare Verarbeiten====== =====Formular und Parameterübergabe===== Interaktivität und Dynamik sind für einen gelungenen Web-Auftritt maßgebend. Dabei spielen Formulare eine wichtige Rolle. Denn durch sie kann der Besucher aktiv werden. Er kann Daten an den Server schicken, die dann verarbeitet werden. Formulare haben in erster Linie wenig mit PHP gemein, da sie durch HTML erzeugt werden. PHP kommt erst dann zum Einsatz, wenn die Formulardaten verarbeitet werden. Die Daten werden dabei durch das HTTP-Protokoll entweder per ''POST'' oder ''GET'' versendet. Auch in [[php:cookies|Cookies]] können Daten gespeichert werden. =====Erstellen eines Formulars===== Ein Formular wird durch die beiden Auszeichnungen ''
'' und ''
'' eingeschlossen. Die dazwischen liegenden Elemente des Formulars werden beim Versenden abgearbeitet. Andere HTML-Auszeichnungen, etwa Tabellen, werden zwar dargestellt, aber bei der Versendung nicht beachtet. Die Methode und das Ziel der Übergabe werden innerhalb des ''form''-Tags angegeben. * ''method'' legt die Methode der Übergabe fest: * ''POST'' * ''GET'' * ''action'' gibt das Ziel an Das Ziel kann eine beliebige Web-Adresse oder auch eine Mail-Adresse sein. Bei der Verarbeitung des Formulars werden alle Elementnamen automatisch in Variablen und alle Elementwerte in die Werte der jeweiligen Variable geschrieben. Test-Formular
Als Methode wurde hier ''GET'' gewählt. Der Inhalt des Formulars wird an die Datei form.php versendet. Durch ''input'' wird ein Formularelement erzeugt. Auf welche Elementtypen Du zurückgreifen kannst, wiird in der Folgenden Tabelle gezeigt: ^Typ^Attribute^Beschreibung^ |button|name, value|Schaltfläche (Ein Button).| |checkbox|name, value, checked| Kontrollkästchen.| |file|size, maxlength, accept| Eingabefeld für Dateien und Schaltfläche zum Durchsuchen.| |hidden|name, value|Unsichtbares Feld, nützlich für Informationen die Automatisch mitgegeben werden sollen.| |image|name, src, Bildattribute| Bild als Submit-Button.| |radio|name, value, checked| Optionsschalter| |reset|name, value|Setzt Formulareingaben zurück.| |submit|name, value|Senden-Button.| |text|name, value, size, maxlength|Einzeiliges Eingabefeld.| |password|name, value size, maxlength|Einzeiliges Eingabefeld,das die Eingabe als Sternchen(*) ausgibt.| Zwei Elementtypen werden nicht durch input angegeben. Mehrzeilige Textfelder und Optionsmenüs sind durch reine HTML-Auszeichnungen Begrenzt: *
Der Browser zeigt jetzt das Formular an, in das bereits ein Text eingegeben wurde. {{:php:auswahl_018.png |}} Alle eingaben werden an die Datei new_entry.php übergeben. Genauso gut kann der Inhalt des Formulars auch an dieselbe Datei geschickt werden. Die Datei kann direkt angegeben werden, oder Du verwendest die globale Server-Variable PHP_SELF. Die ''form''-Auszeichnung muss in diesem Fall dann so abgewandelt werden:
Anstatt ''$_SERVER['PHP_SELF']'' steht nach der Verarbeitung der Datei dann ihr Dateiname im Attribut ACTION. Konzentrieren wir uns nun wieder auf unser ursprüngliches Beispiel. Die Date new_entry.php wurde angelegt un wird zum Test wie folgt beschrieben(Datei new_entry.php): @@@ Email: $mail
URL: $url
Dein Text: $text"; } else{ echo "Bitte fülle das Formular ganz aus!"; } ?>
Dieses kleine Skript zeigt, dass die zuvor eingegebenen Daten übernommen wurden und schon angezeigt werden können. {{ :php:auswahl_019.png|}} Du kannst diesen Datensatz schon jetzt speichern. Das hat aus Sicherheitsgründen und wegen der fehlenden Formatierung der Zeichenketten aber keinen Sinn. Außerdem sorgen fehlende Fehlerkorrekturen für unvollständige und oder falsche Einträge. =====Globale Servervariablen===== Im vorigen Beispiel hast Du bereits mit PHP auf die Formularwerte zugegriffen, die per POST vom Formular übergeben wurden. Du erhälst das Formularelement ''url'' durch die Anweisung $url = $_POST['url']; PHP speichert alle Elemente eines Formulars mit der POST-Methode in einem assoziativen Array mit dem Namen $_POST[], analog dazu $_GET[], wenn Du die Methode GET verwendest. Hier eine Liste der globalen Assoziativen Variablen, welche durch Formulare erzeugt werden können: ^Name^Bedeutung^ |$_POST[]|Formulardaten die mit POST versendet wurden.| |$_GET[]|Formulardaten welche mit GET gesendet worden sind.| |$_COOKIE| Gespeicherte Cookies *| |$_SERVER[]|Verschiedene Servervariablen *| |$_ENV|Variablen der Serverumgebung *| |$_FILES|Für Datei-Upload.| |$_SESSION[]|Sitzungsvariablen*| |$_REQUEST[]|Enthält die Inhalte von $_GET, $_POST und $_COOKIE| * Bedeutet dass diese Variablen nicht durch Formulare erzeugt werden, aber dennoch der vollständigkeit-halber hier aufgeführt werden. Da es sich bei den jeweiligen Daten um assoziative Arrays handelt, stehen Dir auch Arrayfunkionen zur Verfügung, um diese Arrays beispielsweise auszulesen. Du kannst diese Arrays aber nicht ändern. Damit bist Du in der Lage, dynamisch erzeugte Formulare auszulesen oder sich viel Schreibarbeit zu ersparen, wenn die Formulare sehr kompliziert sind. Die Eingabe für unser Gästebuch lässt sich auch in dieser Form ausgeben. $element) { echo strtoupper($name). ": $element
"; } } ?>
Zuerst wird geprüft, ob Daten durch POST übergeben wurden. Mit foreach werden die Datensätze ausgelesen und jeweils ausgegeben. Das Ergebnis ist hier zu begutachten: {{ :php:auswahl_020.png|}} ====Fehlerbehandlung und Formatierung==== Du bist mit den PHP-Grundlagen fähig, Kontrollstrukturen zu programmieren. Leicht ist es auf jeden Fall, fehlende Werte zu erkennen und gegebenenfalls eine Fehlermeldung im Browser auszugeben. Auch durch JavaScript kann eine solche Fehlerroutine hinzugefügt werden. Die Behandlung durch PHP ist jedoch auf jeden Fall effektiver, da JavaScript durch den Besucher deaktiviert sein könnte. Das Beispiel zeigt, wie eine Fehlerbehandlung mittels PHP aussehen könnte: Email: $mail
URL: $url
Dein Text: $text"; } else { echo "Name und der Text müssen angegeben werden!"; } } else { echo "Bitte verwende das Formular."; } ?>
Das Skript enthält eine simple Kontrollfunktion, in der überprüft wird, ob die Werte in $name und $text vorhanden sind. Außerdem wird jeder Datensatz formatiert. Als Erstes werden mit ''rtrim'' überflüssige Zeichen entfernt. Außerdem werden mit ''htmlentities'' HTML-spezifische Auszeichnungen und Umlaute umgewandelt. Sonderzeichen werden mit ''addshlashes'' ebenfalls behandelt, falls die Daten in einer Datenbank gespeichert werden soll. ====Formularoptionen und Arrays==== Du willst mehr über die Besucher erfahren? Eine weit verbreitete Lösung sind Checkboxen oder Optionsmenüs mit mehreren Auswahlmöglichkeiten. Da Du mehrere Werte auswählen kannst, kommt es bei der bisherigen Verarbeitung durch PHP zu Problemen. Diese äußern sich in unserem Beispiel darin, dass nur der letzte ausgewählte Wert gespeichert wird, denn es existieren mehrere Werte, aber nur eine Variable. Die Lösung kennst Du bereits aus dem Kapitel über [[php:arrays|Arrays]]. Nur Arrays sind dazu fähig mehrere Werte aufzunehmen. Bei der Formularübergabe muss also dieser Datentyp anstelle eines einzelnen Wertes benutzt werden. PHP muss also erkennen, dass es Daten bekommt, die in einem Array zu speichern sind. Erreicht wird das, indem dem ELementnamen eckige Klammern [] angefügt werden.
Als Ziel muss eine PHP-Datei angegeben werden; die hochgeladene Datei wird nämlich in einem temporären Ordner des Servers abgelegt und sofort gelöscht, wenn der Upload abgeschlossen ist. Das Skript, welches als Ziel angegeben wird, dient Dir zur Verarbeitung der Daten. Zumindest muss die Datei durch das Skript über den Dateizugriff an seinen wahren Bestimmungsort auf dem Server kopiert werden. Das Zielskript ''upload.php'' sollte jedoch noch etwas mehr können. So soll es prüfen, ob die Datei bereits vorliegt, und diese auf Wunsch umbenennen. Doch zunächst solltest Du erfahren, wie Du Informationen über die Datei erhälst. Nach dem Sendevorgang steht dem aufgerufenen Skript automatisch das assoziative Array ''$_FILES[]'' zur Verfügung. Dieses assoziative Array enthält selbst wieder assoziative Arrays, von denen jedes die Informationen über eine gesendete Datei enthält. Den Zugriff auf das erste assoziative Array erhälst Du, indem Du den Namen des Datei-Upload-Elements im Formular einsetzt (Hier ''file'') * $_FILES["file"]["tmp_name"] enthält den Dateinamen der im temporären Ordner liegenden Datei. * $_FILES["file"]["name"] enthält den Originalen Namen der Datei. * $_FILES["file"]["size"] enthält die Dateigröße. * $_FILES["file"]["type"] enthält den Media-Typ der Datei (die unterstützten Typen erfährst Du von deinem Provider oder findest sie in der Konfiguration des Servers. * $_FILES["file"]["error"] kann verwendet werden, um auf Fehler nach dem Upload zu testen. Folgende Werte sind möglich: * UPLOAD_ERR_OK(0) kein Fehler. * UPLOAD_ERR_INI_SIZE(1): Datei ist größer als der Wert, der in der Datei php.ini unter upload_max_filesize angegeben wurde. * UPLOAD_ERR_FORM_SIZE(2): Datei ist größer als im Form-Tag des Formulars angegeben. * UPLOAD_ERR_PARTIAL(3): Datei wurde nicht vollständig Hochgeladen. * UPLOAD_ERR_NO_FILE(4): Es wurde keine Datei hochgeladen. ====Begrenzung der Dateigröße==== Zwar ist die Begrenzung im Zielskript sinnvoller, aber dennoch gibt Dir auch das Formular die Möglichkeitm die Dateigröße zu begrenzen. Dazu wird ein unsichtbares Formularelement erstellt. Der Elementname wird mit MAX_FILE_SIZE angegeben. Der zugewiesene Wert einer Ganzzahl entspricht der zulässigen Dateigröße in Byte. Wir der zulässige Wert überschritten, gibt der Browser zwar eine Fehlermeldung aus, die Datei wird aber dennoch hochgeladen. Bei dieser Variante besteht die Chance des Missbrauchs, denn das Formular kann auf der Seite des Clients selbst geschrieben werden. Eine wirkungsvollere Methode stellt die Einschränkung über Servereinstellungen selbst dar. In der php.ini existiert ein Eintrag namens upload_max_filesize, dessen Wert in Byte Du beliebig verändern kannst. Ist eine Größe angegeben kann sie auf dem Server nicht überschritten werden und ist damit global festgelegt. Bitte beachte, dass einige Provider diese Einstellung aus Sicherheitsgründen mit einem Wert belegt haben (Standardmäßig sind es 2 Mbyte und meist auch so belassen). ====Mehrere Dateien hochladen==== Unter [[php:forms#formularoptionen_und_arrays|Formularoptionen und Arrays]] wurde beschrieben. wie Du mehrere Werte über Formularelemente mit gleichem Elementnamen verschicken kannst. Das gleiche Prinzip wird auch beim Upload angewendet. Dabei erzeugt PHP wieder ein Arry.


Das Zielskript sollte jetzt natürlich auch auf Arrays zugreifen ====Die Zieldatei==== Die Zieldatei, welche im Form-Tag angegeben wurde, soll im Wesentlichen folgende Funktion besitzen: * Prüfen, ob es sich wirklich um eine hochgeladene Datei handelt * Prüfen der Dateigröße * Prüfen, ob Zieldatei schon vorliegt, * Kopieren der hochgeladenen Datei aus dem temporären Verzeichnis in das Zielverzeichnis. * Fehlerkorrektur * Löschen der temporären Datei(Wird von PHP automatisch erledigt). Ein wichtiges Kriterium für Skripts ist die Wiederverwendbarkeit. Falls sich Änderungen ergeben, wie zum Beispiel durch einen Providerwechsel oder einfach durch die zugelassene Dateigröße, soll ja nicht das gesamte Skript umgeschrieben werden. Deswegen werden diese Werte eingangs deklariert. Dann wird die Funktion für die zufällige Auswahl eines neuen Dateinamens vereinbart. Schließlich sollen schon existierende Dateien mit dem gleichen Dateinamen nicht einfach überschrieben werden. $zielname = tempnam($ziel, "IMG") . $datei_ende; Diese Funktion wird dann an gewünschter Stelle aufgerufen. Jetzt folgt die eigentliche Programmstruktur, welche die Datei aus dem temporären Ordner in den Zielordner kopiert und auf Fehler überprüft. if(!is_uploaded_file($_FILES["file"]["tmp_name"]) { exit("Es handelt sich um keine hochgeladene Datei."); } if($_FILES["file"]["size"] > $datei_max) { exit("Die Datei ist größer als $datei_max Byte."); } if($_FILES["file"]["type"] != $datei_mime) { exit("Der Dateityp ist nicht richtig. Die Datei muss vom Typ $datei_ende sein."); } if(file_exists($zielname) or !copy($_FILES["file"]["tmp_name"], $zielname)) { exit("Ein Fehler ist beim Kopieren der Datei ".$_FILES["file"]["name"]." Aufgetreten!"); } echo "Die Datei ".basename($zielname)." wurde erfolgreich Hochgeladen.

"; ?>
Am Schluss kannst Du die hochgeladene Datei löschen, was PHP allerdings automatisch erledigt, wenn das Skript beendet wird. Allerdings ist der Code sauberer, wenn man dies nicht automatisch machen lässt. unlink($_FILES["file"]["tmp_name"]); ?> Das Skript eignet sich vor allem für den kontrollierten Upload eines bestimmten Dateityps. Eine Anwendung im bereich von Nutzer-spezifischen Anwendungen ist optimal. So könnte zum Beispiel jeder angemeldete Benutzer ein Bild von sich auf Deine Website laden. Der neu erzeugte Dateiname sollte dann nur noch in einer Datenbank gespeichert werden, sonst verlierst Du die Übersicht über die kryptisch anmutenden Dateinamen. ---- Die Prüfung auf den Dateityp beinhaltet allerdings Risiken, denn es wird lediglich das geprüft, was der Browser an PHP weitergibt. Eine tatsächliche Prüfung findet **nicht** statt. ---- ===Sicherheitshinweis=== Der Upload einer Datei birg Risiken. Sobald Dateien unkontrolliert auf den Webserver geladen werden drüfen, sind Benutzer mit bösen Absichten oder einer gefährlichen Unkenntnis nicht weit. So könnten Viren, Trojanische Pferde oder einfach nur Datenmüll versendet werden. Deshalb solltest Du den Datei-Upload immer absichern.