Perl/CGI

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Inhaltsverzeichnis

[Bearbeiten] HTTP-Header und Inhalte senden

Ein CGI-Script wird vom Webserver aufgerufen, sobald ihm der anfragende Browser eine Aufforderung dazu etwa durch das Abschicken eines Formulars signalisiert. Dazu kommuniziert zunächst der Browser mit dem Webserver über das HTTP-Protokoll und fordert das Script an. Bei dieser Anforderung kann der Browser auch gleich Daten versenden, die für das CGI-Script gedacht sind, z.B. Daten aus einem ausgefüllten HTML-Formular. Der Webserver entscheidet, ob es sich bei der vom Browser angeforderten Datei um ein CGI-Script handelt und lässt das Script vom Perl-Interpreter ausführen. Während dies geschieht, "wartet" der Browser jedoch auf Daten. Denn wenn der Browser vom Server ein CGI-Script anfordert, ist das für ihn nichts anderes, als ob er eine statische HTML-Datei anfordern würde. Er wartet auf Daten, die der Server sendet und die er (der Browser) als nächstes anzeigen soll. Deshalb muss der Script-Interpreter unmittelbar bei der Auswertung eines CGI-Scripts irgendetwas an den Webserver schicken, damit der es an den wartenden Browser weitersenden kann. Die zu sendenden Daten müssen dabei wieder über das HTTP-Protokoll verschickt werden. Das HTTP-Protokoll verlangt nun für jeden Datenversand einen so genannten HTTP-Header. Das ist eine Art Vorab-Datenpaket mit Informationen zu den nachfolgenden Daten. Damit ein Browser die Daten korrekt interpretieren kann, muss das Script also zunächst die Sendung eines gültigen HTTP-Headers veranlassen.

Beispiel
#!/usr/bin/perl -w
 
use strict;
use CGI::Carp qw(fatalsToBrowser);
 
my $Text = "Hallo Welt";
 
print "Content-type: text/html\n\n";
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n";
print "<html><head><title>Hallo Welt</title></head><body>\n";
print "<h1>$Text</h1>\n";
print "</body></html>\n";
Für den HTML-Code, den ein Perl-Script als CGI-Script ausgeben lassen soll, ist die Perl-Funktion print geeignet. Zum "Senden" gibt das Perl-Script einfach mit der print-Funktion Daten aus. Die erste dieser print-Anweisungen, die ein CGI-Script enthalten muss, ist jedoch diejenige für den HTTP-Header. Die einfachste Form eines HTTP-Headers besteht schlicht aus dem Befehl Content-type: und der Angabe eines MIME-Typs für die nachfolgenden Daten. Da das CGI-Script HTML-Code an den Browser senden will, benutzt es den MIME-Typ für HTML, nämlich text/html. Weiterhin muss ein HTTP-Header zwei abschließende Steuerzeichen für Zeilenumbruch enthalten. In Perl lässt sich ein solcher Zeilenumbruch durch die Zeichenfolge \n erzeugen. Durch die Anweisung:
print "Content-type: text/html\n\n";
wird also ein vollständiger HTTP-Header erzeugt, der dem Browser signalisiert, dass Daten vom Typ HTML folgen. Für eine vollständige HTTP-Kommunikation sind freilich noch mehr HTTP-Headerzeilen notwendig; die fehlenden Angaben werden dann von der CGI-Schnittstelle bzw. vom Webserver ergänzt.

Anschließend wird mit einzelnen print-Anweisungen eine vollständige kleine HTML-Datei an den Browser gesendet. Bei den einzelnen print-Anweisungen ist am Ende übrigens immer ein Zeilenumbruch-Zeichen \n notiert. Dies hat eher kosmetische Gründe. Dadurch wird im erzeugten HTML-Quelltext jeweils eine neue Zeile begonnen. Wenn diese Steuerzeichen fehlen würden, dann würde Perl den gesamten HTML-Code in eine Textzeile schreiben, und falls Sie sich diesen Quelltext in Ihrem Browser anschauen möchten, sehen Sie einen absatzlosen Brei aus Buchstaben und Zahlen, der sehr schwer lesbar ist. Bei der Variante oben wird der HTML-Quelltext dagegen nach jeder print-Anweisung umbrochen.

