Ein- und Ausgabe

Um was geht es?

Ein- und Ausgabe ist einerseits der Prozess der Kommunikation eines Programms mit seiner Anwenderin oder seinem Anwender, andererseits das Lesen und Schreiben in Dateien und schliesslich die Kommunikation mit anderen Programmen.

Für Internet-Sprachen ist die Anwenderkommunikation kein ganz so einfaches Geschäft wie für andere Programmiersprachen. Das liegt daran, dass die klassische Form der Ein- und Ausgabe über ein Terminalfenster nicht existiert. Für jede Eingabe über das Internet muss eine grafische Schnittstelle (GUI - graphical user interface) geschaffen werden, für deren Auslesen es keinen einheitlichen Befehl gibt. Aber auch die Ausgabe erfolgt nicht grundsätzlich im Haupttext einer HTML-Seite, sondern z.B. innerhalb von Textfeldern oder als Meldung in einem neuen Fenster. Derartige Möglichkeiten gibt es in anderen Programmiersprachen natürlich auch, aber man wird nicht gleich als Anfänger beim Erlernen der Sprache damit konfrontiert. Bei Programmen für das Internet führt dagegen von Anfang an kein Weg an GUI's vorbei.

Erschwerend kommt hinzu, dass Java, JavaScript und PHP, obwohl sie alle eine Webseite mitgestalten können, sehr unterschiedliche Rollen übernehmen. Das Arbeitsgebiet von JavaScript sind der Browser und die dargestellten HTML-Seiten; JavaScript ist darauf spezialisiert, diese Elemente zu beeinflussen. Java schafft sich innerhalb des Anzeigebereichs, der ihm auf einer Webseite zur Verfügung gestellt wird, seine ganz eigene Umgebung und arbeitet mit dem Rest der Seite kaum zusammen. Es benutzt eigene Befehle zur Erstellung einer GUI und kann mit den HTML-Eingabefeldern, die vielleicht auf der gleichen Seite vorhanden sind, nichts anfangen. GUI's mit Java sind somit ein ganz eigenes Kapitel, das im Rahmen einer Einführung zu weit führt. PHP schliesslich kann die Eingaben aus einem Webformular entgegen nehmen und daraus unter Benutzung der auf dem Server gespeicherten Daten neuen HTML-Code generieren. Es kann die erhaltenen Formulareingaben jedoch auch für Aktivitäten auf dem Server nutzen, z.B. um sie in einer Datei oder Datenbank abzulegen. Es ist sogar möglich, mit PHP Programme auf dem Server aufzurufen, und deren Ausgabe weiterzuverwenden.

Das Lesen und Schreiben in Dateien als zweite Form der Ein- und Ausgabe ist JavaScript- und Java-Programmen aus Sicherheitsgründen grundsätzlich verboten. Da JavaScript und Java Client-seitig ausgeführt werden, würden diese Lese- und Schreibvorgänge ja auf dem Client-Computer ausgeführt werden, und so könnten JavaScripts und Java-Applets den Client-Computer gänzlich auf den Kopf stellen. Es gibt allerdings Ausnahmen: JavaScripts können den Browser veranlassen, in einer von diesem dafür bestimmten Datei einzelnen Zeilen (so genannten Cookies) einzutragen, die dann später auch wieder ausgelesen werden können. Auch Java-Applets kennen Ausnahmen: Es ist möglich, Applets digital signieren zu lassen, so dass sich ihre Herkunft einwandfrei feststellen lässt. Solchen Applets kann man als Anwenderin oder Anwender sein Vertrauen aussprechen, und sie damit auch auf die Dateien des eigenen Rechners zugreifen lassen.

Wirklich wichtig ist das Lesen und Schreiben von Dateien aber vor allem für PHP-Programme. PHP würde gar keinen Sinn machen, wenn es nicht auf die Resourcen des Servers zugreifen würde, denn alle sonstigen Aufgaben können mit JavaScript gleich gut oder besser erledigt werden. Erst der Zugriff auf Serverdaten ermöglicht PHP Dinge, die mit Client-seitigen Programmen nicht möglich sind.

