xwolf.de|com

Menü

Inhalt dieser Site

Ansicht

Individuelle Benutzerkonfiguration für die Site.

Druckansicht Startseite Suchen

A A A A

CGI Tutorial - Teil 5 / 10

Wolfgang Wiese (www.xwolf.de, xwolf@xwolf.de), Juli 1998, Letzte Änderung: Mai 2003

[Das Common Gateway Interface]
[Übergabe von Benutzereingaben]
[Decodierung der übergebenen Daten]
[Schritt 1: Erstellung einer Eingabeform]
[Schritt 2: Die Programmierung]
[Schritt 3: Debugging eines CGI-Programmes]
[Standardfehler]
[Die Optimierung von CGI-Programmen durch Libraries und Module]
[Tipps, Tricks und Beachtenswertes]
[Links zu wichtigen FAQs und CGI-Seiten]

Schritt 2: Die Programmierung

Bevor wir blind losprogrammieren, sollten wir uns darüber Gedanken machen, was unser Programm genau machen soll. Wollen wir nur eine einfache Ausgabe an den Benutzer senden, oder wollen wir die Daten weiterverabeiten, ggf. speichern und/oder weitere Funktionen, die unsichtbar sind für den Benutzer, starten (z.B.: Logdateien, Mail versenden, Statistiken bearbeiten,...)?
Wir wollen annehmen, daß es unsere Aufgabe ist, einfach die eingegebenen Daten an eine Datei anzufügen und dem Benutzer eine Bestätigung zu senden.

Als strenger Informatiker würde man nun damit anfangen Struktugramme und Ablaufdiagramme, oder gar Automaten zu zeichen.
Da wir allerdings bereits genau wissen, was wir wollen, und auch das Programm selbst nur Daten entgegennehmen soll und diese dann zu speichern, sparen wir uns das und gehen gleich in die Materie!

Ein Perl-Programm sieht in der Regel folgendermaßen aus:


#!/usr/bin/perl
(Kommandos)

Die erste Zeile weist den Perl-Interpreter an, den darauf folgenden Programm-Code abzuarbeiten.
Kommentare müssen durch ein vorlaufendes '#' ausgewiesen werden. Dies gilt aber nur bedingt für das '#' in der ersten Zeile. Man sollte nicht auf die Idee kommen, es wegzumachen.
Sollte man in einem Team arbeiten, oder das Programm weitergeben wollen, sollte man außerdem Kommentarzeilen einfügen, in denen steht, was man macht, und warum. Jedoch dies auch nur in Maßen. Ein Programm, das zu viele Kommentare hat, ist genauso unübersichtlich, wie eines, welches keine hat.

Im ersten Teil unseres CGI-Programmes sollten wir die Eingaben den Benutzers entgegennehmen. Dies können wir mit dem oben beschriebenen Code machen:


#!/usr/bin/perl5
# simpleform.cgi Version 1.0
# Dieses Skript nimmt Eingaben aus einer Form entgegen, 
# fügt sie an eine vorgegebene Datei an, und zeigt 
# dem Benutzer nochmals, was er eingegeben hat.

$dateiname = 'umfrage.dat';
# In die Datei mit den Namen 'umfrage.dat' werd ich 
# meine Daten speichern.

if ($ENV{'REQUEST_METHOD'} eq "GET") { 
    $buffer = $ENV{'QUERY_STRING'}; 
} else { 
    read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); 
}
# Nehme Daten entgegen und kopiere sie in die 
# Variable $buffer

@nvpairs = split(/&/,$buffer);
# Ich teile den Datenstring in einzelne Teile.
foreach $pair (@nvpairs) { 
    # Ich decodiere jedes der Teil
    ($name, $value) = split(/=/, $pair);
    $value =~ tr/+/ /;
    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
    $in{$name} = $value;
}	

Jetzt fehlen uns noch 2 Teile: Die Ausgabe an den Benutzer und das Sichern der Daten in eine Datei.
Damit der Benutzer eine Ausgabe erhät, müssen wir eine HTML-Datei generieren, die dann vom Server an den Browser gesandt wird. Außerdem müssen wir dem Web-Server sagen, daß wir auch wirkllich ein HTML-Dokument senden.
Dies machen wir, indem wir dem Web-Server melden, daß die darauf folgende Information vom Type "Text/HTML" ist. Die Syntax dieser Meldung ist eindeutig festgelegt:

Content-type: text/html

Wichtig dabei ist die Leerzeile. Genauer gesagt: 2 Zeilenumbrüche hinter "text/html". In Perl wird ein Zeilenumbruch mittels des Zeichens "\n" angegeben.
Neben diesem Typ gibt es noch viele andere, so z.B. auch "Location: URL", welches ein Redirecten (Weiterleiten) zu einer anderen Seite erlaubt.