Innerhalb der h1-Überschrift wird im obigen Beispiel eine Variable ausgegeben, nämlich der Skalar $Text. Sie können innerhalb von print-Ausgaben einfach solche Variablen einfügen. An der entsprechenden Stelle wird dann der aktuelle Wert der Variablen ausgegeben. Im obigen Beispiel wird dem Skalar $Text weiter oben im Script der Wert Hallo Welt zugewiesen. Dieser Wert wird an der Stelle, wo $Text im auszugebenden HTML-Code notiert ist, eingesetzt.

[Bearbeiten] Inhalte senden (alternative Form)

Die vielen einzelnen print-Anweisungen sind bei längeren Ausgaben lästig. Es gibt deshalb auch eine elegantere Form der Ausgabe größerer HTML-Code-Abschnitte.

Beispiel
#!/usr/bin/perl -w
 
use strict;
use CGI::Carp qw(fatalsToBrowser);
 
my $Einleitung = "Es geht auch so!";
 
print "Content-type: text/html\n\n";
 
print <<"ENDE";
<html><head><title>Testausgabe</title></head><body>
<h1>$Einleitung</h1>
<p>Der Vorteil bei dieser Form ist, dass man viel HTML-Code
auf einmal erzeugen kann, ohne einen einzigen weiteren print-Befehl
in Perl zu notieren. Praktisch beispielsweise auch zum Ausgeben
von JavaScript:</p>
<script type="text/javascript">
document.write("<p>Und die Adresse dieser HTML-Datenquelle lautet: ");
document.write(document.URL+"<\/p>");
</script>
</body></html>
ENDE
Das Script sendet zunächst mit einer einzelnen print-Anweisung den HTTP-Header. Anschließend wird jedoch eine elegantere Methode benutzt, um größere Mengen HTML-Code zu senden. Dabei wird zunächst die Anweisung print <<"ENDE"; notiert. ENDE ist ein frei vergebbarer Name für einen Endbegrenzer. Ganz unten im Script ist dann noch einmal das Wort ENDE notiert, und zwar alleinstehend in einer Zeile. Alles, was zwischen der einführenden Anweisung und dem alleinstehenden Endbegrenzer steht, wird so wie es da steht an den Browser gesendet. Sinnvoll ist diese Form der Notation, wenn längere Abschnitte HTML-Code gesendet werden sollen. Der HTML-Code kann alles mögliche enthalten, zum Beispiel auch JavaScript-Bereiche, wie im Beispiel gezeigt, aber auch Perl-Variablen! Diese werden interpoliert, d.h. bei der Ausgabe durch ihren Wert ersetzt - allerdings nur, weil print <<"ENDE"; mit doppelten Anführungszeichen notiert wurde. Erlaubt ist auch die Notation mit einfachen Anführungszeichen, also print <<'ENDE';. In diesem Fall werden keine Perl-Variablen interpoliert (siehe auch: Regeln beim Notieren von Zeichenketten). Eine weitere Möglichkeit besteht darin, die Anführungszeichen ganz wegzulassen, also print <<ENDE;. In diesem Fall gelten dieselben Regeln wie bei der Notation mit doppelten Anführungszeichen.
Beachten Sie: Hinter dem Endbegrenzer muss in Ihrem Script auf jeden Fall ein Zeilenumbruch notiert werden, gerade auch dann, wenn es sich um die letzte Zeile im Script handelt.

Eine weitere oft genutzte Möglichkeit, HTTP-Header und HTML-Code an den Browser zu senden, bietet das CGI-Modul an. Dieses Modul stellt eigene Methoden bereit, um (X)HTML-Ausgaben zu erzeugen. Zum Senden an den Browser wird aber auch dort die print-Funktion verwendet.

