Zum Inhalt springen

Apache/14 CGI/6 Perl

Aus Foxwiki
Version vom 28. April 2025, 10:22 Uhr von Dirkwagner (Diskussion | Beiträge) (Textersetzung - „z. B. “ durch „beispielsweise “)

Perl-Modul

Das Perl-Modul CGI.pm

Das Modul CGI.pm von Lincoln D. Stein, das schon seit langer Zeit zur Standarddistribution von Perl gehört, vereinfacht das Erstellen von CGI-Skripten erheblich. Zum einen gibt es eine standardisierte Methode zum Lesen von Formulardaten, zum anderen werden zahlreiche Funktionen geliefert, die das automatische Erstellen von HTTP-Headern und HTML-Elementen ermöglichen.

14.6.1 CGI.pm im Überblick

Zunächst einmal müssen Sie das Modul in Ihr Skript einbinden

  • Wie viele PerlModule besitzt CGI.pm zwei verschiedene Schnittstellen, eine objektorientierte und eine prozedurale
  • Da die objektorientierte Verwendung heute üblicher ist, wird sie automatisch aktiviert, wenn Sie das Modul folgendermaßen importieren
use CGI;

Um die prozedurale Schnittstelle freizuschalten, müssen Sie die use-Anweisung mit dem Tag :standard kombinieren

use CGI qw/:standard/;

Wenn Sie diese Option wählen, können Sie die von CGI.pm exportierten Grundfunktionen prozedural (aber natürlich auch weiterhin objektorientiert) aufrufen – beispielsweise param() zum Auslesen von Formulardaten

  • Wenn Sie nicht den vollen Funktionsumfang von CGI.pm benötigen, können Sie anstelle von :standard einige spezielle Funktionslisten oder sogar einzelne Funktionen importieren
  • Umgekehrt können Sie über andere Import-Tags auch noch Funktionalität hinzufügen

Die entsprechenden Optionen werden im Verlauf dieses Kapitels noch beschrieben

Während der Entwicklung eines CGI-Skripts sollten Sie auch noch folgende Zeile einfügen

use CGI::Carp qw/fatalsToBrowser/;

Das Modul CGI::Carp ermöglicht ein ähnlich elegantes Abfangen und Verfolgen von Fehlern wie Carp für Konsolen-Perl-Skripte

  • Das Pragma 'fatalsToBrowser'

sendet Fehlermeldungen direkt über den Webserver an den Browser, mit dem das Skript getestet wird

  • Auf diese Weise erhalten Sie sofort Feedback, wenn etwas nicht richtig funktioniert, und brauchen nicht zuerst das ErrorLog zu öffnen oder gar das ScriptLog einzuschalten
  • Wenn Sie das Skript gründlich genug getestet haben, sollten Sie die Zeile allerdings wieder entfernen (oder einfach auskommentieren)
  • Denn erstens verwirrt die Skriptfehlerausgabe gewöhnliche User Ihrer Website, und zweitens können Fehlermeldungen potenziellen Crackern wertvolle Hinweise über Schwachstellen des Skripts liefern

Wenn Sie sich für die objektorientierte Variante entschieden haben, dann müssen Sie als Nächstes ein CGI-Objekt erzeugen

Beispiel
my $cgi = CGI->new();

Anschließend werden alle CGI.pm-Funktionen als Methoden dieser Instanz aufgerufen, beispielsweise $cgi->param()

  • Das ist zwar einerseits etwas mehr Schreibarbeit, ermöglicht aber andererseits eine saubere Abgrenzung der CGI-spezifischen Anweisungen vom allgemeinen Perl-Code

Im restlichen Teil dieses Abschnitts gilt der Name $cgi ohne weiteren Hinweis als Referenz auf ein so erzeugtes CGI-Objekt

CGI::Pretty Wenn Sie CGI.pm zur Erzeugung von HTML-Code mit den im Folgenden beschriebenen Methoden einsetzen, werden Sie feststellen, dass der HTML-Code einfach ohne Zeilenumbrüche erzeugt wird

  • Einem Browser ist das völlig egal, aber es stört manchmal beim Debugging des ausgegebenen Codes
  • Wenn Sie umbrochenes und eingerücktes HTML benötigen, können Sie das Modul CGI::Pretty.pm von Brian Paulsen verwenden
  • Es gehört wie CGI.pm zum Lieferumfang von Perl und besitzt identische Funktionen
  • Nur der Import und die eventuelle Instanziierung sehen natürlich anders aus
use CGI::Pretty;
my $cgi = CGI::Pretty->new();

Leider wird die Pretty-Formatierung nur auf Standard-HTML-Elemente angewendet, nicht auf die speziellen Formularfunktionen

param() ist die wichtigste Methode (beziehungsweise Funktion) des gesamten Moduls

  • Sie liest Formulardaten aus und ermittelt dabei automatisch, ob diese mit GET oder mit POST versandt wurden; Sie brauchen sich nicht mehr selbst um dieses Detail zu kümmern
  • Selbstverständlich übernimmt sie auch gleich das Unescaping (Umwandlung aus der URL-Codierung in Klartext)
  • Mithilfe dieser Methode können Sie die Werte einzelner Formularfelder anhand ihres Namens lesen
  • Darüber hinaus liefert ein Aufruf von param() ohne Argumente ein Array mit den Namen aller übergebenen Formularfelder zurück
  • Angenommen, das aktuelle Skript wurde durch folgendes HTML-Formular aufgerufen