Die Kommunikation mit anderen Programmen schliesslich führt schnell zu sehr fortgeschrittenen Problemen. Java-Applets können z.B. über das Internet mit Programmen auf dem Server kommunizieren, von dem sie geladen wurden. Natuürlich setzt das ein entsprechendes Programm auf dem Server voraus, das auf den Kommunikationsversuch antwortet. JavaScript kann (ausser auf dem Mac) mit den Java-Applets kommunizieren, die im gleichen Browser ablaufen. PHP kann andere Programme starten und deren Ausgabe auswerten, es kann aber auch mit bereits gestarteten Programmen, z.B. Datenbanken, kommunizieren, sofern diese dafür eingerichtet sind. Obwohl diese Aufgaben zum Teil sehr einfach zu realisieren sind, gehen sie doch vom Konzept her sehr weit und passen daher grösstenteils nicht in eine Einführung wie diese.

Im Bereich der Ein- und Ausgabe lassen sich die verschiedenen Programmiersprachen des Internets somit kaum vereinheitlicht darstellen. Im folgenden werden wir uns daher im Gegensatz zur übrigen Anleitung nicht mit allgemeinen Konzepten befassen, sondern einzelne Aufgaben ansehen, die im Zusammenhang mit der Programmierung des Internets wichtig sind: Das Auslesen von Formularfeldern mit JavaScript und PHP, das Setzen von Formularfeldinhalten mit JavaScript und das Lesen und Schreiben in Dateien mit PHP.

Eingabefelder auslesen mit JavaScript

HTML-Formulare bestehen aus einzelnen Feldern wie anklickbaren Buttons, Auswahlen, Menus usw. Eine Übersicht über die verschiedenen Arten von Eingabefeldern findet man im Abschnitt Formulare der Selfhtml-Anleitung.

Damit JavaScript die Formulardaten ausliest, muss man es dazu veranlassen. Die üblichste Methode dazu besteht darin, einen Klick-Button zu definieren, der JavaScript-Code startet, sobald er angeklickt wird. Eine Übersicht über andere Möglichkeiten gibt die Selfhtml-Anleitung im Abschnitt Event-Handler. In jedem Fall muss der JavaScript-Code, der gestartet wird, eine Funktion sein.

Das folgende Beispiel enthält ein Textfeld für die Eingabe, einen <span>...</span>-Bereich für die Ausgabe (zu diesem kommt die Erklärung im nächsten Abschnitt) und einen Button, der eine JavaScript-Funktion aufruft, sobald er angeklickt wird.


Eingabe: <input type="text" id="eingabe" size="40" maxlength="40"> <br /><br /> 
<!-- Das Attribut "id" dient zur Kennzeichnung des Eingabefelds. Später
     kann es in JavaScript über diese Id angesprochen werden -->
Ausgabe: <span id="ausgabe">&nbsp;</span> <br /><br />
<!-- Gewöhnlicher Text kann nur durch <span> zu einem Element gemacht werden, das dann über seine
     id (hier "ausgabe") von JavaScript angesprochen werden kann -->
<input type="button" onclick="javascript:verarbeiten()" value="Klick hier"><br><br>

Um die Daten wirklich auslesen zu können, müssen wir eine Funktion namens auslesen() schreiben. (Es ist nicht nötig, dass diese Funktion wirklich auslesen() heisst, der Name ist frei wählbar. Nur muss er gleich sein wie in der onClick="javascript:....()"-Anweisung.)

Für die Auswertung der Daten ist es wichtig, dass alle Formularelemente eine Id haben, die im jeweiligen einleitenden Tag mit id="...." definiert wird. Diesen Namen können wir gebrauchen, um mit der Funktion document.getElementById("id") (wobei id hier für den Wert der gesetzten Id steht) auf das Objekt zuzugreifen.