[Bearbeiten] CGI-typische Lösungen in Perl

Perl wurde, anders als etwa PHP oder ASP, nicht speziell für Web-Anwendungen konzipiert, sondern als eine offene Programmiersprache für scriptbasierte Lösungen aller Art. Es hat jedoch Eigenschaften, die es als Sprache für CGI-Scripts qualifizieren: dazu gehören die mächtigen Funktionen für Zeichenkettenverarbeitung und Datei-Handling, aber auch die vielen Unix-spezifischen Funktionen, von denen auch in Perl geschriebene CGI-Scripts, die auf typischen Web-Server-Umgebungen wie Linux und Apache zum Einsatz kommen, profitieren können. Durch das Modulkonzept von Perl gibt es mittlerweile außerdem Module, die sich speziell für die Verwendung in CGI-Scripts anbieten - allen voran das CGI-Modul, das bei jeder Standard-Installation von Perl zur Verfügung steht. Mit den Möglichkeiten dieses Moduls sollten Sie sich auf jeden Fall näher befassen, wenn Sie CGI-Scripts schreiben.

Wenn Sie noch unsicher sind in Perl und sich nicht in der Lage sehen, eine CGI-Anwendung von Grund auf nach eigenen Vorstellungen zu programmieren, dann können Sie auf zahlreiche Scripts zurückgreifen, die im Web verfügbar sind. Es gibt viele Anbieter, die Freeware-Scripts oder Shareware-Scripts zur Verfügung stellen. Um ein solches Script auf Ihrem Server oder in Ihrer lokalen HTTP-Umgebung zum Laufen zu bekommen und die Anwendung so zu gestalten, dass sie Ihren Vorstellungen entspricht, müssen Sie sich allerdings mit dem Quelltext des Scripts auseinandersetzen und die angewendete Programmierlogik des fremden Script-Entwicklers nachvollziehen können. Wenn Sie Glück haben, ist das Script Ihrer Wahl sauber dokumentiert, und es ist nicht schwer, es für eigene Zwecke anzupassen. Häufig allerdings stoßen Sie in solchen Scriptarchiven auch auf völlig veraltete Angebote! Im Link-Verzeichnis des selfhtml-WIKI finden Sie eine Übersicht mit Anbietern fertiger CGI-Scripts in Perl und anderen Sprachen:

Perl/Links

Im folgenden werden einige typische Anwendungsgebiete von CGI-Scripts angeschnitten. Es wird beschrieben, wie der prinzipielle Programmablauf eines entsprechenden Scripts aussieht, und welche Perl-Bestandteile dazu erforderlich sind. Die Beschreibungen enthalten Verweise zu den Stellen, an denen Sie weitere Details finden.

[Bearbeiten] Counter (Zugriffszähler)

Ein Counter ist entweder grafisch oder textbasiert. Bei einem grafischen Counter wird das CGI-Script aus HTML heraus mittels eines <img>-Tags aufgerufen - Beispiel (HTML):

<img src="/cgi-bin/counter.pl" alt="Counter">

Bei einem textbasierten Counter geschieht der Aufruf meistens mit Hilfe von Server Side Includes - Beispiel (HTML):

<!--#exec cgi="/cgi-bin/counter.pl"-->

Das aufgerufene Script muss dann zuerst die Datei mit dem aktuellen Zählerstand auslesen, den Zählerstand um 1 erhöhen und den neuen Zählerstand wieder in die Datei zurückschreiben. Dafür gibt es in Perl die Funktionen für Ein-/Ausgabe und Lesen/Schreiben von Daten. Wenn es ein textbasierter Counter ist, kann das Script den Zählerstand z.B. mit einem HTTP-Header mit dem MIME-Typ text/html ausgeben, der die Zahl an der Stelle der Server-Side-Include-Anweisung einfügt. Bei einem grafischen Counter muss das Script eine Grafik vom Typ GIF, PNG oder JPEG zurückgeben, da der Browser im <img>-Tag etwas Entsprechendes erwartet. PNG-Grafiken lassen sich dynamisch mit Perl beispielsweise mit dem CPAN-Modul namens GD erzeugen.