Nachdem man die Content-Type gesendet hat, kann man das HTML-Dokument generieren. Bei unseren Beispiel reichen ein paar einfache print-Befehle:


print "Content-type: text/html \n\n";
# Sendet an den Web-Server den Content-type.

print "<HTML><HEAD>\n";
print "<TITLE>Umfrageauswertung</TITLE> \n";
print "</HEAD> \n";
print "<h2>Vielen Dank für Ihre Informationen.</h2>\n";
print "Sie gaben ein:<hr><dl>\n";
print "<dd>Ihr Lernerfolg war $in{'Lernerfolg'}\n";
print "<dd>Das Tempo der Vorlesung war $in{'Tempo'}\n";
print "<dd>Ihre Vorkenntnisse waren $in{'Vorkenntnisse'}\n";
print "<dd>Ihr Kommentar:<br> $in{'Kommentar'}\n";
print "<p>";
if (($in{'Tempo'} eq 'zu langsam') 
&& ($in{'Lernerfolg'} eq 'nichts')) {
    print "<br>Du fauler Sack!<br>\n";
}
# No comment here :))

Nachdem man erstmal die Content-Type gegeben hat ist man nicht verpflichtet innerhalb der Print-Befehle ein Zeilenumbruch zu senden ("\n"). Dennoch ist dies ratsam für das Debugging: Sollte Ihr Skript durch einen dummen Fehler etwas seltsames Ausdrucken, ist es mitunter angebracht, den Source-Code des HTML-Dokuments anzusehen. Dort sieht man dann natürlich nicht den CGI-Programmcode, sondern nur den vom Perlskript fabrizierten HTML-Code. Sprich: Die Zeilen, die mittels print ausgegeben wurden mit Ausnahme der Zeile mit dem Content-Type.
Hat man allerdings innerhalb des CGI-Programmes keine Zeilenumbrüche mitgegeben, wird der Source-Code recht un&uumbersichtlich sein, da der gesamte Code in einer einzigen Zeile sein wird.
Sie tun sich also selbst einen Gefallen, wenn Sie die Zeilenumbrüche einfügen.

Im letzten Teil unseres CGI-Programmes wollen wir die Daten speichern.
Dazu müssen wir die Datei öffnen und dann die Daten anfügen:


open(filehandle,">>$dateiname") 
|| &Fehlermeldung("Kann die Datei $dateiname nicht öffnen!");
print filehandle "-------Neuer Eintrag-------\n";
print filehandle "Lernerfolg = $in{'Lernerfolg'}\n";
print filehandle "Tempo = $in{'Tempo'}\n";
print filehandle "Vorkenntnisse = $in{'Vorkenntnisse'}\n";
print filehandle "Kommentar: $in{'Kommentar'}\n\n";
close filehandle;

print "</HTML>\n";
# Wir schliessen das HTML-Dokument
exit(0);
	

Das Vorgehen dürfte im Prinzip klar sein. Was einer Erwähnung Bedarf ist die erste Zeile.
In Perl liefert das open() true, wenn es erfolgreich war, und false, wenn es nicht ausgeführt werden konnte. Ein Wert oder eine Funktion, die ein boolsches Ergebniss abliefert kann aber mit einer Abfrage verknüpft werden.
In der ersten Zeile wird also wenn das open() fehlschlug die Subroutine Fehlermeldung() ausgeführt, welche wir noch zu definieren haben.
In der letzten Zeile haben wir zusätzlich noch ein exit() gemeldet. Wenn das Programm an diese Stelle ankommt wird es beendet. Der Wert, der in der Klammer angegeben wird, ist der Return-Wert, den die Funktion zurückliefert. Dieser wird aber in der Regel bei CGI-Programmen nicht verwendet.

Wir sind jetzt fast am Ende des Programmes. Alles was wir noch tun müssen ist die von uns eingeführte Subroutine zu definieren:


sub Fehlermeldung {
    my $text= shift;
    print "<P><center>Es ist ein Fehler aufgetreten:<br>";
    print "$text\n";
    print "</center>";
    print "<p>Programm wird abgebrochen.\n";
    print "</HTML>\n";
    exit(1);
}
	

Subroutinen können in einem Perl-Programm fast an jeder Stelle abgelegt werden. 2 Möglichkeiten haben sich aber gut bewährt: Subroutinen werden entweder ganz am Anfang, oder ganz am Ende des CGI-Programmes abgelegt.
Ich selbst hab es mir angewöhnt am Anfang des Programmes Globale Variablen festzulegen, und die Subroutinen am Ende des Programmes abzulegen. So brauch ich nicht durch einen Wust an Subroutinen zu scrollen, um irgentwann endlich zu meinen Programmrumpf zu kommen.



Info

© 1996 - 2003 by xwolf