Um mit diesem Objekt etwas anfangen zu können, müssen wir freilich auch noch wissen, welche Variablen und Methoden es enthält. Bei einem Objekt vom Typ input sind das die Variablen defaultValue, form, name, type und value, sowie die Methoden blur(), click(), focus(), handleEvent() und select(). Die Bedeutung dieser Felder wird in der Selfhtml-Anleitung im Abschnitt elements erklärt. Der Text, der in das Eingabefeld angegeben ist, steht in der Variablen value. Wir gelangen an ihn, wenn wir ihn als document.getElementById("eingabe").value ansprechen.

Andere Arten von Eingabefeldern, z.B. Auswahlen oder Checkboxen, müssen mit den anderen Variablen ausgewertet werden, z.B. steht bei einer Checkbox in der Variablen checked, ob diese angewählt ist oder nicht. Für Auswahlen (also Menu-ähnliche Strukturen) gibt es sogar eine Unterklasse options, deren Objekte die einzelnen Auswahlmöglichkeiten sind. Genaueres zu den vielen Möglichkeiten findet man im schon erwähnten Abschnitt elements der Selfhtml-Anleitung.

Ausgabe schreiben mit JavaScript

Um eine Ausgabe zu schreiben, muss JavaScript wissen, wohin diese geschrieben werden soll. Dazu muss zunächst ein Bereich (ein so genannter span) definiert werden, der dies festlegt. Dies haben wir im vorigen Abschnitt bereits erledigt. Es sah so aus:


Eingabe: <input type="text" id="eingabe" size="40" maxlength="40"> <br /><br /> 
<!-- Das Attribut "id" dient zur Kennzeichnung des Eingabefelds. Später
     kann es in JavaScript über diese Id angesprochen werden -->
Ausgabe: <span id="ausgabe">&nbsp;</span> <br /><br />
<!-- Gewöhnlicher Text kann nur durch <span> zu einem Element gemacht werden, das dann über seine
     id (hier "ausgabe") von JavaScript angesprochen werden kann -->
<input type="button" onclick="javascript:verarbeiten()" value="Klick hier"><br><br>

Wichtig ist es, dem <span>...</span>-Bereich eine Id zuzuweisen, die im ganzen Dokument nur einmal vorkommen darf. Anhand dieser Id kann das Element nun mit der Funktion document.getElementById("id") angesprochen werden. Die Funktion liefert das ganze <span>-Objekt zurück, der eigentliche Inhalt befindet sich im Unterobjekt firstChild.nodeValue. Um nun den Text im Span mit der id "ausgabe" anzusprechen, müssen wir somit document.getElementById("ausgabe").firstChild.nodeValue schreiben. Das ist zwar kompliziert, aber es funktioniert bei jedem Span gleich.

Im Folgenden nun der (im HTML-Teil leicht gekürzte) Quelltext (das lauffähige Programm ist hier):


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de">
<head>
<title>Ein einfaches Formular</title>
<meta http-equiv="Content-type" content="text/html; charset=iso-8859-1" />
<script type="text/javascript">
<!--
function verarbeiten() {
  document.getElementById("ausgabe").firstChild.nodeValue document.getElementById("eingabe").value;
  // links sehen Sie, wie man einen span anspricht          rechts sehen Sie, wie man ein Eingabefeld anspricht
}
//-->
</script> 
</head>
<body>
<h1>Ein einfaches Formular</h1>
<p>
Eingabe: <input type="text" id="eingabe" size="40" maxlength="40" /> <br /><br /> 
<!-- Das Attribut "id" dient zur Kennzeichnung des Eingabefelds. Später
     kann es in JavaScript über diese Id angesprochen werden -->
Ausgabe: <span id="ausgabe">&nbsp;</span> <br /><br />
<!-- Gewöhnlicher Text kann nur durch <span> zu einem Element gemacht werden, das dann über seine
     id (hier "ausgabe") von JavaScript angesprochen werden kann -->
<input type="button" onclick="javascript:verarbeiten()" value="Klick hier" /><br /><br />
</p>
<p>
<a href="simpleformjs.html.phps">Quelltext</a>
</p>
</body>
</html>

 

Formulardaten mit PHP lesen und verarbeiten