[Bearbeiten] Form-Mailer

Ein Form-Mailer löst das leidige mailto-Problem bei HTML-Formularen. Ein solches Script kann ein beliebiges HTML-Formular verarbeiten und sendet die Daten per E-Mail an einen vorgesehenen Empfänger, in der Regel den Anbieter des Web-Projekts. In HTML wird das Form-Mail-Script einfach als action-Attribut im HTML-Formular angegeben - Beispiel:

<form action="/cgi-bin/formmail.pl" method="post">

Das Script wird aufgerufen, wenn ein Anwender das Formular absendet. Das Script sollte die Formularverarbeitung mit dem CGI-Modul nutzen, um die übergebenen Formulardaten einzulesen. Anschließend muss es aus den Daten des Formulars eine E-Mail zusammenbauen. Dazu sind vor allem der Operator für Zeichenkettenverknüpfung und die Funktionen für Zeichenketten von Bedeutung, ferner aber auch Wissen über den Aufbau einer E-Mail und darüber, wie eine E-Mail zu versenden ist. Die typische Anweisungsfolge dazu lautet:

Beispiel
my $Sendmail_Prog = "/usr/lib/sendmail";
open(MAIL,"|$Sendmail_Prog -t") or die "Mailprogramm konnte nicht gestartet werden\n";
print MAIL "To: $mailto\n";
print MAIL "Subject: $subject\n\n";
print MAIL "$mailtext\n";
close(MAIL) or die "Fehler beim E-Mail-Versand!";

Wichtig ist bei Anwendung der open-Funktion, dass das Programm sendmail, das E-Mails versenden kann, auch tatsächlich verfügbar ist, und zwar unter dem angegebenen Pfad. Der Pfad im Beispiel und die Verfügbarkeit von sendmail beziehen sich auf typische Unix-Rechner. Fragen Sie Ihren Provider gegebenenfalls danach! Die E-Mail selbst wird dann, wie Sie dem Beispiel entnehmen können, mit print-Anweisungen in den bei open benannten Ein-/Ausgabekanal des sendmail-Programms geschrieben - im Beispiel der Kanal mit dem Namen MAIL. Wichtig ist, dass eine E-Mail eine erste Zeile mit To: beginnend und eine weitere mit Subject: beginnend enthält. Vor der Ausgabe des E-Mail-Textes, also der zuvor für die Ausgabe vorbereiteten Formulardaten, müssen zwei Steuerzeichen \n\n stehen, also eine Leerzeile. Die Art und Weise der Datenübergabe kann variieren. Schauen Sie auf jeden Fall in die Anleitungen und FAQs Ihrers Providers und ggf. in die Anleitung des E-Mail-Programms!

Neben dem E-Mail-Versand muss das Script natürlich auch noch eine CGI-notwendige Ausgabe an den Browser senden. Bei einem Form-Mailer ist das sinnvollerweise eine Dank-Seite, die dem Anwender bestätigt, dass sein Formular verarbeitet wurde.


Im Online-Angebot von SELFHTML aktuell finden Sie einen Artikel: Einfacher Form-Mailer, der ein vollständiges Beispiel eines Form-Mailers beschreibt.

[Bearbeiten] Gästebuch

Es gibt mehrere Wege, ein Gästebuch zu programmieren. Einer besteht darin, die Gästebucheinträge in eine statische HTML-Datei schreiben zu lassen, die angezeigt wird, wenn der Anwender das Gästebuch aufruft. Die Datei könnte ein Formular enthalten, in das der Anwender seinen eigenen Eintrag schreiben kann, sowie die bereits vorhandenen Einträge. Das Script, das das Gästebuch verwaltet, würde dann aufgerufen, wenn der Anwender das Formular mit einem eigenen Eintrag absendet. Dazu ist im einleitenden <form>-Tag ein entsprechender Aufruf notiert - Beispiel:

<form action="/cgi-bin/guestbook.pl" method="post">

Das Script sollte die Formularverarbeitung mit dem CGI-Modul nutzen, um die übergebenen Formulardaten einzulesen. Angenommen, das Formular hat zwei Felder: eines für den Namen des Gästebuchschreibers (name="Username"), und eines für den Text (name="Usertext"). Dann wäre nach dem Einlesen mit dem CGI-Modul in Perl beispielsweise mit einem Konstrukt wie $cgi->param($Username) ein Zugriff auf den Inhalt des Feldes Username möglich.

Weiterhin muss das Script die HTML-Datei mit den bisherigen Einträgen einlesen. Mit der open-Funktion beispielsweise lässt sich die Datei dann öffnen und kann danach etwa in einen Array eingelesen werden. Jedes Element des Arrays ist dann eine Zeile der HTML-Datei.

Damit das Script sich im eingelesenen HTML-Code zurechtfindet und weiß, wo es die neuen Daten einfügen muss, sollte die Datei an der betreffenden Stelle in einer eigenen Zeile eine "geheime Marke" enthalten, was mit einem HTML-Kommentar lösbar ist - Beispiel:

<!-- NEU -->

Es macht aber auch Sinn, wenn die HTML-Datei vor jedem vorhandenen Eintrag in einer eigenen Zeile noch eine interne Notiz für das Script bereithält. Auch das ist mit Kommentaren möglich. Beispiel eines Eintrags in der HTML-Datei:

<!-- EINTRAG [Winfried Wachtelmann] [27.07.2001]-->
<table border="1"><tr>
<th>von:</th><td>Winfried Wachtelmann</td>
<th>am:</th><td>27.07.2001</td>
</tr><tr>
<td colspan="2">Diese wunderbare Seite hat mein Leben ver&auml;ndert usw.</td>
</tr></table>

Das Script tut sich dann leichter mit eventuellem Suchen in der Datei. Um die Formulardaten, die das Script übergeben bekommen und eingelesen hat, einzufügen, muss es aus den Formulardaten erst einmal den für einen Gästebucheintrag üblichen HTML-Code zusammenbauen und die Formulardaten darin einfügen. Im Beispiel würde das Script also eine HTML-Tabelle zusammen- und in den dafür vorgesehenen Zellen die Werte aus den Formulardaten einbauen. Am sinnvollsten ist es, wenn das Script dazu einen Array deklariert und diesem für jede Zeile des HTML-Codes ein Element zuweist mit dem entsprechenden HTML-Code. Am Ende jedes Eintrags im Array sollte ein \n für "neue Zeile" stehen. Dazu benötigen Sie die Funktion push und den Operator für Zeichenkettenverknüpfung - Beispiel:

Beispiel
my @NeuerEintrag;
push(@NeuerEintrag, "<!-- EINTRAG [".$cgi->param($Username)."] [".$Datum."]-->\n");
push(@NeuerEintrag, "<table border=\"1\"><tr>\n");
push(@NeuerEintrag, "<th>von:</th><td>".$cgi->param($Username)."</td>\n");
push(@NeuerEintrag, "<th>am:</th><td>".$Datum."</td>\n");
push(@NeuerEintrag, "</tr><tr>\n");
push(@NeuerEintrag, "<td colspan=\"2\">".$cgi->param($Usertext)."</td>\n");
push(@NeuerEintrag, "</tr></table>\n");
Das in $Datum gespeicherte Tagesdatum muss das Script natürlich zuvor ermitteln. Dazu gibt es die Funktionen für Datum und Uhrzeit. Nun muss das Script den neuen Eintrag einfach an der Stelle in der bisherigen Datei einfügen, wo mit <!-- NEU --> die Marke zum Einfügen steht. Eine mögliche Variante ist es, einen neuen Array zu bauen, der aus den Zeilen der alten Datei und den Zeilen des neuen Eintrags besteht. Dazu kann das Script in einer foreach-Schleife den Array mit den Zeilen der eingelesenen Datei abarbeiten und mit Hilfe eines regulären Ausdrucks nach /^<!-- NEU -->$/ suchen und an der betreffenden Stelle den Array mit dem neuen Eintrag einfügen. Der Code könnte etwa so aussehen:
my @NeueZeilen;
my $Zeile;
foreach $Zeile (@Zeilen) {               # @Zeilen = zuvor eingelesene Zeilen der Datei
  if($Zeile =~ /^<!-- NEU -->/) {        # Aha, Eintrag hier einfügen
    foreach(@NeuerEintrag) {             # @NeuerEintrag = zuvor zusammengebaute HTML-Zeilen
      push(@NeueZeilen,$_);              # Zeile für Zeile hinzufügen
    }
    push(@NeueZeilen,"<!-- NEU -->\n");  # fürs nächste mal ...
  }
  else {                                 # jede alte Zeile, die nicht /^<!-- NEU -->/ enthält
    push(@NeueZeilen,$Zeile);            # einfach in den neuen Array kopieren
  }
}
Der neue Array @NeueZeilen enthält dann also die Zeilen der neuen Fassung der Gästebuch-HTML-Datei. Dieser Array muss nun einfach noch in die gleiche Datei zurückgeschrieben werden, die zuvor eingelesen wurde. Das geht mit schreibendem Öffnen mit open und Beschreiben mit print ins Datei-Handle der geöffneten Datei.

Am Ende darf das Script natürlich nicht vergessen, CGI-notwendige Ausgaben an den Browser zu senden. Am einfachsten ist es wohl, einfach einen HTTP-Kopf und @NeueZeilen auszugeben. Das sind zwei print-Befehle, und schon sieht der Anwender, der das Formular abgesendet hat, das Gästebuch mit seinem eigenen neuen Eintrag.

Natürlich gibt es noch viele weitere wichtige Dinge, die das Gästebuch erledigen sollte. Beispielsweise sollten Dateien, die ein CGI-Script öffnet, grundsätzlich gegen versehentlichen Mehrfachzugriff geschützt werden - denn es könnten ja zwei Anwender gleichzeitig ein Formular mit einem neuen Eintrag absenden. Dann würden sich zwei Prozesse mit dem gleichen Script in die Quere kommen. Das so genannte File-Locking für den Zugriffsschutz geht mit der Funktion flock.
Weiterhin sollte das Script reagieren, wenn die HTML-Datei mit den Gästebucheinträgen zu groß wird. In diesem Fall könnte das Script einen Teil des Arrays mit älteren Einträgen in eine zweite Datei schreiben und diese in der Datei mit den aktuellen Einträgen verlinken, d.h. also in die erste Datei einen HTML-Link auf die zweite mit einbauen.
Und dann sollte das Script auch prüfen, ob eventuell angegebene mail-Adressen gültig (valide) sind und Benutzernamen nicht aus unsinnigen Zeichenfolgen wie @~Der Kobold~@ bestehen. Solche Aufgaben lassen sich am besten mit regulären Ausdrücken innerhalb bedingter Anweisungen lösen.

[Bearbeiten] Datenbank-Front-End

