Webprogrammierung — 12. Lektion

Formularauswertung

Die Nutzereingaben in Formularfelder werden in die interne Repräsentation (das Document Object Model – DOM) der Seite eingetragen und können mittels JavaScript abgegrifen und clientseitig ausgewertet werden. Das Auswertungsprogramm ist demzufolge ebenfalls dem Browser beim Laden der Seite zugeschickt worden. Damit könnte der Nutzer auskundschaften, bei welcher Eingabe was erwartet wird. Folglich kann auf diese Weise nicht überprüft werden, ob der Nutzer wirklich weiß, was eingetragen werden soll oder es erst in Erfahrung gebracht hat. Also fallen prüfungsähnliche Szenarien als Anwendungsfälle aus. Kein Quiz, keine Prüfung, keine Passwortabfrage, denn in all diesen Fällen sollte der Client die Auflösung nicht vorgesagt bekommen.
Es gibt auch andere Situationen, in denen JavaScript und eine clientseitige Bearbeitung nicht weiterhilft. Die Daten können beispielsweise nicht auf dem Client-Rechner gespeichert werden (so, dass sie nach Beenden des Browsers immer noch und auch anderen Programmen zur Verfügung stehen). In wiederum anderen Fällen müssen die Eingaben an einen Server gehen, da jemand anderer darauf reagieren soll, z.B. beim Bestellen von Waren, Registrieren von Zugangsdaten, Melden von Vorkommnissen.
Der Browser muss also getätigte Eingaben an einen Server schicken können, der wiederum muss sie automatisch oihne Zutun eines Menschen) verarbeiten können. Für letzteres werden Programme geschrieben. Eine gängige Programmiersprache ist PHP, aber es gibt daneben noch weitere.

Absenden eines Formulars

Damit Daten an einen Server abgesendet werden, muss im Formularelement angegeben sein, wohin die Daten gesendet werden sollen (Server und empfangendes Programm). Es gibt Ereignisse, die das Absenden auslösen. Dazu zählen standardmäßig das Drücken eines Submit-Buttons oder das Abschließen einer Text-Eingabe mit Enter (letzteres führt häufig zu vorzeitigem Absenden der Formulardaten, weshalb es nutzerfreundlicher sein kann, dieses Verhalten mittels JavaScript zu ändern – das wird hier jedoch nicht behandelt).

Rückblick

Ein Submit-Button wird gesetzt durch <button>Aufschrift</button> oder <input type=submit value="Aufschrift"> (auch im button-Anfangstag darf das Attribut type gesetzt werden; submit ist aber der Standardwert). Um die Bedienung zu erleichtern, sollte so ein Knopf immer vorhanden und als solcher zu erkennen sein. Mit dem Attribut onclick kann festgelegt werden, welche Aktion (JavaScript) beim Anklicken ausgeführt werden soll. Wenn so etwas angegeben ist, wird dies ausgeführt, bevor die Daten abgesendet werden. Dadurch können die Daten schon vor Übertragung in mancherlei Hinsicht überprüft werden.

Absenden abbrechen

Falls sich beim Überprüfen durch die im Attribut onclick angegebene Funktion ergibt, dass die Daten doch nicht abgesendet werden sollen, kann man das Absenden verhindern. Eine Möglichkeit dazu ergibt sich wie folgt: onclick="return true;" bewirkt das Absenden der Daten; onclick="return false;" bewirkt das Abbrechen der Aktion. Man rufe also eine Überprüfungsfunktion auf und gebe dann true oder false in Abhängigkeit von deren Ausgang zurück. Zweckmäßigerweise gibt die Überprüfungsfunktion selbst schon diesen benötigten Wert zurück, dann muss er nur noch weitergereicht werden: onclick="return ueberpruefe();" und die Funktion ueberpruefe() gibt true zurück, wenn alles in Ordnung ist, und andernfalls false.

Sendemethoden