<form action="test.pl" method="get">
Name: <input type="text" name="user" />
Alter: <input type="text" name="age" />
</form>

Mit param ('user') können Sie den eingegebenen Benutzernamen prozedural ermitteln, mit $cgi->param ('user') objektorientiert

my $user = param('user'); # prozedural
my $user = $cgi->param('user'); # objektorientiert

Wenn Sie den nachfolgenden Code eingeben, wird die Liste der Feldnamen im Array @cgivars gespeichert

my @cgivars = param(); # prozedural
my @cgivars = $cgi->param(); # objektorientiert

Da der Unterschied zwischen prozeduraler und objektorientierter Syntax immer diesem Schema folgt, wird im Folgenden nur noch letztere Syntax verwendet

Die Liste der Feldnamen können Sie beispielsweise benutzen, um sämtliche Formularfelder in einen Hash einzulesen, in dem die Feldnamen die Schlüssel und ihre Einträge die Werte darstellen

  • Das folgende Beispiel liest sie in einen Hash namens %formfields ein
my @formnames = $cgi->param(); # Namen auslesen
my %formfields; # Hash deklarieren
foreach $name (@formnames) {
$formfields{$name} = $cgi->param ($name);
}

Beachten Sie, dass eine bestimmte Sorte von Formularfeldern auf diese Weise nicht vollständig gelesen wird: Einige Feldsorten können mehrere Werte enthalten; diese stehen in einem Perl-Skript als Array zur Verfügung

  • Es handelt sich konkret um Checkbox-Gruppen und Auswahlmenüs mit Mehrfachauswahloption
  • Betrachten Sie als Beispiel das folgende Formular
<form action="test.pl" method="get">
Welche Programmiersprachen setzen Sie ein?
<select name="plang" multiple="true">
<option value="perl">Perl</option>
<option value="java">Java</option>
<option value="csharp">C#</option>
<option value="cpp">C++</option>
<option value="vb">Visual Basic</option>
</select>

Was brauchen Sie zum Programmieren?

<input type="checkbox" name="pneed" value="cof" />Kaffee
<input type="checkbox" name="pneed" value="col" />Cola
<input type="checkbox" name="pneed" value="piz" />Pizza
<input type="checkbox" name="pneed" value="ice" />Eis
</form>

Bei beiden Fragen können mehrere Antworten zutreffen

  • Angenommen, jemand wählt aus dem Menü (mit gedrückter (Strg)-Taste) die beiden Sprachen Perl und Java aus und kreuzt die beiden Checkboxen Cola und Pizza an
  • Dann ist der Rückgabewert von $cgi->param('plang') und $cgi->param ('pneed') kein Skalar, sondern jeweils ein Array
  • Sollten Sie die Werte, wie bereits gezeigt, dennoch als Skalare auslesen, steht Ihnen nur jeweils der erste zur Verfügung
  • Um beispielsweise die Programmiersprachen korrekt auszulesen, müssen Sie also Folgendes schreiben
my @languages = $cgi->param('plang');

Ein weiterer praktischer Nutzen von $cgi->param() ohne Argumente ist die Überprüfung, ob überhaupt Formulardaten eingegeben wurden

  • Das ist besonders bei Formularen nützlich, die ihre Daten nicht an eine andere URL versenden, sondern an dasselbe Skript: Wenn noch keine Formulardaten übergeben wurden, handelt es sich offenbar um den ersten Aufruf des Skripts – eine Behandlung der Benutzereingaben kann nach einem Schema wie diesem entfallen
# Wurden Parameter übergeben?
if ($cgi->param()) {
# ..
* Behandlung der Eingaben
}

Die andere wichtige Aufgabe von CGI.pm besteht in der Bereitstellung zahlreicher Methoden, die den HTTP-Header und gängige HTML-Elemente ausgeben

  • Das folgende Beispiel definiert einen Standard-Header mit dem Content-Type text/

html

print $cgi->header;

Um die Werte von Header-Feldern anzupassen oder eigene zu setzen, wird das folgende Standardverfahren verwendet: Die einzelnen Felder werden als HashReferenz nach dem Muster -header_name => "Wert" angegeben – mit führendem Minuszeichen und Unterstrichen anstelle von Bindestrichen innerhalb der Feldnamen

  • Dieses Beispiel stellt anstelle von ISO-Latin-1 den für Türkisch verwendeten Zeichensatz iso-8859-9 ein und setzt den zusätzlichen Header ContentLanguage auf den Wert tr (Türkisch)
print $cgi->header
(-content_type="text/html; charset=iso-8859-9", -content_language="tr");

Sogar Cookies lassen sich auf diese Weise setzen

  • Die CGI-Methode cookie()