PHP ist eine Server-seitige Sprache. Alle Eingaben müssen daher vom Client (Browser) zunächst an den Server übermittelt werden, der dann als Antwort eine neue Seite zurückschickt, deren Inhalt von den zuvor übermittelten Eingaben abhängen kann.

Um die Eingaben abzugrenzen, die an den Server geschickt werden sollen, benutzt man in HTML das <form>..</form>-Tag. Den Abschnitt innerhalb dieser Tags nennen wir das Formular. Jedes Formular braucht eine Möglichkeit, mit der es abgeschickt werden kann. Beim Abschicken des Formulars werden dann die Inhalte aller Eingabefelder, die sich innerhalb des <form>..</form>-Bereichs befinden, übermittelt. Eine HTML-Seite kann auch mehr als ein Formular enthalten, jedoch werden beim Abschicken nur die Daten desjenigen Formulars weitergeschickt, von dem der Befehl zum abschicken ausgeht.

Wenn man ein Formular abschicken will, kann man das entweder einer JavaScript-Funktion mitteilen, die auf Aktionen an einem Element des Formulars reagiert, oder man fügt ein Eingabefeld vom Typ submit ein, und legt im einleitenden <form>-Tag fest, was mit dem Formular gemacht werden soll, wenn es abgeschickt wird.

Zum Abschicken stehen zwei Methoden zur Verfügung, get und post. Wenn die Methode get gewählt wird, sind nach dem Laden des Dokuments, das die Daten verarbeiten soll, in der Pfadzeile des Browser die Namen und Werte der weitergeschickten Variablen sichtbar, denn diese Daten werden als Teil der Pfadadresse weitergegeben. Mit post ist das nicht der Fall, hier werden diese Daten in einer eigenen Datei an den Server geschickt. In beiden Fällen kennt der PHP-Prozessor, der das PHP-Skript abarbeitet, die Namen und Verte dieser Variablen, so dass diese Variablen im Skript einfach verwendet werden können.

Um die Namen der Variablen festzulegen, versieht man die Eingabeelemente des Formulars mit einem name-Attribut. Dieses erfüllt also eine ähnliche Funktion wie das id-Attribut für JavaScript, und es ist denkbar, dass in Zukunft das name-Attribut sogar ganz zu Gunsten des id-Attributs verschwindet. Momentan ist es sicher keine schlechte Lösung, beide Attribute zu verwenden, sie aber mit dem gleichen Wert zu versehen.

Im folgenden Formular wird durch die Anweisung action="auswertung.php" innerhalb des <form>-Tags festgelegt, dass die Formulardaten an eine Datei namens auswertung.php geschickt werden. Das Formular enthält ein Eingabe- und ein Abschick-Feld.


<form id="formular" action="auswertung.php" method="post">
Eingabe: <input type="text" id="eingabe" name="eingabe" size="40" /> <br />
<input type="submit" value="Klick hier" /><br />
</form>

Das folgende Beispiel zeigt, wie auf das obige Formular auf einfachste Weise reagiert werden kann, indem zurückgemeldet wird, was der Wert des Feldes war. Wenn Sie das Beispiel durchspielen wollen, klicken Sie auf das Formular. Sie können sich auch den Quelltext der wirklichen auswertenden PHP-Datei ansehen.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de">
<head>
<title>Auswertung mit PHP</title>
<meta http-equiv="Content-type" content="text/html; charset=iso-8859-1" />
</head>
<body>

<h1>Auswertung mit PHP</h1>
<p>
<?php
echo "Die Eingabe war <em>$eingabe</em>.\n"; 
     // (Die Variable muss gleich heissen wie der Feldname, der mit id="eingabe" bezeichnet wurde.)
?>
</p>
</body>
</html>

Dateien lesen mit PHP

Um eine Datei lesen zu können, muss man sie mit der Funktion fopen() öffnen. fopen() erwartet zwei Parameter, nämlich den Namen der zu öffnenden Datei und den Modus, wie die Datei geöffnet werden soll. Zum lesen ist der Modus r für read. fopen() gibt einen Wert zurück, den man jetzt immer angeben muss, wenn man aus der Datei lesen will. Es ist daher unerlässlich, diesen Wert in einer Variablen zu speichern. Insgesamt läuft der Öffnungsvorgang dann so ab:


$datei = fopen("/pfad/zur/datei/dateiname", "r");

Wird kein Pfad angegeben, nimmt PHP an, die Datei befinde sich im gleichen Verzeichnis wie das Skript selbst.

Natürlich kann es sein, dass sich die Datei aus irgendwelchen Gründen nicht öffnen lässt. In solchen Fällen gibt fopen() den Wert 0 zurück. Vielleicht existiert sie nicht, oder PHP hat keine Leseberechtigung (es ist zu beachten, dass PHP die Datei nicht mit den Rechten des Eigentümers, sondern mit denjenigen Rechten öffnet, die der ganzen Welt zugestanden werden). Tatsächlich existiert die Datei manchmal nicht, weil sich im Pfad ein Tippfehler eingeschlichen hat. Es wäre in jedem Fall gut, wenn PHP dann den Programmablauf mit einer Fehlermeldung abbrechen würde. Um genau das zu tun, gibt es die Funktion die(). Das obige Programmbeispiel sieht dann so aus:


$datei = fopen("/pfad/zur/datei/dateiname", "r");
if($datei == 0)
  die("Die Datei konnte nicht geöffnet werden!");

Ein PHP-Guru schreibt diese 3 Zeilen allerdings folgendermassen:


$datei = fopen("/pfad/zur/datei/dateiname", "r")
  or die("Die Datei konnte nicht geöffnet werden!");

Eine Erklärung dieses wirklich schönen Codes würde hier zu weit führten, dennoch wird er zur Nachahmung empfohlen.

Um eine Zeile aus der Datei zu lesen, benutzt man die Funktion fgets() (file get string). Das obige Beispiel könnte daher so weiter gehen:


$zeile1 = fgets($datei); 
echo "In der ersten Zeile steht $zeile1";

Jeder weitere Aufruf von fgets() liefert eine weitere Zeile der Datei. Wenn die Datei zu Ende gelesen ist, gibt fgets() 0 zurück. Um die ganze Datei auszulesen, gehen wir daher so vor:

$i = 0;
while($zeile = fgets($datei) { 
  /* Die while()-Schleife wird ausgeführt, solange der Ausdruck in der
     Schleife den logischen Wert WAHR hat. Da in PHP jede Zahl ausser 0 den logischen
     Wert WAHR hat, und der Wert einer Zuweisung der zugewiesene Wert ist, wird die
     Schleife so lange ausgeführt, bis in $zeile der Wert 0 steht; also bis die
     Datei zu Ende gelesen ist. 
  */
  ++$i;
  echo "Zeile $i: $zeile";
}

Manchmal möchte man das Zeichen für den Zeilenumbruch am Ende der Zeile loswerden. Das ist z.B. dann unumgänglich, wenn die eingelesene Zeile aus einer Zahl besteht, die nachher auch als Zahl gebraucht werden soll. Dazu gibt es den Befehl chop():


$a = "String mit Newline am Ende\n";
$a = chop($a); #Jetzt ist das Newline am Ende weg.

Schliesslich muss die Datei auch wieder geschlossen werden. Dazu gibt es den Befehl fclose(). Damit endet das obige Beispiel mit


fclose($datei);

Dateien schreiben mit PHP

Dateien lesen und schreiben funktioniert ziemlich gleich. Daher sollte nach dem letzten Abschnitt das folgende Beispiel keine weiteren Erklärungen erfordern. Zu beachten ist jedoch, dass eine allenfalls schon bestehende Datei gleichen Namens gelöscht wird, wenn man sie zum schreiben öffnet.


$datei = fopen("/pfad/zur/datei/dateiname", "w") # w für write
  or die("Die Datei kann nicht geöffnet werden!"); 
for($i = 1; $i < 100; $i++) // 100 mal schreiben
   fputs($datei, "Hier schreiben wir die Zeile $i!\n");
fclose($datei);

Valid XHTML 1.1! Valid CSS!