Sie brauchen nicht für jede Anwendung, bei der ein Web-Seitenbesucher dynamisch Daten abfragen kann, eine Datenbank. Datenbestände von bis zu ein paar Megabyte Größe, die nicht zu intensiv genutzt werden, lassen sich durchaus auch in Textdateien (z.B. kommasepariert oder in einer XML-Struktur) halten, die dann mit CGI-Scripts in Perl verwaltet werden können. Ein öffentliches "Front-End" (also eine Web-Anwendung) zum Abfragen des Datenbestandes sowie ein nur intern zugängliches Front-End zum Verwalten des Datenbestandes (auch eine Web-Anwendung, die das Hinzufügen, Ändern und Löschen von Datensätzen mittels Formular möglich macht) brauchen Sie sowieso in jedem Fall. Eine richtige Datenbank sollten Sie dann wählen, wenn der Datenbestand sehr intensiv gepflegt wird (sehr viele Änderungen im Datenbestand - ein Fall für "Table-Locking"), oder wenn die Datenstruktur sehr stark relational ist und mit vielen Lookups arbeitet, oder wenn der Datenbestand wirklich sehr groß ist und die Pi-mal-Daumen-Größe von ein paar Megabyte übersteigt. Auf dem Server muss dann natürlich eine entsprechende Datenbank-Software installiert sein - z.B. das beliebte Freeware-Produkt MySQL. Letzteres ist mittlerweile so dominant im Web, dass es für relationale Datenbanken bis zu mittlerer Größe praktisch konkurrenzlos ist. Fragen Sie gegebenenfalls Ihren Provider, ob Ihnen MySQL dort, wo Sie Speicherplatz im WWW gemietet haben, zur Verfügung steht, bzw. berücksichtigen Sie dies bei der Wahl des Providers, wenn Sie eine Datenbankanbindung brauchen. MySQL wird zwar vorwiegend gemeinsam mit PHP genutzt, aber über Perl ist es genauso möglich, Datenbank-Front-Ends zu schreiben, die mit MySQL kommunizieren können.

Bevor Sie ein Datenbank-Front-End in Perl schreiben, müssen Sie sich zuerst intensiv mit MySQL, Datenbankschnittstellen und der Abfragesprache SQL auseinandersetzen. Dazu gibt es Dokumentationen und Bücher. Im Link-Verzeichnis des Online-Angebots von SELFHTML finden Sie entsprechende Links:

SELFHTML:Linkliste Datenbankanbindung

Dieser kurze Abschnitt hier kann nur einige allgemeine Details aus Sicht von Perl behandeln. In einem Perl-CGI-Script, das mit einer MySQL-Datenbank kommunizieren möchte, müssen zu Beginn Zeilen wie die folgenden stehen:

Beispiel
use CGI;
use DBI;
 
my $DB_NAME = "Produkte";
my $DB_DSN = "DBI:mysql:database=$DB_NAME";
my $DB_USER = "";
my $DB_PASSWD = "";
 
my $dbh = DBI->connect($DB_DSN, $DB_USER, $DB_PASSWD) or die "Fehler bei Datenbankverbindung: $!";
DBI ist ein CPAN-Modul, das Sie in der Regel benötigen, um mit Perl auf Datenbanken zugreifen zu können. Es stellt eine datenbankunabhängige Schnittstelle zu verschiedenen datenbankabhängigen Treibern dar. Ihr Perl-Script kommuniziert also mit der Datenbank in der Form, dass es die Funktionen bzw. Methoden des DBI-Moduls nutzt.

Im Beispiel-Code deklariert das Script einige Skalare, die für das Modul und die Zusammenarbeit mit der Datenbank erforderlich sind. $DB_NAME ist der Name der Datenbank. DB_DSN ist eine Information für das DBI-Modul, welcher Treiber zum Verbindungsaufbau mit der Datenbank (im Beispiel: mysql) benutzt und welche Datenbank geöffnet werden soll (im Beispiel die Datenbank, die in $DB_NAME gespeichert ist). Da der SQL-Server von MySQL, der die Datenbankzugriffe und die Ausgabe an extern aufrufende Prozesse überwacht, Daten aus Datenbanken nur gegen Anmeldung mit Benutzerkennwort und Passwort herausrückt, sind diese ebenfalls bei der Datenbankverbindung anzugeben. Im Beispiel erhalten die entsprechenden Skalare $DB_USER und $DB_PASSWD einen leeren Inhalt zugewiesen. Bei autorisierter Nutzung einer Datenbank müssen Sie dort jedoch die Kenndaten eingeben.