dient dabei sowohl zum Lesen als auch zum Schreiben des Cookies

  • Das folgende Beispiel versucht zunächst, ein zuvor gesetztes Cookie mit dem Namen lastvisit aus der Client-Anfrage zu lesen, bevor es dieses Cookie mit Datum und Uhrzeit neu setzt
# Cookie lastvisit lesen
my $readcookie = $cgi->cookie (-name => 'lastvisit');
# Datum und Uhrzeit
my $now = scalar localtime;
# Cookie lastvisit neu erzeugen
my $setcookie = $cgi->cookie (-name => 'lastvisit', -value => $now, -expires => '+7d', -path => '/');

Das Perl-Modul CGI.pm 14.6

  1. Header erzeugen und das neu erstellte Cookie setzen
print $cgi->header (-cookie => $setcookie);

Den Standardrahmen eines HTML-Dokuments können Sie mithilfe der beiden Methoden start_html und end_html ausgeben

  • start_html nimmt optional einen Titel als Argument entgegen
Beispiel
print $cgi->start_html ('Testseite');

Dies erzeugt den folgenden Teil des Ausgabedokuments

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml" lang="en-US"><head>
<title>Testseite</title>
</head><body>

Wenn Sie anstelle von XHTML lieber klassisches HTML 4.0 verwenden möchten, müssen Sie das Modul wie folgt mit dem Pragma -no_xhtml importieren

use CGI qw/-no_xhtml/; # objektorientiert

beziehungsweise

use CGI qw/:standard -no_xhtml/; # prozedural

end_html schließt den Rahmen des Dokuments ab und wird folgendermaßen aufgerufen

print $cgi->end_html;

Dies erzeugt folgende Ausgabe

</body></html>

Zur Erzeugung von HTML-Tags gibt es zwei unterschiedliche Ansätze, je nachdem, ob diese nur einfachen Text (beziehungsweise gar nichts) oder zahlreiche weitere Elemente umschließen

Zunächst einmal existiert für jedes HTML-Tag eine Methode (beziehungsweise Funktion), deren Name dem Tag entspricht

  • Beispielsweise wird eine

    -Überschrift folgendermaßen definiert

print $cgi->h1 ('Hauptüberschrift');

Noch einfacher funktioniert natürlich ein völlig leeres Tag wie der Zeilenumbruch

print $cgi->br();

Auch bei HTML-Tags werden Attribute nach dem oben gezeigten Schema verwendet, wenn auch mit einem kleinen Unterschied: Um Attribute von Inhalten eines Tags unterscheiden zu können, stehen die Attribute in einem anonymen Hash, der von geschweiften Klammern { ... } umschlossen wird

  • Das folgende Beispiel erzeugt ein <img>-Tag zum Einbetten des Bildes test.gif mit der Breite 200 Pixel, der Höhe 100 Pixel und dem Alternativtext Testbild
print $cgi->img ({-src => 'test.gif', -width => 200, -height => 200, -alt => 'Testbild'});

Enthält ein Tag Textinhalt, wird dieser als zweiter Parameter nach der Attributliste angegeben

  • Beispielsweise erzeugt diese Anweisung eine

    -Überschrift, die (auf veraltete Weise) zentriert dargestellt wird

print $cgi->h1 ({-align => 'center'}, 'Hallo Welt!');

Eine etwas größere Herausforderung stellen ineinander verschachtelte HTMLTags dar

  • Das folgende Beispiel erstellt eine Tabelle mit zwei Zeilen, die je zwei Zellen enthalten
