Wo Sie die Beispiele und den Code finden
Beispiel 1:
Formulareingaben sammeln, formatieren und als E-Mail versenden
Beispiel 2:
Ein Konvertierprogramm von RGB nach Hexadezimal
Beispiel 3:
Ein Adre▀buch durchsuchen
Tag 10
Kapitel 20 - Nⁿtzliche Formulare und Skripte
Das Lernen anhand von Beispielen ist eine Lebensform im Web. Man kann sich stets den Quellcode fⁿr die HTML-Seiten im Web ansehen, wenn also irgend jemand etwas Interessantes kreiert hat, k÷nnen Sie es nachvollziehen. Bei Formularen ist es jedoch schwieriger, diese attraktiven Komponenten kennenzulernen, weil Sie die Skripten nicht erhalten, die zur Verarbeitung der Formulare verwendet werden, es sei denn, sie werden explizit zur Verfⁿgung gestellt.
Dieses Kapitel enthΣlt vier Formulare oder Skripten fⁿr allgemeine und praktische Aufgaben, die Sie in ihrer Art vielleicht in Ihre eigenen Seiten aufnehmen wollen. Es enthΣlt au▀erdem Anweisungen und Beispielcode fⁿr die folgenden Dinge:
Wie ich bereits im vorigen Kapitel erwΣhnte, erfordern eine Menge der raffinierten Dinge, die Sie mit Formularen und InteraktivitΣt auf Ihren Webseiten verwirklichen k÷nnen, zumindest etwas Grundwissen im Programmieren. Die Beispiele in diesem Kapitel verwenden Perl, eine Programmiersprache, die fⁿrs CGI-Programmieren beliebt ist. Um dieses Kapitel voll ausnutzen zu k÷nnen, sollten Sie ein grundlegendes VerstΣndnis der Programmierkonzepte und von CGI, so wie ich es im vorigen Kapitel beschrieben habe, mitbringen. |
Bei diesem Kapitel hat mir Eric Murray entscheidend geholfen, der fast alle CGI-Skripten fⁿr die Beispiele geschrieben hat (insbesondere, wenn sie in Perl geschrieben wurden). Danke Eric, da▀ du diese Beispiele neben deiner tΣglichen Arbeit noch schreiben konntest. |
Wo Sie die Beispiele und den Code finden
Alle Beispiele aus diesem Kapitel sowie den Code fⁿr die Formulare und die zugeh÷rigen CGI-Skripten finden Sie im Web auf den folgenden Seiten:
http://www.lne.com/Web/Examples/
Wenn Sie in diesem Kapitel etwas finden, was Sie gerne verwenden wollen, besuchen Sie einfach den entsprechenden Site. Wenn Sie die Formulare in Ihren eigenen Web-PrΣsentationen einsetzen, geben Sie eine Verknⁿpfung zu unserer Site an, damit auch andere die Informationen finden k÷nnen. Weitere Richtlinien finden Sie an Ort und Stelle.
Beispiel 1:
Formulareingaben sammeln, formatieren und als E-Mail versenden
In diesem ersten Beispiel beginnen wir mit etwas ganz Einfachem, das Sie sich schon lange wⁿnschen: einem CGI-Skript, das nur die Eingaben von einem Formular entgegennimmt, sie formatiert und das Ergebnis per E-Mail an den Autor sendet.
Wie alles funktioniert
Hier finden Sie ein einfaches Beispiel, wie diese Kombination aus Formular und CGI-Skript funktioniert. Es hei▀t Surrealist Census, und sein Formular ist in Abbildung 20.1 gezeigt.
Abbildung 20.1: |
Nachdem der Leser das Formular ausgefⁿllt hat, schickt er es ab und erhΣlt eine freundliche Antwort (wie in Abbildung 20.2 gezeigt).
Die Ergebnisse werden via E-Mail an die Person geschickt, die das Formular geschrieben hat. Abbildung 20.3 zeigt diese Mail.
Abbildung 20.2: |
Abbildung 20.3: |
Das Formular
Hier der HTML-Code fⁿr das Formular von Surrealist Census:
<HTML><HEAD>
<TITLE>The Surrealist Census</TITLE>
</HEAD><BODY>
<H1>The Surrealist Census</H1>
<P>Welcome to the Surrealist Census. Please full out the following
form to the best of your abilities.</P>
<P>Use <STRONG>Submit</STRONG> To submit your results.
<HR>
<FORM METHOD="POST" ACTION="/cgi-bin/uncgi/mailcensus">
<P><STRONG>Name: </STRONG><INPUT TYPE="TEXT"
NAME="theName"></P>
<P><STRONG>Sex: </STRONG>
<INPUT TYPE="radio" NAME="theSex" VALUE="male">Male
<INPUT TYPE="radio" NAME="theSex"
VALUE="female">Female
<INPUT TYPE="radio" NAME="theSex" VALUE="null">Null
</P>
<P><STRONG>Contains (Select all that Apply): </STRONG><BR>
<INPUT TYPE="checkbox" NAME="humor">Vitreous Humor<BR>
<INPUT TYPE="checkbox" NAME="fish">Fish<BR>
<INPUT TYPE="checkbox" NAME="glycol">Propylene Glycol<BR>
<INPUT TYPE="checkbox" NAME="svga">SVGA Support<BR>
<INPUT TYPE="checkbox" NAME="angst">Angst<BR>
<INPUT TYPE="checkbox" NAME="catcon">Catalytic
Converter<BR>
<INPUT TYPE="checkbox" NAME="vitamin">Ten Essential Vitamins and
Nutrients<BR>
</P>
<P><INPUT TYPE="SUBMIT" VALUE="Submit Your Votes">
<INPUT TYPE="RESET" VALUE="Clear Form"></P>
<FORM>
<HR>
</BODY></HTML>
Einige Anmerkungen zu diesem Formular:
Das Skript
Nun wollen wir uns mit dem Skript fⁿr die Verarbeitung des Formulars beschΣftigen. Dieses Skript wurde in der Bourne-Shell geschrieben und stellt ein einfaches Beispiel dar, das die Formulardaten in einer temporΣren Datei ablegt und dann den Dateiinhalt per Mail an irgend jemanden sendet (hier ist das der Alias Web-Master). Sie k÷nnten diese Datei modifizieren, so da▀ sie den Inhalt des Formulars an eine bereits existierende Datei anhΣngt, das Ergebnis auf Ihrem Drucker ausgibt oder es an Ihren Freund in Oldenburg sendet. Der Knackpunkt ist, da▀ dieses Skript einfach nur Formulareingaben sammelt und sie irgendwo ausgibt. Diese Eingaben werden nicht verarbeitet.
Im ersten Schritt wird eine temporΣre Datei erzeugt, die die formatierten Daten speichert. Sie wird der Variablen TMP zugeordnet. Diese Zeile erzeugt eine temporΣre Datei, wobei die Proze▀-ID des Skripts angehΣngt wird (der $$-Teil), um einen eindeutigen Dateinamen zu erzeugen und zu verhindern, da▀ andere temporΣre Dateien ⁿberschrieben werden, die das Skript m÷glicherweise gleichzeitig verwenden.
#!/bin/sh
TMP=/tmp/mailcensus.$$
Jetzt fⁿgen wir der Datei eine einfache ▄berschrift hinzu:
echo "Surrealist Census Results"
>> $TMP
echo "-----------" >> $TMP
echo >> $TMP
Als nΣchstes werden die Werte der Felder theName und theSex an dieselbe Datei angehΣngt, ebenso wie eine Unterⁿberschrift fⁿr Contains. Beachten Sie, da▀ das Programm uncgi am Anfang jeder Variablen, wie Sie im letzten Kapitel erfahren haben, das PrΣfix WWW_ schreibt.
echo "Name: $WWW_theName"
>> $TMP
echo "Sex: $WWW_theSex" >> $TMP
echo >> $TMP
echo "Contains:" >> $TMP
Der nΣchste Abschnitt gibt die KontrollkΣstchen fⁿr die Daten dieser Person aus. Hier werte ich alle KontrollkΣstchenvariablen aus und gebe nur die markierten aus, so da▀ die Liste in der temporΣren Datei eine Untermenge der gesamten Liste enthΣlt (es sei denn, alle Elemente wurden markiert). Sie k÷nnen dieses Skript modifizieren, um die Liste in anderer Form auszugeben - beispielsweise durch die Angabe von JA oder NEIN hinter den Namen der einzelnen KontrollkΣstchen, um zu kennzeichnen, welche davon selektiert wurden. Da es Ihnen ⁿberlassen ist, wie Sie die Formulareingaben verarbeiten, k÷nnen Sie auch bestimmen, wie sie prΣsentiert werden sollen.
Fⁿr KontrollkΣstchen ist der Standardwert, der fⁿr den markierten Zustand gesendet wird, ╗on½. Hier ⁿberprⁿfen wir die einzelnen KontrollkΣstchenvariablen auf diesen Wert hin, wie etwa im folgenden Beispiel:
if [ "$WWW_humor" =
"on" ]; then
echo " Vitreous Humor" >> $TMP
fi
if [ "$WWW_fish" = "on" ]; then
echo " Fish" >> $TMP
fi
if [ "$WWW_glycol" = "on" ]; then
echo " Propylene Glycol" >> $TMP
fi
Da diese ▄berprⁿfung fⁿr die einzelnen KontrollkΣstchen im wesentlichen immer dieselbe ist, werde ich hier nur ein paar davon aufzeigen. Wenn Sie das vollstΣndige Skript sehen wollen, laden Sie es sich vom Web herunter.
Nachdem alle Daten gesammelt und formatiert wurden, versenden wir sie als Mail. Diese Zeile schickt die ganze temporΣre Datei als Mail an das Web-Master-Alias, wobei als Thema Survey Results angegeben wird:
mail -s "Survey Results" Web-Master < $TMP
Nun l÷schen wir die temporΣre Datei, damit nicht Ihr ganzes /tmp-Verzeichnis vollgeschrieben wird:
rm $TMP
Jetzt denken Sie vielleicht, Sie seien fertig, aber Sie mⁿssen ja noch etwas an den Browser zurⁿckgeben, so da▀ Ihr Leser wei▀, da▀ alles in Ordnung ist. Wir geben den Standard-Header und eine einfache HTML-Seite aus:
echo Content-type: text/html
echo
echo "<HTML><HEAD>"
echo "<TITLE>The Surrealist Census: Thank You</TITLE>"
echo "</HEAD><BODY>"
echo "<H1>Thank you for voting!</H1>"
echo "<P>Your votes in the Surrealist Census will be tallied and"
echo "used for reasons wholly inappropriate to herding sheep.</P>"
echo "</BODY></HTML>"
Speichern Sie Ihre Datei unter dem Namen mailcensus, installieren Sie sie in Ihrem Verzeichnis cgi-bin, und ⁿberprⁿfen Sie, ob sie ausfⁿhrbar ist. Anschlie▀end k÷nnen Sie sie von Ihrem Formular aus ausfⁿhren.
Mail von Nobody?
Wenn Sie sich dieses Skript herunterladen und auf Ihrem eigenen System einsetzen, werden Sie wahrscheinlich sofort feststellen, da▀ die Mail, die es an Sie schickt, vom Benutzer Nobody (Niemand) kommt. Die erste Frage wird sein: ╗Wie kann ich mein Skript so umschreiben, da▀ die Mail vom tatsΣchlichen Benutzer gesendet wird?½
Die Antwort ist: Das geht nicht. Wenn der Browser die Daten von dem Formular zum Server sendet, sendet er den Namen des Systems, von dem die Anforderung kam (enthalten in der Umgebungsvariablen REMOTE_HOST). Er sendet jedoch nicht den Namen des Benutzers, der das Formular gesendet hat (REMOTE_USER wird fⁿr pa▀wortgeschⁿtzte Seiten verwendet; mehr darⁿber erfahren Sie in Kapitel28, ╗Web-Server: Sicherheit und Zugriffskontrolle½).
Betrachten Sie es so: Wenn der Browser die E-Mail-Adresse von allen senden wⁿrde, die Ihr Formular eingeschickt haben, dann k÷nnten Sie diese Adressen sammeln und ihnen unsinnige Mails senden. Zum Schutz der PrivatsphΣre haben die meisten, wenn nicht sogar alle Browser-Entwickler sich darauf geeinigt, nichts zu senden, was die E-Mail-Adresse eines Benutzers betrifft, wenn ein Formular ⁿbertragen wird.
Wenn Sie die E-Mail-Adressen wollen, dann fragen Sie in Ihrem Formular danach. Wenn Ihre Leser wollen, da▀ Sie sie erreichen, dann werden sie ihre Adressen eintragen.
Wie das Skript an eine Datei angefⁿgt wird
Eine gebrΣuchliche AbΣnderung dieses Skripts ist, die Formulareingabe an eine Datei anzuhΣngen, statt sie via Mail zu versenden. Das ist insbesondere fⁿr einfache Textdatenbanken praktisch, etwa fⁿr das Adre▀buch, das Sie spΣter in diesem Kapitel noch kennenlernen werden.
Wenn Sie Ihr CGI-Skript in eine Datei schreiben wollen, sollten Sie beachten, da▀ CGI-Skripten unter Unix vom Server mit dem Namen Nobody ausgefⁿhrt werden (das ist zumindest der Standard; m÷glicherweise hat Ihr Server-Administrator einen anderen Namen gewΣhlt). Das ist nicht schlecht, weil der Server nicht verrⁿckt spielen und alles auf der Maschine l÷schen kann. Andererseits hat der Benutzer Nobody vielleicht keinen Zugriff auf die Datei, in die Sie schreiben wollen. In diesem Skript hat er Zugriff auf die temporΣre Datei, weil sie sich im Verzeichnis /tmp befindet, auf das alle Zugriff haben.
Um dieses Problem zu umgehen, stellen Sie sicher, da▀ jeder Ihre temporΣre Datei lesen und schreiben kann (world-writeable), indem Sie mit dem Befehl chmod die Dateirechte abΣndern (der exakte Befehl ist chmod a+w dateiname). Das bedeutet natⁿrlich auch, da▀ jeder in Ihrem System etwas hineinschreiben (oder den Inhalt l÷schen) kann. Vielleicht wollen Sie sie deshalb auch irgendwo auf Ihrem System verstecken oder in regelmΣ▀igen AbstΣnden in einer nicht ⁿberschreibbaren Datei sichern.
Allgemeine Mail-Skripts und gefΣlschte Mail
Eine weitere M÷glichkeit wΣre, das Skript allgemein zu gestalten und verschiedene E-Mail-Adressen als Bestandteil des Formulars zu ⁿbergeben, entweder als Abfragestring oder in einem verborgenen Feld. Dann k÷nnen mehrere Leute dasselbe Skript verwenden, und Sie schreiben das Verzeichnis cgi-bin nicht mit irgendwelchen Skripten voll, die alle dasselbe enthalten.
Na gut, nicht ganz. Das Problem bei der ▄bergabe eines E-Mail-Arguments vom Formular an Ihr Skript ist, da▀ jeder Ihr Skript von jedem beliebigen Formular aus mit einer beliebigen E-Mail-Adresse aufrufen kann. Ihr Skript sendet freudig Daten an alle E-Mail-Adressen, die man ihm ⁿbermittelt. Angenommen, jemand hat Ihr Formular gespeichert und bearbeitet, so da▀ das Mail-Argument auf joe@randomsite.com zeigt. Diese Person k÷nnte dann Ihr mailcensus-Skript verwenden, um Ihre so gesammelten Daten m÷glicherweise tausendmal an joe@randomsite.com zu senden, wobei immer Ihr mailcensus-Skript verwendet wⁿrde; die Person k÷nnte Ihre Rechenzeit verbrauchen und den armen Joe mit Mails bombardieren; Joe wⁿrde sich irgendwann bei Ihnen beschweren, weil Sie den einzig identifizierbaren Header in der Mail darstellen. Um das zu verhindern, sollten Sie die E-Mail-Adresse im Skript festschreiben oder eine M÷glichkeit auf dem Server bereitstellen, die Adresse, an die die Mail gesendet wird, zu ⁿberprⁿfen.
Beispiel 2:
Ein Konvertierprogramm von RGB nach Hexadezimal
RGBtoHex ist ein Konverter, der drei RGB-Zahlen (0-255) entgegennimmt, und ein Hexadezimal-Tripel (#NNNNNN) zurⁿckgibt, das Sie beispielsweise fⁿr einen Netscape-Hintergrund oder andere bildverarbeitende Programme nutzen k÷nnen, die die Spezifikation von Farben auf diese Weise fordern.
Das Skript fⁿr die Umwandlung ist eigentlich ganz einfach. Die Konvertierung von ASCII in Hex ist keine schwierige Aufgabe. Aber dieses Beispiel ist in Perl geschrieben, und es bietet eine gute Einfⁿhrung in die umfassenderen Perl-Skripten im weiteren Kapitel.
Wie es funktioniert
Abbildung 20.4 zeigt das Formular fⁿr dieses Beispiel, das einige Bedienanweisungen sowie drei Textfelder fⁿr die Zahlen von 0 bis 255 enthΣlt.
Wenn Sie beispielsweise 155 155 155 eingeben (ein wunderbarer Grauton) und auf Submit Values drⁿcken, erhalten Sie das in Abbildung 20.5 gezeigte Ergebnis. Dieses Hexadezimal-Tripel k÷nnen Sie in Ihre HTML-Dateien oder in andere Programme kopieren.
Abbildung 20.4: |
Abbildung 20.5: |
Das Formular
Das Formular, das das Skript RGBtoHex aufruft, ist ganz einfach: drei Textfelder und die unumgΣnglichen SchaltflΣchen Submit und Reset, es sieht etwa so aus:
<HTML><HEAD>
<TITLE>RGBtoHex: an RGB to Hexadecimal Color Converter</TITLE>
</HEAD><BODY>
<H2>RGBtoHex</H3>
<P>RGBtoHex converts standard RGB values (three 0 to 255 ASCII numbers
indicating red, green, and blue), into a hexadecimal triplet that can
be used for the background and text colors in Netscape 1.1 or in any
other program that requires colors in this format.
<HR>
<FORM METHOD=POST ACTION="/cgi-bin/rgb.cgi">
<P>Please enter the RGB values for your color:
<P>Red (0-255): <INPUT TYPE="text" NAME="red"><BR>
Green (0-255): <INPUT TYPE="text" NAME="green"><BR>
Blue (0-255): <INPUT TYPE="text" NAME="blue"><BR>
<INPUT TYPE="submit" VALUE="Submit Values"><INPUT
TYPE="reset"
VALUE="Clear Values">
<HR>
</BODY></HTML>
Das einzige, was hier kommentiert werden soll, sind die Namen der Textfelder: red, green und blue. Sie ben÷tigen Sie fⁿr das Skript. Beachten Sie, da▀ der Name des Skripts rgb.cgi ist und sich im cgi-bin-Verzeichnis Ihres Servers befindet. Sie mⁿssen den ACTION-Teil Ihres Formulars dahingehend verΣndern, da▀ er auf Ihr eigenes Skript zeigt.
Das Skript
Fⁿr die Umwandlung der RGB-ASCII-Werte in ein Hexadezimal-Tripel wird ein einfaches Perl-Skript verwendet, das die Bibliothek cgi-lib.pl verwendet, um die Formularwerte zu decodieren. (cgi-lib.pl wurde im vorigen Kapitel beschrieben). Hier ein kurzer Einblick in das Skript:
Die erste Zeile zeigt, da▀ es sich um ein Perl-Skript handelt, im Gegensatz zu einem Bourne-Shell-Skript. Wenn Sie Perl auf Ihrem System nicht unter /usr/local/bin/perl gespeichert haben, dann sollten Sie die folgende Zeile modifizieren, so da▀ sie auf das Skript zeigt:
#!/usr/local/bin/perl
Wenn Sie nicht wissen, wo sich Perl in Ihrem System befindet, geben Sie am Systemprompt which perl ein. Wenn Perl installiert ist und sich in Ihrem Suchpfad befindet, erhalten Sie damit den Pfad-Namen fⁿr das Perl-Programm. |
Jetzt kommen zuerst die ganzen Initialisierungen, die fⁿr ein CGI-Skript notwendig sind.
require 'cgi-lib.pl';
&ReadParse(*in);
print "Content-Type: text/html\n\n";
#Top of HTML file
print "<HTML><HEAD>\n"
print "<TITLE>RGBtoHex: Results</TITLE></HEAD><BODY>\n";
print "<H2>RGBtoHex: Result</H2>\n";
print "<HR>\n";
Diese Zeilen erledigen drei Dinge:
Aber jetzt weiter zum eigentlich Interessanten. Wir k÷nnen kein Tripel erzeugen, wenn der Leser nicht in alle drei Textfelder Werte eingegeben hat. Deshalb ⁿberprⁿfen wir in diesem Abschnitt, ob bei der ▄bertragung des Formulars alle drei Werte eingetragen wurden.
In Perl erhalten Sie unter Verwendung von cgi-lib.pl die Wert-Komponente des Name-Wert-Tags, indem Sie auf den Namen des entsprechenden Arrays ($in) und den Namen des Namensschlⁿssels verweisen. $in{'red'} ergibt also den Wert, den der Leser in das Textfeld red eingegeben hat. Hier ⁿberprⁿfen wir alle Werte, um sicherzustellen, da▀ sie nicht leer sind, und melden gegebenenfalls einen Fehler zurⁿck.
if (($in{'red'} eq '') || ($in{'green'} eq
'') ||
($in{'blue'} eq '')) {
print "You need to give all three values!";
} else {
Und jetzt kommt's. Die Umwandlung des ASCII-Werts in Hex ist eigentlich ganz einfach. Sie k÷nnen das mit fast jedem wissenschaftlichen Taschenrechner bewerkstelligen, und in Perl wird dazu nur eine einfache Formatoption fⁿr die printf-Funktion verwendet (so wie in C). Aber zuerst wollen wir den ersten Teil ausgeben (der hier auf zwei Zeilen erscheint, sich aber in Ihrem Quellcode auf einer einzigen Zeile befinden sollte):
print "<p> RGB values of $in{'red'} $in{'green'} $in{'blue'} equals the hexadecimal value <B>";
Anschlie▀end kommen die Hexzahlen, was Perl mit einer einfachen printf-Anweisung erledigt. Dabei werden jeweils zwei Stellen fⁿr jede Komponente des Tripels ausgegeben:
printf
("#%2.2X%2.2X%2.2X\n",$in{'red'},$in{'green'},$in{'blue'});
}
Jetzt noch die abschlie▀enden HTML-Tags fⁿr das Dokument:
print "</B><BODY></HTML>\n";
Das ist alles. Speichern Sie das Beispiel als rgb.cgi, rufen Sie es auf, und los geht's!
Beispiel 3:
Ein Adre▀buch durchsuchen
Im dritten Beispiel verwenden wir ein komplexeres und umfangreicheres Skript. Wir fragen Informationen ab, die in einer Art Datenbank gespeichert sind - eigentlich in einer einfachen Textdatei, die auf dem Server liegt. Das Formular erlaubt die Eingabe von Schlⁿsselw÷rtern, nach denen gesucht werden soll. Das Skript gibt eine HTML-Datei mit ⁿbereinstimmenden DatensΣtzen zurⁿck.
Wie es funktioniert
Bei der Datenbank fⁿr dieses Beispiel handelt es sich eigentlich um eine einfache Textdatei, die lauter Adre▀daten enthΣlt. Jeder Datensatz bietet Informationen ⁿber eine einzelne Person, unter anderem Adresse, Telefonnummer, E-Mail usw. (Details ⁿber das Dateiformat finden Sie im nΣchsten Abschnitt.) Das Suchformular (siehe Abbildung 20.6) besteht aus mehreren Textfeldern, mit deren Hilfe Sie nach Schlⁿsselw÷rtern in beliebigen Abschnitten der Datenbank suchen k÷nnen.
Abbildung 20.6: |
Wenn das Formular ⁿbertragen wird, durchsucht das CGI-Skript die Adre▀datei und gibt alle gefundenen DatensΣtze zurⁿck, zusammen mit automatisch erzeugten Links fⁿr die E-Mail- und Homepage-Felder, wie in Abbildung 20.7 gezeigt.
Abbildung 20.7: |
Wenn Sie in mehreren Feldern des Formulars Suchinformationen eingeben, gibt das Suchskript alle DatensΣtze zurⁿck, die eines dieser Schlⁿsselw÷rter enthalten. Wenn Sie also in das Feld Name laura eingeben und in das Feld Email lne.com, prⁿft das Skript jeden Datensatz, ob er laura oder lne.com enthΣlt, und gibt dann alle DatensΣtze zurⁿck, die eines dieser Schlⁿsselw÷rter enthalten.
Die Datei
Bei der vom Formular durchsuchten Adre▀buchdatei handelt es sich um eine einfache Textdatei, die mehrere DatensΣtze fⁿr einzelne Personen enthΣlt, jeweils durch Leerzeilen voneinander abgetrennt. Diese DatensΣtze sehen etwa wie folgt aus:
Name: Laura Lemay
Address: 11 Palm Tree Lane, Brunford, CA 91234
Home Phone: (415) 555-5555
Work Phone: (415) 555-6666
Email Address: lemay@lne.com
Home Page: http://www.lne.com/lemay/
Jeder Datensatz setzt sich aus mehreren Feldern zusammen, unter anderem Name, Adresse usw. Der Feldname und der Feldinhalt sind jeweils durch einen Doppelpunkt getrennt. Felder, die keine Information enthalten, werden dennoch angezeigt, aber es erfolgt keine Wertangabe, dies sieht etwa so aus:
Name: Andrew Fnutz
Address: 5555555 SE North St. West Forward, ND 00554
Home Phone: (411) 555-8888
Work Phone:
Email Address: fnutz@loothmid.zurk.com
Home Page:
Die Adre▀daten befinden sich irgendwo auf dem Server, wo das Skript darauf zugreifen kann. Bei mir hei▀en sie address.data und befinden sich in meinem Web-Verzeichnis. Sie k÷nnen Ihr eigenes Adre▀verzeichnis erzeugen oder meines zu Testzwecken benutzen (Sie finden es auf der CD-ROM, die diesem Buch beiliegt). |
Das Formular
Das Formular zum Durchsuchen des Adre▀buchs ist ganz einfach - es besteht nur aus mehreren Textfeldern. Nichts Neues oder gar Aufregendes. Ich habe in diesem Beispiel vorformatierten Text verwendet, so da▀ die Felder alle in einer Reihe stehen.
<HTML><HEAD>
<TITLE>Address Book Search Forms</TITLE>
</HEAD><BODY>
<H1>WWW Address Manager</H1>
<P>Enter search values in any field.
<PRE><HR>
<FORM METHOD=POST ACTION="/cgi-bin/address.cgi">
<P><B>Name:</B> <INPUT TYPE="text" NAME="Name"
SIZE=40>
<P><B>Address:</B> <INPUT TYPE="text"
NAME="Address" SIZE=40>
<P><B>Home Phone:</B> <INPUT TYPE="text"
NAME="Hphone" SIZE=40>
<P><B>Work Phone:</B> <INPUT TYPE="text"
NAME="Wphone" SIZE=40>
<P><B>Email Address:</B> <INPUT TYPE="text"
NAME="Email" SIZE=40>
<P><B>Home Page: </B> <INPUT TYPE="text"
NAME="WWW" SIZE=40>
</PRE>
<INPUT TYPE="submit" VALUE="Search"><INPUT
TYPE="reset" VALUE="Clear">
<HR>
</FORM></BODY></HTML>
Das Skript
Jetzt weiter zum Skript address.cgi. Auch hier handelt es sich um ein Perl-Skript, das allerdings etwas komplizierter ist als das RGBtoHex-Skript. Aber auch dieses Skript beginnt mit den Zeilen zum Einbinden von cgi-lib.pl, decodiert die Formulareingabe und gibt den ersten Teil der Antwort aus.
#!/usr/local/bin/perl
require 'cgi-lib.pl';
&ReadParse(*in);
print "Content-type: text/html\n\n";
print "<HTML><HEAD><TITLE>Address Book Search
Results</TITLE></HEAD>\n";
print "<BODY><H1>Addresss Book Search Results</H1>\n";
Um das Adre▀buch zu durchsuchen, mu▀ das Skript wissen, wo sich dieses befindet. Die erste Zeile zeigt auf die Datei im lokalen Dateisystem, die die Daten enthΣlt. (─ndern Sie sie so ab, da▀ sie auf Ihre eigene Datendatei zeigt.) Die nΣchste Zeile ÷ffnet diese Datei zum Lesen (fⁿgen Sie hier den vollstΣndigen Pfad-Namen zu dieser Datei auf Ihrem eigenen System ein):
$data="/home/www/Web/Books/Examples/Professional/chap20/address/address.data";
open(DATA,"$data") || die "Can't open $data:
$!\n</BODY></HTML>\n";
Jetzt kommt das Schwierigste. Im nΣchsten (langen) Codeabschnitt, der in einer while-Schleife enthalten ist (while(<DATA>) {...}) werden die Daten in der Datei zeilenweise gelesen, wobei fⁿr jede Zeile mehrere ▄berprⁿfungen ausgefⁿhrt werden. Die gesamte Schleife erledigt mehrere Dinge:
Lassen Sie uns mit dem ersten Teil der while-Schleife anfangen und dann mit dem Befehl chop, der ⁿberflⁿssige nachfolgende neue Zeilen am Ende der aktuellen Zeile entfernt.
while(<DATA>) {
chop; # delete trailing \n
Innerhalb der while-Schleife fⁿhren wir verschiedene Tests aus. Die Schleife testet jede Zeile, um zu sehen, ob es ▄bereinstimmungen mit den Suchkriterien gibt. Sie testet auch, ob wir eine Leerzeile erreicht haben. Beachten Sie, da▀ die DatensΣtze in der Adre▀datei durch leere Zeilen voneinander abgetrennt werden; wenn die Schleife also eine Leerzeile findet, dann wei▀ sie, da▀ sie einen ganzen Datensatz gelesen hat. Im nΣchsten Code-Block werden wir wieder nach einer Leerzeile suchen und noch einen zusΣtzlichen Test ausfⁿhren, um herauszufinden, ob in diesem Eintrag bereits vorher ▄bereinstimmungen gefunden wurden. Wenn eine Leerzeile und eine ▄bereinstimmung gefunden werden, wird dieser Code-Block folgendes erledigen:
UnabhΣngig davon, ob eine ▄bereinstimmung gefunden wurde, zeigt die Anwesenheit einer Leerzeile an, da▀ das Ende eines Datensatzes erreicht wurde, so da▀ das Programm noch zwei weitere Aufgaben erledigt:
Und hier der Code, der auf eine Leerzeile und eine ▄bereinstimmung hin prⁿft, den Eintrag verarbeitet und dann alles wieder l÷scht:
if (/^\s*$/) { #blank line means end of
record
if ($match) {
# if anything matched, print the whole record
&printrecord($record);
$nrecords_matched++;
}
undef $match;
undef $record;
next;
}
Jetzt fⁿhren wir die eigentlichen ▄berprⁿfungen der Felddaten durch. Die Datendatei enthΣlt ihre Zeilen im Format Tag: Wert, beispielsweise Email: lemay@lne.com. Die nΣchste Codezeile trennt diese Information in zwei Komponenten auf und schreibt ihren Inhalt in die Variablen tag und value.
($tag,$val) = split(/:/,$_,2);
Und jetzt kommen die eigentlichen ▄berprⁿfungen. Es gibt sechs einzelne Tests (einen fⁿr jedes Feld: Name, Address, HomePhone, WorkPhone, Email und Homepage), aber da sie im wesentlichen alle gleich aussehen, werde ich hier nur zwei davon angeben. Die vollstΣndige Datei finden Sie auf der CD-ROM, falls Sie daran interessiert sind. |
Jede dieser Suchen ⁿberprⁿft die Variable tag, um festzustellen, ob wir gerade eine Zeile mit dem entsprechenden Feldnamen lesen. Wenn das der Fall ist, vergleicht das Skript den Wert der Zeile mit dem Suchschlⁿssel, den es gegebenenfalls fⁿr dieses Feld hat. Wenn das Skript eine ▄bereinstimmung findet, setzt es die Variable match. Egal aber, ob es eine ▄bereinstimmung findet, das Skript kopiert die Zeile auf alle FΣlle in das Array.
Hier die ▄berprⁿfungen fⁿr die Felder mit Name und Adresse:
if ($tag =~ /^Name/i) {
$match++ if( $in{'Name'} && $val =~ /\b$in{'Name'\b/i) ;
$record = $val;
next;
}
if ($tag =~ /^Address/i) {
$match++
if( $in{'Address'} && $val =~ /\b$in{'Address'}\b/i) ;
$record .= "\n<BR>$val" if ($val);
next;
}
Schlie▀lich gibt es ganz unten in der Schleife noch eine weitere Zeile. Wenn es in der Datendatei Zeilen gibt, die keinem Feld zugeordnet sind, wollen wir sie trotzdem beibehalten. Wenn wir also eine finden, kopieren wir sie einfach in das Array:
$record .= $_;
}
Nachdem die Schleife abgearbeitet ist und wir alles gefunden haben, was wir wollten, schlie▀en wir die Datendatei:
close DATA;
Was passiert, wenn keine DatensΣtze gefunden wurden? Sie wissen vielleicht noch, da▀ es am Anfang der Schleife eine Variable fⁿr nrecords_matched gab. Wenn wir einen ⁿbereinstimmenden Datensatz finden, setzen wir diese Variable. Wenn es also keine ⁿbereinstimmenden DatensΣtze gibt, wird sie niemals gesetzt. Hier ⁿberprⁿfen wir sie und geben eine Meldung aus, wenn sie nicht gesetzt ist:
if (! defined $nrecords_matched)
{ print "<H2>No Matches</H2>\n"; }
Jetzt noch die abschlie▀enden HTML-Tags:
print
"</BODY></HTML>\n";
exit;
Aber wir sind noch nicht ganz fertig. Der letzte Teil des Skripts enthΣlt eine Unterroutine, die den Datensatz in HTML-Format ausgibt.
sub printrecord {
local($buf) = @_;
print "<P>\n$buf\n";
}
Weitere Ideen
Dieses Beispiel war ganz einfach - einfach nur eine Datendatei und ein Suchskript. Ein paar weitere Skripten, und Sie k÷nnten Formulare entwickeln, die EintrΣge im Adre▀buch hinzufⁿgen, l÷schen oder modifizieren. Sie k÷nnten Formulare verwenden, die die Information in verschiedenen Layoutformaten zusammenfassen. Sie k÷nnten aber auch v÷llig abheben und ein Formular erzeugen, das fⁿr einen bestimmten Namen die Telefonnummer als Tonwahl ⁿber Ihren Lautsprecher ausgibt, so da▀ Sie Ihr Telefon an Ihren Lautsprecher halten und es wΣhlen lassen. Aber vielleicht auch besser nicht. Wenn man ⁿberlegt, wie lange es dauern wⁿrde, bis Sie Ihren Web-Browser gestartet, das Formular gefunden, den Namen eingetippt und auf die Antwort gewartet haben, k÷nnen Sie genausogut auch gleich selber wΣhlen. Jedenfalls soll dieses einfache Skript Ihnen nur einen Vorgeschmack davon geben, was Sie mit einer datenbankΣhnlichen Datei auf Ihrem Server anfangen k÷nnen.
Beispiel 4:
Ein GΣstebuch
Nachdem Sie nun die Perl-Skripts zur Genⁿge kennengelernt haben, wollen wir ein komplexeres Beispiel betrachten: eine GΣstebuchseite, auf der Ihre Leser Kommentare ⁿber Ihre Seiten abgeben k÷nnen. Das Skript fⁿr die Verarbeitung des GΣstebuchs trΣgt den Kommentar automatisch in eine Datei ein.
Wie es funktioniert
Wenn Ihre Leser Ihre erste GΣstebuchseite sehen, dann erhalten Sie etwa die in Abbildung 20.8 gezeigte Anzeige.
Abbildung 20.8: |
Jeder Eintrag im GΣstebuch zeigt den Namen, eine E-Mail-Adresse (das ist ein Link zum URL mailto:) sowie all die netten Dinge, die der Leser ⁿber Ihre Seiten sagen will. Ganz unten in der GΣstebuchdatei befindet sich ein Formular, in das die Leser ihre eigenen Kommentare einfⁿgen k÷nnen (siehe Abbildung 20.9).
Abbildung 20.9: |
Ihre Leser k÷nnen hier ihre Namen und E-Mail-Adressen sowie einige Kommentare (die gegebenenfalls auch HTML-Tags enthalten k÷nnen) einfⁿgen und dann POST anklicken. Das Skript aktualisiert die Datei und gibt eine BestΣtigung zurⁿck (siehe Abbildung 20.10).
Wenn der Leser zum GΣstebuch zurⁿckkehrt, wird sein Kommentar in die Liste aufgenommen (siehe Abbildung 20.11).
Abbildung 20.10: |
Abbildung 20.11: |
Anders als normale GΣstebuch-Applikationen hΣngt das CGI-Skript fⁿr dieses Formular den neuen Kommentar nicht nur am Ende einer Datei an. Es fⁿgt den neuen Kommentar in die Datei ein, aktualisiert das Datum, erzeugt die entsprechenden Verknⁿpfungen und formatiert alles wunderbar. Ein gutes Stⁿck CGI-Codierung!
Atmen Sie gut durch: Es wird lang und kompliziert. Wenn Sie irgendwo nicht mehr weiterkommen, blΣttern Sie einfach zurⁿck. Weil diese Dateien auch im Web vorliegen, k÷nnen Sie jederzeit auch das Original betrachten.
Das Formular fⁿr unser GΣstebuch
Der HTML-Code fⁿr das GΣstebuch ist im wesentlichen eine einfache HTML-Datei mit einem Formular am Ende. Damit das CGI-Skript erkennen kann, wie es die Datei aktualisieren soll, enthΣlt die HTML-Datei jedoch noch einige Extras, die wir hier detailliert erklΣren wollen.
ZunΣchst wieder die Standardangaben in HTML:
<HTML>
<HEAD>
<TITLE>Comments!</TITLE>
</HEAD>
</BODY>
Dieser HTML-Kommentar ist der erste in der HTML-Datei, der dem CGI-Skript helfen soll, alles dorthin zu schaffen, wo es hingeh÷rt. Der Kommentar GUESTBOOK teilt dem CGI-Skript mit, da▀ es sich wirklich um ein GΣstebuch handelt. Sie mⁿssen diesen Kommentar irgendwo in der HTML-Datei haben, weil Ihr Skript die Datei sonst nicht aktualisiert. Sie k÷nnen diesen Kommentar an einer beliebigen Stelle ablegen, aber ich habe ihn hier ganz vorne eingefⁿgt:
<!-GUESTBOOK->
Jetzt erzeugen wir einen einfachen Titel und einen Hinweis, da▀ hier das GΣstebuch beginnt:
<H1>Comments!</H2>
<P>Here are comments people have left about my pages.
Post your own using the form at the end of the page.
Nun wird eine kleine Statistik ⁿber die Datei eingefⁿgt. Der Kommentar LASTDATE teilt dem CGI-Skript mit, wo die neuen Daten eingefⁿgt werden sollen (er wird jedesmal aktualisiert, wenn jemand etwas in das GΣstebuch eintrΣgt).
Comments list started on Apr 4 1995
Last post on <!-LASTDATE->
Und nun erfahren Sie, wie der erste Eintrag aussieht (die Schablone hat diesen ersten Eintrag nicht). Alle EintrΣge in der HTML-Datei sehen diesem Σhnlich, mit einem Trennstrich, dem Namen des entsprechenden Schreibers, seiner E-Mail-Adresse als mailto-URL, dem Datum und dem eigentlichen Kommentar.
<HR><B>Laura Lemay <A
HREF=mailto:lemay@lne.com>lemay@lne.com
</A></B> Tue Apr 18 21:00:15 EDT 1995
<P>Test the guestbook...
Nach all den EintrΣgen in der Datei finden wir einen Kommentar namens POINTER. Er ist sehr wichtig, weil er dem CGI-Skript anzeigt, wo es neue EintrΣge einfⁿgen soll.
<!-POINTER->
Das Formular bildet den Rest der Datei:
<HR>
Post a response:
<BR>
<FORM METHOD=POST
ACTION="/cgi-bin/guestbook.cgi/lemay/examples/guestbook.html">
Name: <INPUT TYPE="text" NAME="name" SIZE=25 MAXLENGTH=25>
<BR>
Email address: <INPUT TYPE="text" NAME="address" SIZE=30
MAXLENGTH=30>
<BR>
Text:
<BR>
<TEXTAREA ROWS=15 COLS=60 NAME="body"></TEXTAREA>
<BR>
<INPUT TYPE=submit VALUE="POST">
<INPUT TYPE=reset VALUE="CLEAR">
</FORM> </BODY> </HTML>
Beachten Sie den Aufruf des CGI-Skripts im ACTION-Attribut. Das ist der wichtigste Bestandteil des Skripts, weil dem CGI-Skript hier mit Hilfe der Pfadinformation mitgeteilt wird, welche Datei aktualisiert werden soll. Sie k÷nnten den Namen der GΣstebuchdatei auch im CGI-Skript kodieren, aber auf diese Weise k÷nnen Sie mehrere GΣstebⁿcher verwenden, die mit Hilfe eines einzigen CGI-Skripts aktualisiert werden k÷nnen. Hier noch einmal die ACTION-Zeile:
ACTION="/cgi-bin/guestbook.cgi/lemay/examples/guestbook.html">
Der erste Teil dieser Zeile enthΣlt den Aufruf des Skripts (hier /cgi-bin/guestbook.cgi). Auf diese Weise wⁿrden Sie jedes beliebige CGI-Skript aus einem ACTION-Attribut heraus aufrufen. Sie werden diesen Teil umΣndern mⁿssen, so da▀ er auf guestbook.cgi zeigt, wo auch immer Sie es auf Ihrem Server installiert haben. Die restliche Zeile enthΣlt den Pfad fⁿr die eigentliche GΣstebuchdatei, wie sie im URL erscheint. Das ist sehr wichtig. Die Pfadinformation, die an den Skriptnamen angehΣngt wird, ist nΣmlich nicht der wirkliche Pfad-Name der Datei. Vielmehr handelt es sich um das URL, wobei das http: und der Hostname entfernt werden. Wenn das URL fⁿr Ihr GΣstebuch so aussieht:
http://myhost/mypages/stuff/guestbook.html
dann lautet der Teil daraus, der an den Skriptnamen angehΣngt wird:
/mypages/stuff/guestbook.html
Ist das URL gleich
http://myhost/~myname/stuff/guestbook.html
dann wird an die Datei das Folgende angehΣngt:
/~myname/stuff/guestbook.html
Vergessen Sie den anfⁿhrenden SchrΣgstrich nicht, wenn Sie in Ihrem URL eine Tilde (~) verwenden. Er ist wichtig! |
Es gibt noch etwas, das Sie bei der Installation dieser HTML-Datei auf Ihrem System wissen sollten: So wie bei den temporΣren Dateien im ersten Beispiel, mu▀ es dem Benutzer Nobody m÷glich sein, in die Datei zu schreiben, so da▀ das CGI-Skript die EintrΣge hinzufⁿgen kann. Das bedeutet, da▀ Sie fⁿr die HTML-Datei allen Schreibrechte gewΣhren mⁿssen.
Das Skript
Nun wollen wir das Skript betrachten. Es ist komplizierter als die bisher in diesem Abschnitt betrachteten Skripte, deshalb soll es zeilenweise erklΣrt werden.
Wir beginnen mit dem Standard-Perl-Code fⁿr die Decodierung von Daten und die Ausgabe des ersten Teils der HTML-Antwort:
#!/usr/local/bin/perl
require 'cgi-lib.pl';
&ReadParse(*in);
print "Content-type: text/html\n\n";
print "<HTML><HEAD>\n";
print "<TITLE>Post Results</TITLE>\n";
print "</HEAD><BODY>\n";
Das guestbook-Skript fⁿgt in jeden Eintrag ein Datum ein. Deshalb holen sich die beiden folgenden Zeilen das aktuelle Datum und schneiden am Ende die Neuzeile ab. Die Variable $date enthΣlt jetzt das Datum:
$date = 'date';
chop($date); # trim \n
In diesem Abschnitt ermittelt das CGI-Skript, wo sich die HTML-Datei befindet, in die es schreiben soll. Wissen Sie noch, da▀ Sie im ACTION-Teil des Formulars den Pfad fⁿr die Datei in das URL aufgenommen haben? Dieser Pfad wird in die CGI-Umgebungsvariable PATH_INFO geschrieben. Der Server ⁿbersetzt ihn in einen echten Dateisystem-Pfad-Namen und schreibt diesen Wert in die Umgebungsvariable PATH_TRANSLATED. Mit Hilfe des Werts von PATH_TRANSLATED kann das CGI-Skript feststellen, in welche Datei es schreiben soll:
$file = "$ENV{'PATH_TRANSLATED'}";
Au▀erdem ben÷tigen wir eine temporΣre Datei, um die Originaldatei im Fehlerfall nicht zu zerst÷ren. Die temporΣre Datei soll eindeutig (aber nicht zu eindeutig) sein. Warum? Wenn zwei Leute gleichzeitig etwas in das GΣstebuch eintragen, dann wollen Sie doch nicht, da▀ sie gegenseitig ihre EintrΣge ausl÷schen. Man kann nicht einfach nur die Proze▀-ID an die temporΣre Datei anhΣngen (wie wir es im ersten Skript gemacht haben): Das ist zu eindeutig! Statt dessen werden wir eine temporΣre Datei (in /tmp) au▀erhalb des Pfads zum eigentlichen GΣstebuch erzeugen, indem wir einfach alle SchrΣgstriche im Pfad durch Klammeraffen (@) ersetzen. Das ist ziemlich verrⁿckt, aber wir erhalten damit eine einzelne temporΣre Datei fⁿr jede GΣstebuchdatei, und genau das wollten wir:
$tmp =
"$ENV{'PATH_TRANSLATED'}.tmp";
$tmp =~ s/\//@/g; # make a unique tmp file name from the path
$tmp = "/tmp/$tmp";
Jetzt wollen wir die Eingaben aus dem Formular auswerten. Zuerst ⁿberprⁿfen wir, ob der Leser in alle Felder etwas eingetragen hat. Wenn das nicht der Fall ist, geben wir eine Fehlermeldung aus. Beachten Sie, da▀ &err ein Aufruf einer Perl-Unterroutine fⁿr die Fehlerausgabe ist. Die Definition dieser Unterroutine finden Sie am Ende des Skripts. Jetzt sollten Sie nur zur Kenntnis nehmen, da▀ sie existiert.
if ( !$in{'name'} || !$in{'address'} ||
!$in{'body'}) {
&err("You haven't filled in all the fields.
Back up and try again.");
}
Der Rumpf des Eintrags (der Teil, der sich im Textbereich des Formulars befand) mu▀ neu formatiert werden. Insbesondere wenn der Leser die Eingabe in einzelne Abschnitte untergliedert hat, sollten Sie diese (zwei Neue-Zeile-Zeichen in einer Zeile) jeweils durch ein Abschnitt-Tag ersetzen, so da▀ HTML sie erkennt. Dadurch erhalten wir m÷glicherweise mehrere <P>-Tags. Deshalb entfernt die letzte Zeile alle Duplikate:
$text = $in{'body'};
$text =~ s/\r/ /g;
$text =~ s/\n\n/<P>/g;
$text =~ s/\n/ /g;
$text =~ s/<P><P>/<P>/g;
Jetzt k÷nnen wir mit der Aktualisierung des GΣstebuchs beginnen. Zuerst versuchen wir, die zuvor benannte temporΣre Datei zu ÷ffnen. Erinnern Sie sich an den Hinweis, da▀ die temporΣre Datei nicht zu eindeutig sein darf? Hier werden Sie verstehen, warum. Bevor das Skript die temporΣre Datei ÷ffnet, prⁿft es, ob es bereits eine solche gibt. Wenn ja, dann erfolgt gerade ein anderer Eintrag in das GΣstebuch, und wir mⁿssen warten. Wir warten eine bestimmte Zeit lang. Wenn es zu lange dauert, nehmen wir an, es sei etwas schiefgelaufen, und beenden die Operation. Verstanden? Hier der Code:
for($count = 0; -f "$tmp";
$count++) {
sleep(1);
&err("Tmp file in use, giving up!") if ($count > 4); }
Wenn die temporΣre Datei noch nicht existiert, k÷nnen wir sie ÷ffnen, ebenso wie die Original-GΣstebuchdatei. Damit k÷nnen wir aus der Originaldatei lesen und in die temporΣre Datei schreiben. Kann die Datei nicht ge÷ffnet werden, wird in jedem Fall ein Fehler erzeugt, wie der folgende Code zeigt:
open(TMP,">$tmp") ||
&err("Can't open tmp file.");
open(FILE,"<$file") || &err("Can't open file $file: $!");
Die Dateien sind offen. Jetzt k÷nnen wir den Inhalt aus dem Original zeilenweise in die temporΣre Datei kopieren. Dabei prⁿfen wir fⁿr jede Zeile, ob sie einen fⁿr uns interessanten Kommentar enthΣlt. Wenn wir beispielsweise den Kommentar LASTDATE finden, geben wir ihn aus, gefolgt von dem aktuellen Datum (es wurde am Skriptanfang gesetzt):
while(<FILE>) {
if (/<!-LASTDATE->/)
{ print TMP "<!-LASTDATE-> $date \n"; }
Wenn wir den Kommentar GUESTBOOK finden, dann handelt es sich wirklich um eine GΣstebuchdatei. Das werden wir spΣter noch ⁿberprⁿfen, deshalb setzen wir hier die Variable guestbook:
elsif (/<!-GUESTBOOK->/) {
print TMP "<!-GUESTBOOK->\n";
$guestbook++;
}
Dort, wo wir den Kommentar POINTER finden, wird der neue Eintrag eingefⁿgt. Hier werden mehrere Schritte notwendig:
Und hier der Code:
elsif (/<!-POINTER->/) {
print TMP "<HR>";
print TMP "<B>$in{'name'} \n";
print TMP " <A HREF=mailto:$in{'address'}>
$in{'address'}</A></B>$date\n";
print TMP "<P> $text\n<!-POINTER->\n";
}
Wenn die ausgewertete Zeile keinen speziellen Kommentar enthΣlt, kopieren wir sie einfach nur vom Original in die temporΣre Datei.
else { print TMP $_; } # copy lines
}
Jetzt werten wir die guestbook-Variable aus, die wir in der Schleife gesetzt haben. Wenn die Datei den Kommentar GUESTBOOK nicht enthΣlt, war sie keine GΣstebuchdatei, und wir beenden unsere Operation hier, ohne die Originaldatei zu aktualisieren.
if (! defined $guestbook)
{ &err("not a Guestbook file!"); }
Schlie▀lich ersetzen wir die alte HTML-Datei durch die neue Version und l÷schen die temporΣre Datei:
open(TMP,"<$tmp") ||
&err("Can't open tmp file.");
open(FILE,">$file") || &err("Can't open file $file: $!");
while(<TMP>) {
print FILE $_;
}
close(FILE);
close(TMP);
unlink "$tmp";
Damit sind wir fast fertig. Wir geben nun noch die restliche HTML-Antwort aus. Beachten Sie, da▀ sie eine Verknⁿpfung zum Original-Pfad-Namen des GΣstebuchs enthΣlt (wie in der Umgebungsvariablen PATH_INFO angegeben), so da▀ die Leute noch einmal zurⁿckkommen und das Ergebnis betrachten k÷nnen:
print "<H1>Thank
you!</H1>";
print "<P>Your comment has been added to the ";
print "<A HREF=$ENV{'PATH_INFO'}>guestbook</A>\n";
print "</BODY></HTML>\n";
1;
Den letzten Teil des Skripts stellt die Unterroutine dar, die gegebenenfalls einen Fehler ausgibt. Ich werde sie hier zeigen, damit Sie sehen, was sie macht:
sub err {
local($msg) = @_;
print "$msg\n";
close FILE;
close TMP;
unlink "$tmp";
print "</BODY></HTML>\n";
exit;
}
Falls ein Fehler zu verarbeiten ist, dann werden im wesentlichen die folgenden Schritte ausgefⁿhrt:
Ideen
Warum nur ein GΣstebuch? Der hier beschriebene Aufbau k÷nnte auch zu einem Web-basierten Konferenzsystem oder einem Diskussionsforum erweitert werden.
Dieses GΣstebuch-Skript wurde ursprⁿnglich fⁿr ein gr÷▀eres HTML-Konferenzsystem namens htmlbbs geschrieben, das Sie in Kapitel 28 noch genauer kennenlernen werden. Wenn der Rahmen zum Hinzufⁿgen individueller Kommentare erst einmal errichtet ist, ist es nicht mehr so schwierig, den Rahmen so zu erweitern, da▀ er mit mehreren Themen gleichzeitig fertig werden kann.
Zusammenfassung
Im letzten Kapitel haben Sie die technischen Aspekte von CGI kennengelernt, ebenso, wie Sie Ihren Programmen ⁿber die CGI-Schnittstelle eine Interaktion mit dem Web-Server und dem Browser erm÷glichen k÷nnen. In diesem Kapitel haben wir vier Beispiele fⁿr Formulare und CGI-Skripten beschrieben:
Damit sollten Sie ⁿber genⁿgend Grundlagenwissen verfⁿgen, um Ihre eigenen Ideen fⁿr Formulare in echte interaktive Web-PrΣsentationen umsetzen zu k÷nnen.
Dabei sollten Sie erkennen, da▀ sich CGI nicht wesentlich von anderen Programmieraufgaben unterscheidet. Mit einem VerstΣndnis fⁿr Ihre Ziele und die Erwartung der Anwender ist es ganz leicht, zusΣtzliche Informationen fⁿr den Einsatz Ihres Programms im Web einzufⁿgen.
Alle Beispiele, die Sie in diesem Kapitel erforscht haben, finden Sie auf der CD-ROM und dem Web-Site (englisch) zu diesem Buch (http://www.lne.com/Web/). |
Fragen und Antworten
Frage:
Mir gefallen die Seiten, die ZugriffszΣhler darauf haben, auf denen so etwas Σhnliches steht wie: ╗Sie sind die 15.643. Person, die diese Seite seit dem 14. April besucht hat.½ Kann man dies mit einem CGI-Skript tun?
Antwort:
Sie haben schon etwas ⁿber ZugriffszΣhler in Kapitel 15, ╗Alles online verfⁿgbar machen½, gelernt, und es gab da auch einige Hinweise auf ÷ffentliche ZugriffszΣhler, die ohne CGI-Skripten funktionieren. Die Antwort auf Ihre tatsΣchliche Frage - nΣmlich, ob Sie ZugriffszΣhler mit Hilfe von CGI-Skripten verwirklichen k÷nnen - ist Ja, der einfachste Weg dazu besteht jedoch aus etwas, das Server-Includes genannt wird. Sie werden mehr ⁿber Server-Includes und darⁿber, wie Sie damit ZugriffszΣhler erzeugen k÷nnen, in Kapitel 27, ╗Web-Server: Hinweise, Tricks und Tips½, erfahren.
Frage:
Ich kann keines dieser Perl-Beispiele zum Laufen kriegen. Entweder bekomme ich leere Resultate, es werden keinerlei ▄bereinstimmungen gefunden, oder ich erhalte seltsame Fehler. Was geht hier vor?
Antwort:
Wahrscheinlich haben Sie cgi-lib.pl nicht an der richtigen Stelle. cgi-lib.pl ist eine Perl-Bibliothek und mu▀ als solche bei Ihrer Perl-Installation mit allen anderen Ihrer Perl-Bibliotheken installiert werden, meistens im Verzeichnis /usr/lib.perl. Es in Ihr cgi-bin-Verzeichnis zu stecken, funktioniert nicht - Perl wird nicht in der Lage sein, es zu finden. Sprechen Sie mit Ihrem Web-Master oder Systemverwalter darⁿber, wie Sie diese Bibliothek an der richtigen Stelle installiert bekommen, so da▀ Sie diese Skripten ausfⁿhren k÷nnen.
Frage:
Kann man ein CGI-Skript erzeugen, das Formulareingabe zulΣ▀t, mit der man eine gro▀e Datenbank so wie Oracle oder Sybase abfragen kann?
Antwort:
Ja, man kann. Aber CGI zu schreiben, das SQL ansprechen kann, ist eine zu komplexe Aufgabe fⁿr dieses Buch, so da▀ ich vorschlage, da▀ Sie mit Ihrer Datenbank-Firma sprechen oder einen Web-Index nach weiteren Informationen durchsuchen. Kapitel 30, ╗Verwaltung gro▀er PrΣsentationen und Sites½, gibt Ihnen ebenfalls noch eingehendere Informationen ⁿber Datenbanken und CGI.
Copyright ⌐1998 by SAMS, einem Imprint
der Markt&Technik Buch- und
Software-Verlag GmbH.
Elektronische Fassung des Titels: HTML 4 in 14 Tagen, ISBN: 3-8272-2019-X