Mit DBI->connect(...) wird die Verbindung zur Datenbank aufgebaut. Der Rückgabewert wird in einer Datenbank-Handle-Variablen gespeichert, im Beispiel $dbh. Über dieses Handle können Sie im weiteren Verlauf des Scripts die Funktionen bzw. Methoden des DBI-Moduls ansprechen, wie in diesem Beispiel:
my @DB_Felder = $dbh->list_fields('produktdaten');
$dbh->disconnect;
list_fields ermittelt die Feldnamen einer bestimmten Tabelle der Datenbank, im Beispiel die der Tabelle produktdaten. Mit $dbh->disconnect wird eine Datenbankverbindung am Ende wieder geschlossen. Die eigentliche Kommunikation mit der Datenbank erfolgt jedoch über entsprechende SQL-Befehle. Das folgende Beispiel zeigt, wie Sie in einem Perl-Script einen solchen Befehl notieren können und eine anschließende Datenbankabfrage starten:
my $SQL_Statement = "SELECT nummer, name, beschreibung FROM produktdaten ".
                    "WHERE produktdaten.nummer >= ".$cgi->param($von_Nummer).
                    " AND produktdaten.nummer <= ".$cgi->param($bis_Nummer).
                    " ORDER BY ".$cgi->param($sortier_feld);
 
my $Abfrage = $dbh->prepare($SQL_Statement);
$Abfrage->execute();
 
my @Datensatz;
while(@Datensatz = $Abfrage->fetchrow_array()) {
  DatensatzVerarbeiten(@Datensatz);
}
Für die Datenbankabfrage müssen Sie einen SQL-Befehl zusammenstellen und in einem Skalar speichern. Dazu müssen Sie die Syntax von SQL kennen. Normalerweise wird es so sein, dass Ihr CGI-Script wie im Beispiel die Parameter der Abfrage aus einem HTML-Formular bezieht, das der Anwender, der das Script mit dem Absenden des Formulars aufgerufen hat, ausgefüllt hat. Dazu sollte das Script die Formularverarbeitung mit dem CGI-Modul nutzen, um die übergebenen Formulardaten einzulesen. Eine dynamische Konstruktion eines SQL-Befehls aus Formulardaten ist dann wie gezeigt mit dem Operator für Zeichenkettenverknüpfung möglich. Anschließend wird mit $Abfrage = $dbh->prepare($SQL_Statement) dem DBI-Modul der Abfragewunsch mitgeteilt. Und danach kann dann mit $Abfrage->execute() der Abfragebefehl gestartet werden. Die Datenbank gibt nun der Reihe nach alle gefundenen Datensätze zurück. Jeder Datensatz besteht aus mehreren Feldern. Jeder Datensatz wird einzeln als Array zurückgegeben. In einer while-Schleife, die so lange läuft, wie der Aufruf von $Abfrage->fetchrow_array() einen neuen Datensatz liefert, wird im Beispiel eine Subroutine namens DatensatzVerarbeiten aufgerufen, die als Parameter den aktuellen Datensatz-Array übergeben bekommt. Diese Subroutine könnte beispielsweise den HTML-Code für die Ausgabe eines Datensatzes vorbereiten. Denn abschließend muss das Script natürlich CGI-notwendige Ausgaben zusammenstellen.

Bei der Verwaltung der Datenbank über ein HTML-Formular/Perl-Script-Front-End ist der Vorgang ganz ähnlich, nur mit zusätzlichen SQL-Befehlen zum Hinzufügen oder Zurückschreiben geänderter Datensätze in die Datenbank. Wichtig ist, dass ein solches Front-End für die interne Datenbankpflege gegen öffentliche Zugriffe geschützt ist. Dies kann zweistufig geschehen: zum einen sollte ein solches Front-End-Formular nur in einem htaccess-geschützten Verzeichnis liegen, und zum anderen sollte das Formular auch Eingabefelder für Benutzernamen und Passwort zum schreibenden Zugriff auf die Datenbank enthalten.

Meine Werkzeuge
Namensräume

Varianten
Aktionen
Übersicht
Index
Mitmachen
Werkzeuge
Spenden
SELFHTML