Im Anfangstag des Formulars gibt man neben einer Aktion (Attribut action) auch eine Übertragungsmethode (Attribut method) an. Es werden zwei Methoden unterschieden: get und post. Die Methoden sind Bestandteil des Hypertext Transfer Protocol (HTTP).

Get

Die Methode get wird verwendet, wenn der Client Daten vom Server empfangen soll und dem Server lediglich Parameter für die auszuführende Aktion sendet (wenn also der vordergründige Zweck das Holen von Daten ist), z.B. bei einer Telefonbuchabfrage. Dabei werden die Parameter als Bestandteil der URL gesendet und sind demzufolge im Browser sichtbar. Daher diese Methode niemals verwenden, wenn Passwörter oder andere zu schützende Daten übermittelt werden (auch wenn der primäre Zweck das Abfragen von Daten ist)!

Post

Die Methode post wird verwendet, um Daten (beispielsweise auch Dateien) zum Server zu schicken (ohne notwendigerweise Daten zu empfangen). Dabei werden die übermittelten Daten nicht im Browser angezeigt. Daher ist diese Methode auch vorzuziehen, wenn Daten zu übermitteln sind, die nicht im Browser zu sehen sein sollen.

Gemeinsames Beispiel

Im folgenden Beispiel wird ein Formular aufgebaut, das ein Textfeld zum Eingeben eines Namens, ein Eingabefeld für ein Passwort und einen Absendeknopf enthält. Beim Klick auf den Knopf wird zunächst die Funktion ueberpruefen() aufgerufen. Sie untersucht, ob die Länge der Namenseingabe mit dem Passwort übereinstimmt. Falls ja, ist der Rückgabewert true und return true; bei onclick angegeben bewirkt das Absenden der Daten. Falls das Passwort nicht die Länge der Namenseingabe ist, ist der Rückgabewert false und return false; bei onclick bewirkt, dass nichts abgeschickt wird.
Wenn gesendet wird, werden die Eingabedaten an die bei action angegebene Datei übermittelt. Da nur der Dateiname angegeben ist, wird der Rest (Protokoll, Servername und Pfad) von der aufrufenden Webseite übernommen. Falls sie nicht von einem Webserver (z.B. den von XAMPP) erhalten wurde sondern aus dem lokalen Dateisystem (zu erkennen am anfänglichen file://), wird auch die php-Datei nur wie eine beliebige Datei angezeigt, aber nicht als PHP-Programm ausgeführt. Die gesendeten Daten laufen ins Leere; die Datei wird vom Browser der Sprache HTML entsprechend interpretiert (alles zwischen spitzen Klammern wird als Tag angesehen und nicht angezeigt). Die php-Datei des Beispiels ist so konstruiert, dass bei HTML-Interpretation ein entsprechender Hinweis erscheint (auch wie man erreicht, dass die Datei von localhost geladen wird, dazu muss in XAMPP der Apache-Server gestartet sein) und bei PHP-Interpretation die eigentliche Antwort des Webservers angezeigt wird.
Im Falle, dass das Attribut method den Wert post hat, sieht man nichts außer der Ausschrift des PHP-Programms. Hat das Attribut method den Wert get, sieht man in der Adresszeile des Browsers nach dem Namen der php-Datei ein Fragezeichen. Dies leitet die Parameterübergabe ein. Danach folgen einige (in diesem Beispiel zwei) Paare von Variablen und Werten. Diese Paare sind durch das Und-Zeichen & voneinander getrennt. Ein solches Paar hat als erstes einen Variablennamen, gefolgt vom Gleichheitszeichen = und danach den auf diese Variable übergebenen Wert. Der Variablenname ist der Wert des Attributes name in einem Eingabefeld des Formulars. Der Wert ist das, was in dem betreffenden Eingabefeld eingetragen wurde. Allerdings ist dieser Wert so kodiert, dass eine zulässige URL-Zeichenkette entsteht. Beispielsweise wird ein Leerzeichen durch ein Plus + ersetzt, ein Fragezeichen durch %3F, ein Und-Zeichen durch %26 und ein Gleichheitszeichen durch %3D. Dies ist nötig, damit die Trennzeichen nicht mit den gleichen Zeichen in zu übermittelnden Daten kollidieren. Ist in einem input-Tag das Attribut name nicht mit einer nicht-leeren Zeichenkette belegt, so existiert für dieses Eingabefeld keine Variable (eine möglicherweise angegebene ID hat mit der Datenübertragung nichts zu tun) und es wird auch keine Eingabe in dieses Feld an den Server übertragen.
Da sich mit der get-Methode Fehler leichter erkennen lassen (z.B. vergessenes name-Attribut), werden sich im Folgenden die Ausführungen und Beispiele auf diese Methode beziehen. Es wird aber, wenn nötig, auf die post-Methode eingegangen. In diesem Beispiel ist zu erkennen, dass das eingegebene Passwort in der Adresszeile des Browsers zu sehen ist. Dies dient nur zu Demonstrationszwecken. In realen Anwendungen sollte man so etwas nie tun, sondern immer die post-Methode wählen.
Das Erscheinungsbild wird hier nicht in einem Inline Frame angezeigt, da das Wichtige ist, die Adresszeile des Browsers zu beobachten, und die ist in einem Inline Frame nicht zu sehen.
Die html-Datei mit dem Formular:
<!DOCTYPE html>
<html lang=de>
<head>
  <title>Formular</title>
  <meta charset=utf-8>
  <script src="jquery-3.4.1.min.js"></script>
  <script>
    function ueberpruefen() {
      return ($('#name').val().length==$('#pwd').val());
    }
  </script>
</head>
<body>
  <form name="beispiel-formular" action="bsp57.php" method="get"> <!-- oder method="post" -->

  Name: <input type=text name="name" id="name" required><br>
  Passwort: <input type=password name="pwd" id="pwd" required><br>
  <button onclick="return ueberpruefen();">Absenden</button>

  </form>
</body>
</html>
Beispiel mit get   |   Beispiel mit post
Die php-Datei soll dazu dienen, die Unterschiede zwischen get und post sowie zwischen Anfrage an Webserver und lokales Dateisystem zu verdeutlichen. Deshalb wird hier auf keine Variable und auf keine übermittelten Daten zugegriffen.
<!DOCTYPE html>
<html lang=de>
<head>
  <title>Formular</title>
  <meta charset=utf-8>
</head>
<body>
<?php
  echo "Das Passwort war die Länge Ihres Namens, sonst wären Sie nicht hier.";
?>
<?php
/* >Wenn Sie dies hier sehen, steht in der Adresszeile Ihres Browsers wahrscheinlich <code>file://</code>...<br>
Ersetzen Sie dort alles ab <code>file://</code> bis einschließlich <code>htdocs</code> durch <code>localhost</code> und drücken Sie <code>enter</code>!<br><br>
Machen Sie dies bitte auch bei der Webseite mit der Lektion, bevor Sie mit ihr fortfahren! <!-- */
?> <!-- -->
</body>
</html>

Gesetzte Variablen

Auf einem Webserver mit PHP-Parser gibt es eine Datei namens phpinfo.php. Dieses Programm zeigt die Konfiguration des Servers und Variablen an, auf die von einem PHP-Programm zugegriffen werden kann. Bei XAMPP liegt sie im Verzeichnis dashboard. Falls XAMPP installiert ist und der Apache-Server läuft, kann man mit dem folgenden Link eine Formulardatenübermittlung mittels der Methode get simulieren:
http://localhost/dashboard/phpinfo.php?Veranstaltung=Webprogrammierung&Lehrkraft=Dr.+Bianca+Truthe
[Alternative mit bereitgestelltem Programm: phpinfo.php?Veranstaltung=Webprogrammierung&Lehrkraft=Dr.+Bianca+Truthe ]
In einer der letzten Tabellen der Anzeige, unter „PHP Variables”, sind insbesondere die übermittelten Daten zu sehen. Es gibt u.a. ein Array _GET, in dem die Indices die übermittelten Variablennamen sind und die Werte ihre übermittelten Werte.
Werden die Daten mit der Methode post übermittelt, so gibt es ein Array _POST mit dem gleichen Aufbau und Inhalt. Um dies zu sehen, folge man dem Link zu einem vorbereiteten Formular und klicke auf den Absenden-Knopf: Variante post.
Man kann auch beide Varianten mischen, wie das folgende Beispiel zeigt. Beim Absenden werden die Formulardaten mit der Methode post übermittelt. Die in der URL vom Attribut action angegebenen Parameter werden aber mit der Methode get übertragen. Damit man die Anzeige von phpinfo.php nicht nur in dem kleinen Inline Frame sieht, kann man das Beispiel auch in einem eigenen Tab sehen: Beispiel in großem Fenster.

Überprüfen von Variablen

Im PHP-Programm wird auf die übermittelten Werte über die Variablen der Form
$_GET["Name"] bei Methode get und $_POST["Name"] bei Methode post
zugegriffen, wobei Name der Name des jeweiligen Eingabefeldes ist (der Wert des Attributes name). Es dürfen auch einfache Anführungsstriche verwendet werden. Bei fehlendem Namen wird die zugehörige Eingabe nicht übermittelt. Wird bei einer Einfachauswahl mit Radiobuttons keine Auswahl getroffen, dann wird die zugehörige Variable nicht gesetzt. Damit es keinen fehlerhaften Zugriff darauf gibt, sollte man erst überprüfen, ob eine erwartete Variable gesetzt ist. Dies geschieht mit der Funktion
isset(Var).
Sie gibt true zurück, wenn die Variable Var gesetzt ist (existiert), und false andernfalls.
Die Variablen von Text-Eingabefeldern werden immer gesetzt, auch wenn nichts eingegeben wurde. Ob etwas eingegeben wurde, kann mit der Funktion
empty(Var)
überprüft werden. Sie gibt true zurück, wenn die Variable Var leer ist, und false andernfalls. Dabei bedeutet „leer” allerdings sowohl leere Zeichenkette als auch Wert 0. Wenn man eine genauere Angabe benötigt, muss man mit dem Identitätsoperator === testen, nicht mit dem Gleichheitsoperator ==.
Um zu überprüfen, ob es sich bei einem Wert um eine Zahl handelt, rufe man die Funktion
is_numeric(Var)
auf. Sie gibt true zurück, wenn die Variable Var eine Zahl ist, und false andernfalls.

Einfache Werte

Bei Textfeldern und Einfachauswahl durch Radiobuttons oder Drop-Down-Menüs gibt es höchstens eine Eingabe und damit höchstens einen Wert für jede Variable. Bei Mehrfachauswahl durch zusammenhängende Checkboxen (mit gleichem Namen) oder Drop-Down-Menüs mit Attribut multiple werden auf einer Variablen aber unter Umständen mehrere Werte abgelegt. Daher wird dies getrennt behandelt.
Im Folgenden werden Beispiele für Formularfelder und ihre Auswertung gegeben. Links sind zunächst die html-Dateien zu sehen und rechts das Aussehen. In dem Inline Frame rechts kann das Formular ausgefüllt und abgeschickt werden. Daraufhin wird in dem Inline Frame die Ausgabe des aufgerufenen php-Programmes eingeblendet. Die Programme sind so, dass sie das ursprüngliche Formular wieder anzeigen, aber zu jeder Eingabe noch eine Auswertung zeigen. Man kann das Formular gleich für den nächsten Test verwenden (andere Daten als die voreingestellten eingeben und wieder abschicken). Im linken Anzeigefenster kann mittels Knopfdruck zur Anzeige des zugehörigen PHP-Programmes umgeschaltet werden (und wieder zurück).
Bei diesen Beispielen wird in der Auswertung der Text so ausgegeben, wie er auf der jeweligen Variablen steht (um zu verdeutlichen, wie Beispielsweise Datums- oder Zeitangaben als Zeichenkette in einer Variablen gespeichert werden). Allerdings ist zu berücksichtigen, dass der Browser die Ausgabe vom PHP-Programm seinerseits interpretiert. Das PHP-Programm kann beispielsweise Tags schreiben, die im Browser dann bekanntermaßen interpretiert werden (und nicht als Text ausgeschrieben werden). Wenn in der Eingabe mehrere Leerzeichen oder andere Trennzeichen (z.B. Zeilenumbrüche) oder auch Tags stehen, so landen sie auch auf der Variablen, aber nicht in der Anzeige der Auswertung (man gebe beispielsweise <i>huhu</i> in ein Textfeld ein und sehe sich die Auswertung an). Bei Textfeldern mit freier Eingabe wird deshalb in der Auswertung die Eingabe auch URL-kodiert ausgegeben, also so, wie sie als Parameter in einer URL gesendet werden könnte. Daran kann man erkennen, was für Zeichen in der eigentlichen Zeichenkette vorkommen (kodiert). Mehr zu dieser hier genutzen Umwandlungsfunktion steht auf der Seite https://www.php.net/manual/de/function.urlencode.php.
Am Anfang der Auswertung werden die Anfragezeit und die Herkunft ausgegeben. Dies steht auf Servervariablen, die die Form $_SERVER["Name"] haben. Weitere sind in der Anzeige von phpinfo.php (siehe Abschnitt zuvor) zu sehen. Auf der Variablen $_SERVER["REQUEST_TIME"] steht die Anzahl der Sekunden, die seit dem 1.1.1970 0:00 Uhr UTC vergangen sind. Mit der Funktion date() kann man sich diese Anzahl in das entsprechende Datum und die entsprechende Uhrzeit umwandeln und als Zeichenkette in einem gewissen Format zurückgeben lassen.

Einzeilige Textfelder

Die Variablen zu einzeiligen Textfeldern sind immer gesetzt. In diesem Beispiel wird daher nur unterschieden, ob eine Eingabe vorhanden (nicht leer) war oder nicht.

Mehrzeilige Textfelder

Die Variablen zu mehrzeiligen Textfeldern sind auch immer gesetzt. Daher wird hier unterschieden, ob eine Eingabe vorhanden (nicht leer) war oder nicht.

Einfachauswahl

Wenn eine Auswahl existiert (egal, ob vom Nutzer selbst eingegeben oder standardmäßig gesetzt), dann ist die Variable gesetzt, sonst nicht. Ist eine Auswahl vorgegeben, dann kann der Nutzer durch sein Verhalten nicht mehr erreichen, dass nichts ausgewählt wird. In dem Falle ist die Variable also gesetzt und das Programm muss das nicht mehr untersuchen. Gibt es jedoch keine vorgegebene Auswahl, kann es sein, dass es dabei bleibt. Dann muss das PHP-Programm erst untersuchen, ob die Variable gesetzt ist, bevor sie weiter verwendet werden kann (z.B. untersucht werden kann, wie sie gesetzt ist). Leer sein kann eine solche Variable nur, wenn das Attribut value im input-Tag auf die leere Zeichenkette gesetzt ist. Ist das Attribut value gar nicht angegeben, so ist der Wert der Variablen on, falls dieser Radiobutton gewählt wird. Fehlt das Attribut value bei mehreren input-Tags, so kann man im PHP-Programm nicht unterscheiden, welcher Radiobutton gewählt war.

Drop-Down-Menü

Bei einem Drop-Down-Menü ist die Variable immer gesetzt, da standardmäßig der erste Eintrag als ausgewählt gilt, wenn nichts anderes durch selected oder Nutzereingabe ausgewählt wurde. Ausnahme: Wenn überhaupt kein option-Element angegeben ist, dann wird die Variable nicht gesetzt. Wenn beim ausgewählten option-Tag das Attribut value gesetzt ist, dann ist dieser Wert auch der Wert der Menü-Variablen. Andernfalls steht auf der Variablen der Text, der zwischen Anfangs- und Endtag vom option-Element steht.

Mehrfache Werte

Bei Mehrfachauswahl durch zusammenhängende Checkboxen (mit gleichem Namen) oder Drop-Down-Menüs mit Mehrfachauswahl (Attribut multiple gesetzt) werden unter Umständen mehrere Elemente ausgewählt. Mit der bisherigen Methode werden dann mehrere Name-Wert-Paare mit gleichem Namen an den Server geschickt. Es gilt dann nur das letzte. Um alle Werte zu erhalten, hänge man an den Variablennamen (den Wert des name-Attributes) eckige KLammern [] an. Damit wird diese Variable als Array verwendet, und die einzelnen Werte der ausgewählten Elemente werden fortlaufend hineingeschrieben. Bei Verwendung von JavaScript gehören die Klammern zum Namen. Bei Verwendung als Index für die $_GET- und $_POST-Felder müssen die eckigen Klammern allerdings weggelassen.
Im Folgenden werden Beispiele für Formularelemente mit Mehrfachauswahl und ihre Auswertung gegeben. Dabei werden verschiedene Möglichkeiten vorgestellt, wie die einzelnen Werte behandelt werden können.

Mehrfachauswahl

Wenn eine Auswahl existiert (egal, ob vom Nutzer selbst eingegeben oder standardmäßig gesetzt), dann ist die Variable gesetzt, sonst nicht. Deshalb muss das PHP-Programm erst untersuchen, ob die Variable gesetzt ist, bevor sie weiter verwendet werden kann (z.B. untersucht werden kann, wie sie gesetzt ist). Ein Element des Arrays ist leer, wenn das Attribut value im input-Tag auf die leere Zeichenkette gesetzt ist. Ist das Attribut value gar nicht angegeben, so ist der Wert des Array-Elementes on, falls diese Checkbox ausgewählt wird.
Eine Möglichkeit, die gespeicherten Werte anzuzeigen, ohne das Feld selbst zu durchlaufen, ist die Funktion implode. Sie setzt die Elemente des betreffenden Feldes zu einer Zeichenkette zusammen, wobei je zwei Elemente durch die der Funktion implode übergebenen Zeichenkette getrennt werden. Die Funktion hat die Wirkungsweise wie join in JavaScript.

Multiples Drop-Down-Menü

Bei einem Drop-Down-Menü mit Mehrfachauswahl ist die Variable nur gesetzt, wenn etwas ausgewählt wurde. Im Gegensatz zu Drop-Down-Menüs mit Einfachauswahl wird nicht standardmäßig der erste Eintrag als ausgewählt behandelt. Wenn bei einem ausgewählten option-Tag das Attribut value gesetzt ist, dann wird dieser Wert in das Array der Menü-Variablen geschrieben. Andernfalls kommt in das Array der Text, der zwischen Anfangs- und Endtag vom option-Element steht.
Neben der schon erwähnten Funktion implode() wird hier eine spezielle Schleife verwendet, um an jedes einzelne Array-Element zu gelangen:
foreach (Array-Variable as &Element) { Anweisungen; }
Damit wird das Array durchlaufen und jedes Element kommt der Reihe nach auf die Variable Element. Die Anweisungen werden für jeden Wert, den die Variable Element annimmt, ausgeführt. Dabei ist zu beachten, dass im Schleifenkopf vor der Variablen für die einzelnen Elemente das Zeichen & steht. Damit wird der Schleife die Adresse der Variablen mitgeteilt, so dass dort die einzelnen Werte aus dem Array nacheinander abgelegt werden können.
In diesem Beispiel wird auch das Gegenstück zur Funktion implode() vorgestellt: Mit der Funktion explode() wird eine Zeichenkette an allen Stellen, wo ein Zeichen aus dem ersten Parameter auftritt „auseinander gebrochen”. Diese Zeichen sind hinterher nicht mehr vorhanden und die übrigen Teile werden in ein Array eingetragen. Damit kann man leicht auf einzelne Bestandteile einer Zeichenkette zugreifen.