print ($cgi->table({-border => '2', -cellpadding => '4'}, $cgi->Tr(
$cgi->td('Aktuelles 2.2-Release:'), $cgi->td('2.2.10'), ), $cgi->Tr(
$cgi->td('Aktuelles 2.0-Release:'), $cgi->td('2.0.63')));

Durch eine vernünftige Zeilenumbruch- und Einrückungspraxis, wie sie hier gezeigt wird, können Sie dennoch einigermaßen den Überblick behalten

  • Beachten Sie übrigens, dass Tr() großgeschrieben werden muss; der Name würde sonst mit dem Transliterationsoperator tr// in Konflikt geraten
  • Dasselbe gilt übrigens für Link() und Select()

Wie bereits erwähnt, gibt es für solche verschachtelten Tags auch noch eine andere Lösung: Sie können sie in eine start_*- und eine end_*-Methode aufteilen und erhalten auf diese Weise Folgendes

print $cgi->start_table({-border => '2', -cellpadding => '4'});
print $cgi->start_Tr;
print $cgi->td('Aktuelles 2.2-Release:');
print $cgi->td('2.2.10');
print $cgi->end_Tr;
print $cgi->start_Tr;

Das Perl-Modul CGI.pm 14.6

print $cgi->td('Aktuelles 2.0-Release:');
print $cgi->td('2.0.63');
print $cgi->end_Tr;
print $cgi->end_table;

Wie Sie sehen, wird Tr() in start_Tr() und end_Tr() aus Konsistenzgründen weiterhin großgeschrieben, obwohl hier natürlich keine Verwechslungsgefahr mehr besteht

Auf ähnlich einfache Weise lassen sich mittels CGI.pm HTML-Formulare erzeugen Neben den normalen HTML-Tags für Formulare und ihre Elemente, die durch die soeben gezeigten üblichen Methoden wie start_form(), end_form() oder input() erzeugt werden, gibt es etliche praktische Kurzfassungen: Beispielsweise erzeugt textfield() ein Texteingabefeld, für das Sie normalerweise input({type => 'text' ...}) schreiben müssten; ein anderes Beispiel ist die Methode radio_group(), die gleich eine ganze Gruppe von Radio-Buttons bereitstellt Genaueres erfahren Sie in den Beispielen und der Referenz im Folgenden

14.6.2 Beispiel: Ein kleiner Taschenrechner

Das kleine Beispiel in Listing 14.2 stellt ein Formular zur Eingabe zweier Zahlen und vier Radio-Buttons zur Auswahl einer der vier Grundrechenarten zur Verfügung. Ein Klick auf den des Berechnen-Button sendet die Formulardaten an das Skript selbst, das nun zusätzlich zur erneuten Anzeige des Formulars auch das Rechenergebnis (oder eine Fehlermeldung bei ungültigen Eingaben oder einer Division durch 0) anzeigt.

#!/usr/bin/perl -w
use strict;
use CGI;
use CGI::Carp qw/fatalsToBrowser/;

# CGI-Objekt erzeugen
my $cgi = CGI->new();

print $cgi->header;
print $cgi->start_html ("CGI-Rechner");
print $cgi->h1 ("Kleiner CGI-Rechner");

# Wurden Parameter übergeben?
if ($cgi->param()) {
my $zahl1 = $cgi->param ('z1');
my $zahl2 = $cgi->param ('z2');
my $op = $cgi->param ('op');
if (!test_num ($zahl1) || !test_num ($zahl2)) {
print "Fehler: Ungütiger Operand.";
} elsif ($op eq '/' && $zahl2 == 0) {
print "Fehler: Division durch 0.";
} else {
print "Ergebnis: $zahl1 $op $zahl2 = "
.eval ("$zahl1 $op $zahl2");
}
}
print $cgi->start_form (-method => "get");
print "1. Zahl: ";
print $cgi->textfield (-name => "z1");
print $cgi->br();
print "2. Zahl: ";
print $cgi->textfield (-name => "z2");
print $cgi->br();
print $cgi->br();
print "Operation: ";
print $cgi->radio_group (-name => 'op', -values => ['+', '-', '*', '/'], -default => '+');
print $cgi->br();
print $cgi->submit (-value => "Berechnen");
print $cgi->end_form;
print $cgi->end_html;

sub test_num
{
my $num = shift;
if ($num =~ /^\-?\d*\.?\d*$/) {
return 1;
}
return 0;
}

Listing 14.2 Ein kleiner CGI-Taschenrechner

Wenn Sie das CGI-Skript in ein CGI-fähiges Verzeichnis Ihrer Apache-Installation kopieren, die entsprechende URL (z.B. www.mynet.de/cgi-bin/calc.pl) in Ihren Browser eingeben und anschließend eine Berechnung ausführen, sollte das Ganze etwa so aussehen wie in Abbildung 14.2. Wie Sie sehen, ist ein durch CGI.pm erzeugtes Formular automatisch sticky, das heißt, die vor dem Absenden eingegebenen Formularwerte werden automatisch wieder in die entsprechenden Felder eingetragen.

Das Perl-Modul CGI.pm 14.6

Abbildung 14.2 Beispielberechnung des CGI.pm-Taschenrechners

Die meisten Informationen über die Funktionsweise des Beispiels haben Sie bereits weiter oben in der Einführung erhalten. Zusätzlich sind noch folgende Punkte anzumerken:

  • Das Skript ruft den Perl-Interpreter mit der Option -w (Warnings) auf. Dies

erzeugt zusätzliche Warnungen, die Auskunft über einen unsauberen Programmierstil oder mögliche Fehlerquellen geben. Bei gleichzeitiger Verwendung von CGI::Carp werden auch diese Warnungen im Browser angezeigt. Die Verwendung der Option -w ist grundsätzlich zu empfehlen.

  • Mithilfe von use strict wird die strenge Typüberprüfung eingeschaltet. Diese

Option verlangt, dass sämtliche Variablen vor der ersten Verwendung mit Gültigkeitsbereichen wie my, our oder local deklariert werden. In längeren Skripten verhindert dies z.B. das Auftreten logischer Ausführungsfehler durch falsch geschriebene Variablennamen – eine Fehlersorte, die sich sonst nur in sehr mühseligen Verfahren finden lässt.

  • Zur Berechnung des Ergebnisses der Rechenoperation wird die Funktion

eval() verwendet. Sie betrachtet den übergebenen String als Ausdruck und liefert dessen Ergebnis zurück. Dies erspart langwieriges Hantieren mit ifelse-Konstrukten. Voraussetzung ist natürlich, dass das Formular als Werte für die Rechenoperationen (die Radio-Button-Gruppe op) die eigentlichen Operatoren übergibt.

  • Wie Sie wahrscheinlich wissen, benötigen HTML-Formulare normalerweise

das Attribut action="URL", das die URL angibt, an die die Formulardaten verschickt werden sollen. Die Methode start_form() in diesem Beispiel besitzt dieses Attribut allerdings nicht. Das liegt daran, dass CGI.pm aus Bequemlichkeitsgründen automatisch die URL des aktuellen Skripts selbst einträgt, wenn Sie den Parameter weglassen.

  • Im Formular wird die Methode radio_group() verwendet, um die Radio-Buttons zur Auswahl der Rechenoperation zu erzeugen:

print $cgi->radio_group (-name => 'op', -values => ['+', '-', '*', '/'], -default => '+');

Der Parameter -name ist der gemeinsame Name aller vier Buttons. Das anonyme Array, das den Wert von -values bildet, enthält die Werte, die übermittelt werden, wenn der jeweilige Button ausgewählt wird – und legt damit auch gleich die Anzahl der Radio-Buttons in der Gruppe fest. Das optionale Argument -default gibt den Wert des Buttons an, der zu Beginn automatisch ausgewählt ist. Der erzeugte HTML-Code sieht mit diesen Optionen so aus:

<input type="radio" name="op" value="+" checked="checked" />+ <input type="radio" name="op" value="-" />-<input type="radio" name="op" value="*" />* <input type="radio" name="op" value="/" />/
<input type="submit" name=".submit" value="Berechnen" /> <input type="hidden" name=".cgifields" value="op" />

Wenn die Radio-Buttons anstelle der normalerweise verwendeten -value-Felder eine andere Beschriftung erhalten sollen, können Sie den Parameter -labels hinzufügen. Es handelt sich um einen anonymen Hash (oder eine Hash-Referenz), wobei die Feldwerte die Schlüssel und die gewünschten Beschriftungen die Elemente bilden. Mit einem anonymen Hash sieht die Anweisung für das Rechenoperationsbeispiel so aus:

print $cgi->radio_group (-name => 'op', -values => ['+', '-', '*', '/'], -labels => {'+' => 'Addieren', '-' => 'Subtrahieren', '*' => 'Multiplizieren', '/' => 'Dividieren'}, -default => '+');

Das Perl-Modul CGI.pm 14.6

Eigentlich besteht der Sinn des speziellen Trennsymbols => in einem Hash (neben der Verdeutlichung der Beziehung zwischen Schlüsseln und Werten) darin, dass die Anführungszeichen um die Schlüssel weggelassen werden können. Allerdings funktioniert das nicht, wenn die Schlüssel – wie hier – Symbole mit einer programmiertechnischen Bedeutung sind. Alternativ können Sie zuerst eine Hash-Variable erzeugen und dann als Wert von -labels eine Referenz darauf angeben:

my %labels = ('+' => 'Addieren', '-' => 'Subtrahieren', '*' => 'Multiplizieren', '/' => 'Dividieren'); print $cgi->radio_group (-name => 'op', -values => ['+', '-', '*', '/'], -labels => \%labels, -default => '+');

  • Die Subroutine test_num verwendet den folgenden regulären Ausdruck, um

zu ermitteln, ob das übergebene Argument eine Zahl ist:

/^\-?\d*\.?\d*$/

Dieses Muster lässt sich folgendermaßen zerlegen, um es zu erläutern:

  • ^ Textanfang
  • \-? ein Minus (–) oder auch keins
  • \d* beliebig viele Ziffern
  • \.? ein Punkt (.) oder auch keiner
  • \d* beliebig viele Ziffern
  • $ Textende

Eine kurze Übersicht über reguläre Ausdrücke finden Sie in Anhang G.

14.6.3 CGI.pm-Kurzreferenz

In diesem Abschnitt finden Sie eine Referenz der wichtigsten Bestandteile von CGI.pm: Import-Tags und -Pragmata sowie CGI- und Formularmethoden. Eine Übersicht über sämtliche HTML-Erzeugungsfunktionen ist dagegen nicht dabei, weil sie alle nach demselben, bereits besprochenen Schema funktionieren und den bekannten HTML-Tags entsprechen. Diese können Sie bequem online im Perl-Teil von SelfHTML (https://de.selfhtml.org/perl/module/cgi.htm) nachschlagen.

Importreferenz

Wie bereits erwähnt, gibt es eine Reihe spezieller Tags und Pragmata für den Import des CGI-Moduls. Diese werden hier kurz vorgestellt. Zunächst finden Sie in Tabelle 14.2 die verschiedenen Import-Tags für unterschiedliche Funktionslisten. Daneben können Sie auch immer einzelne Funktionen angeben, indem Sie einfach ihre Namen in die Importliste schreiben.

Tag Beschreibung

cgi Importiert CGI-relevante Methoden; vor allem param().
form Importiert die speziellen Formularmethoden wie radio_group() oder textfield().
html2 Importiert Methoden für HTML-2.0-Tags (grundlegender Satz von

HTML-Tags).

html3 Importiert zusätzliche Methoden für HTML-3.2-Tags.
html4 Importiert zusätzliche Methoden für HTML-4.0-Tags.
nets- Importiert zusätzliche Methoden für Netscape-HTML-Erweiterungen.

cape

html Importiert alle HTML-Methoden, also :html2, :html3, :html4 und
netscape.
stan- Importiert Standardfunktionen sowie alle HTML-, CGI- und Formularmethodard den.
all Importiert alle Methoden.

Tabelle 14.2 Import-Tags für die prozedurale CGI.pm-Programmierung

Beachten Sie, dass diese Funktionslisten nur für die prozedurale CGI.pm-Programmierung wichtig sind. Wenn Sie mit der objektorientierten Syntax auf das Modul zugreifen, stehen Ihnen über Ihre CGI-Instanz auf jeden Fall alle Methoden zur Verfügung.

In Tabelle 14.3 sehen Sie die diversen Pragmata, die jeweils ein spezielles Verhalten der CGI.pm-Methoden zur Folge haben. Im Gegensatz zu den Funktionslisten sind sie für beide Ansätze der CGI-Programmierung relevant.

Pragma Beschreibung -any Akzeptiert beliebige Formulierungen, die dem CGI.pm-Syntaxschema folgen, als auszugebende HTML-Tags (praktisch, falls browserspezifische Erweiterungen verwendet werden sollen, die normalerweise nicht integriert sind). -compile Kompiliert die importierten Methoden. Nützlich, wenn CGI-Skripte unter FastCGI oder mod_perl mehrfach ausgeführt werden.

Tabelle 14.3 Import-Pragmata, die das Verhalten von CGI.pm beeinflussen

Das Perl-Modul CGI.pm 14.6

Pragma Beschreibung -nosticky Formulare sollen nicht sticky sein: Daten werden nach dem Versand nicht mehr automatisch in die Felder eingetragen. -no_undef_params Verhindert HTML-Attribute ohne Wert wie readonly bei Formularfeldern. -no_xhtml Generiert klassisches HTML anstelle des normalerweise erzeugten XHTML. -nph Erzeugt No Parsed Header-CGIs (NPH), bei denen der Header nicht durch den Server manipuliert wird – Apache sendet noch nicht einmal die Statuszeile. -newstyle_urls Verwendet Semikola als Feldertrennzeichen in URL-codierten Formulardaten (altes Pragma; heute ohnehin Standard). -oldstyle_urls Verwendet Ampersands (&) anstelle von Semikola als Feldertrennzeichen. -autoload Gibt unbekannte Funktionen aus Skripten automatisch an CGI.pm weiter, sodass kein Funktionsimport nötig ist (verbraucht weniger Speicher). -no_debug Deaktiviert das alternative Einlesen von Parametern über Kommandozeilenparameter oder die Standardeingabe. -debug Aktiviert das alternative Einlesen von Parametern über Kommandozeilenparameter oder die Standardeingabe, um das Skript offline zu testen. -private_tempfi- Erschwert den sicherheitsgefährdenden Zugriff auf Upload-Dateien les über das lokale Dateisystem.

Tabelle 14.3 Import-Pragmata, die das Verhalten von CGI.pm beeinflussen (Forts.)

Kurzreferenz der CGI-Methoden Es folgt eine Übersicht über die wichtigsten CGI-Methoden des Moduls. Einige von ihnen haben Sie bereits weiter oben in ihrer praktischen Anwendung kennengelernt; hier finden Sie systematisch alle wichtigen Parameter dazu.

  • header(): Diese Methode sendet einen gültigen HTTP-Header. Standardmäßig

wird nur das Feld Content-Type gesetzt, normalerweise mit dem MIME-Type text/html. Darüber hinaus können Sie beliebige weitere Header setzen. Dazu müssen Sie den Namen des Headers klein und mit einem führenden Minuszeichen (–) schreiben; Trennstriche innerhalb des Feldnamens werden durch Unterstriche ersetzt. Aus Content-Type wird also beispielsweise -content_ type. Übrigens fügt Apache zu ausgegebenen Skripten standardmäßig noch die Header Date und Server hinzu. Neben den in Kapitel 2, Funktionsweise von Webservern, besprochenen HTTP-Antwort-Headern können Sie zusätzlich den speziellen Header-Schlüssel -status verwenden, um den (numerischen) Status der Antwort zu setzen. Bei einem korrekt ausgeführten CGI-Skript wird natürlich standardmäßig 200 OK gesendet, was in der Regel auch erwünscht ist. Einige Skripte erzeugen jedoch gar keine eigene Ausgabe, sondern führen nach getaner Arbeit eine Weiterleitung durch. Zu diesem Zweck könnten Sie den Status 303 See Other und einen -location-Header mit dem neuen Status senden:

print $cgi->header (-status => 303, -location => 'other.pl');
  • redirect(): Einfacher lässt sich die Weiterleitung mit der speziellen Methode

redirect() realisieren. Sie benötigt nur ein einziges Argument, nämlich die (absolute oder relative) URL des Weiterleitungsziels. Beispiel:

print $cgi->redirect ('other.pl');

  • cookie(): Die Methode cookie() dient sowohl zum Lesen als auch zum Erzeugen von Cookies. Das Lesen funktioniert, indem Sie den Namen des

gewünschten Cookies angeben, und muss vor dem Senden des Headers erledigt werden:

my $readcookie = $cgi->cookie (-name => 'Cookie-Name');

Um ein neues Cookie zu erzeugen, wird die Methode ebenfalls nach diesem Schema aufgerufen. Sie müssen mindestens ein -value-Feld hinzufügen, damit das Cookie einen sinnvollen Zweck erfüllt:

my $setcookie = $cgi->cookie (-name => 'Cookie-Name', -value => 'Cookie-Wert');

Alle Attribute, die ein Cookie erhalten kann, finden Sie in Tabelle 14.4.

Cookie-Attribut Beschreibung -name Name des Cookies (beliebig) -value Wert des Cookies (beliebige Zeichenkette) -path Pfad, für den das Cookie gelten soll. Standardwert: "/" – das bereits gesetzte Cookie wird an alle CGI-Skripte auf dem Server versendet. -domain Domain, für die das Cookie gelten soll. Besonders wichtig bei namensbasierten virtuellen Hosts, damit das Cookie nicht beim falschen Empfänger unter derselben IP-Adresse landet. -expires Verfallsdatum. Meist relativ im Format '+nEinheit', wobei folgende Einheiten möglich sind: Sekunden (s), Minuten (m), Stunden (h), Tage (d), Monate (M), Jahre (y). '+3d' bedeutet z.B. drei Tage Gültigkeit. Fehlt der Wert, gilt das Cookie nur für die aktuelle Browser-Session.

Tabelle 14.4 Attribute der CGI.pm-Methode cookie( )

Das Perl-Modul CGI.pm 14.6

Cookie-Attribut Beschreibung -secure Falls true, wird das Cookie nur gesetzt, wenn eine SSL-Verbindung besteht.

Tabelle 14.4 Attribute der CGI.pm-Methode cookie( ) (Forts.)

Denken Sie daran, dass Sie das Cookie nach der Erzeugung über den Header ausgeben müssen, damit es tatsächlich gesetzt wird:

print $cgi->header (-cookie => $setcookie);

  • start_html(): Die bereits erwähnte Methode start_html() erzeugt den

Beginn des HTML-Dokuments bis zum <body>-Tag inklusive. Wenn Sie lediglich ein einziges Argument angeben, wird es als Titel des Dokuments (<title> ... </title>) interpretiert. Alternativ können Sie nach dem bewährten Schema zahlreiche benannte Argumente angeben; die wichtigsten sehen Sie in Tabelle 14.5.4

Argument Beschreibung Beispiele -title die benannte Variante des Dokumenttitels -title => 'Testseite' -author Setzt ein link-Tag mit der E-Mail-Adresse -author => 'edides Autors. tor@mynet.de' -base Setzt das Tag <base href="aktuelle URL"> – -base => 'true' der Wert des Parameters ist egal. -target Vorgabeziel für Hyperlinks (praktisch bei -target => 'rightframe' Sites mit Frames) -style Stylesheets; -style => String: <style>-Block 'h1 {color: #0000FF}' Hash: externe CSS-Datei -style => {src => 'normal.css'} -meta Setzt Meta-Tags mit den in einem Hash ange- -meta => gebenen name/value-Paaren. {description => 'CGI-Test', keywords => 'Apache', 'CGI, Test'}

Tabelle 14.5 Argumente der CGI.pm-Methode start_html( )

4 Beachten Sie, dass externe CSS- und JavaScript-Dateien nicht in einem cgi-bin-Verzeichnis liegen dürfen, weil Apache versuchen würde, sie vor der Auslieferung auszuführen.

Argument Beschreibung Beispiele

-script JavaScript; -script => String: Code, der zwischen <script> und 'alert (\'Hallo, </script> im Head stehen soll Welt!\');' Hash: JavaScript aus externer .js-Datei -script => {-language => 'JavaScript', -src => 'myscript.js'} -onLoad JavaScript-Event-Handler im <body>-Tag -onLoad => 'alert (\'Startskript\');'

-BGCOLOR veraltete Grundfarbangaben für das <body>- -BGCOLOR => '#FF0000' -TEXT Tag (besser -style verwenden) usw.

Tabelle 14.5 Argumente der CGI.pm-Methode start_html( ) (Forts.)

  • end_html(): Diese Methode hat keine Parameter. Sie erzeugt den festgelegten

Text </body></html> für das Dokumentende.

  • url(): Mithilfe dieser Methode kann das Skript seine eigene URL ermitteln;

einige Parameter (jeweils mit dem Wert 1 oder einem anderen true-Wert) ermöglichen genauere Einstellungen. Hier die wichtigsten: -absolute gibt die absolute URL zurück, -relative dagegen die relative. Mit -query erhalten Sie zusätzlich die angehängten Parameter.

  • self_url(): Diese parameterlose Methode erzeugt die URL des aktuellen

Skripts mit allen zurzeit gesetzten Formularfeldern. Dies ist vor allem für seiteninterne Hyperlinks nützlich. Beispiel:

my $self = $cgi->self_url; print $cgi->a({-href => "$self#unten"}, 'Siehe unten'});

Kurzreferenz der Formularmethoden Im Folgenden finden Sie eine Übersicht über die wichtigsten Methoden zur Erzeugung von HTML-Formularen und ihren Elementen. Bitte beachten Sie, dass hier nur diejenigen Funktionen berücksichtigt werden, die nicht der normalen HTML-Syntax entsprechen. Die Entsprechungen der HTML-Tags stehen natürlich ebenfalls zur Verfügung, und nichts (außer der Tatsache, dass es unnötige Arbeit ist) hält Sie davon ab, eine Gruppe von Radio-Buttons folgendermaßen zu erzeugen:

Das Perl-Modul CGI.pm 14.6

print $cgi->h3 ('Was sind Sie?'); print $cgi->input ({-type => 'radio', -name => 'prog', -value => 'yes'}); print $cgi->b ('Programmierer'); print ' oder '; print $cgi->input ({-type => 'radio', -name => 'prog', -value => 'no'}); print $cgi->b ('Nichtprogrammierer');

  • start_form(): Durch diese Methode wird ein HTML-Formular eingeleitet.

Wenn Sie keine Parameter angeben, wird als Action-URL das aktuelle Skript selbst, als Methode POST und als Encoding-Type application/x-www-formurlencoded eingetragen. Bei Bedarf können Sie diese Angaben durch die benannten Parameter -action, -method und -enctype ändern. Für die JavaScript-Programmierung ist es obendrein nützlich, das Formular zu benennen; dies erledigt der zusätzliche Parameter -name. Beispiel:

print $cgi->start_form (-action => 'auswert.pl', -method => 'GET');

  • end_form(): Diese Methode gibt einfach </form> zurück.
  • textfield(): Erzeugt ein Texteingabefeld in einem Formular. Die möglichen

Parameter sind -name (der Feldname), -default (Vorgabewert), -size (sichtbare Zeichenzahl) und -maxlength (maximale Zeichenanzahl). Hier ein Beispiel:

print "Ihre E-Mail-Adresse: "; print $cgi->textfield (-name => 'mail', -size => 40, -maxlength => 80);

  • password_field(): Diese Methode besitzt dieselben Parameter wie

textfield(). Der Unterschied besteht darin, dass die Eingabe als *** dargestellt wird. Beispiel:

print "Ihr Kundenkennwort: "; print $cgi->password_field (-name => 'pass', -size => 20, -maxlength => 8);

  • filefield(): Mithilfe dieser Methode wird ein Datei-Upload-Feld erzeugt; die

Parameter sind wiederum identisch mit textfield(). Es ermöglicht Benutzern, zusammen mit dem Formular eine lokale Datei zu versenden. Beachten Sie, dass der Encoding-Type des Formulars dafür auf multipart/form-data gesetzt werden muss. Der eigentliche Upload funktioniert immer nach folgendem Schema:5

  1. Das Dateihandle aus dem Formularfeld lesen

my $file = $cgi->param ('dateifeld');

  1. Die Datei einlesen

while (my $line = <$file>) { chomp $line;

  1. Die eingelesene Zeile beliebig verarbeiten
  2. ...

}

  • popup_menu(): Diese Methode erzeugt ein Auswahlmenü. Die notwendigen

Parameter geben den Feldnamen (-name) und ein Array mit den Werten (-values) an. Zusätzlich können Sie noch einen Standardwert (-default) sowie einen Hash mit von den Werten abweichenden Beschriftungen (-labels) angeben. Beispiel:

print $cgi->h3 ("Welchen Webserver benutzen Sie?"); print $cgi->popup_menu (-name => 'webserver', -value => ['ap', 'ms', 'tc', xx'], -default => 'ap', -labels => {ap => 'Apache', ms => 'Microsoft IIS', tc => 'Tomcat', xx => 'Sonstige'});

  • radio_group() wurde weiter oben bereits im Beispiel verwendet. Die

Methode erzeugt eine Gruppe von Radio-Buttons. Es können alle Parameter von popup_menu() übernommen werden; die Bedeutung ist identisch. Zusätzlich können Sie noch das Argument -linebreak => 'true' verwenden, wenn Ihre Radio-Buttons untereinander und nicht nebeneinander stehen sollen. Mit -rows => $zeilenzahl und -cols => $spaltenzahl lassen sich die Buttons sogar automatisch in einer Tabelle anordnen. Das folgende Beispiel verwendet drei Zeilen mit je zwei Spalten:

print $cgi->h3 ("Unter welchem OS läuft Ihr Webserver?"); print $cgi->radio_group (-name => 'os', -value => ['lx', 'bsd', 'mox', 'ux', 'w32', 'xx'], -default => 'lx',

5 Binärdateien sollten Sie gegebenenfalls mit read() und nicht mit dem Zeilenoperator <> einlesen, um Ärger mit der Zeilenumbruchlogik zu vermeiden. Ein Beispiel für read() zeigt der kleine Perl-Webserver in Kapitel 2, Funktionsweise von Webservern.