|
|
|
6.3 Perl/CGI-Tutorial
|
|
|
|
|
6.3.1
Einleitende Worte
Perl ist eine ausgezeichnete Programmiersprache, wenn man nur bereit ist, sich ein wenig einzuarbeiten. Es heißt, es gebe keine Programmier-Aufgabe, die sich nicht mit Perl realisieren ließe - vielleicht stimmt das sogar. Perl ist übrigens wahrscheinlich auch die portabelste Programmiersprache, verfügbar auf ca. 60 Plattformen.
Und was ist CGI? CGI steht für "Common Gateway Interface" und ist nur eine Methode, Daten an ein serverseitiges Programm zu übergeben. CGI ist keine Programmiersprache und ist nicht auf Perl beschränkt: Programme, die auf CGI zurückgreifen, können auch in C, PHP oder fast jeder anderen Sprache geschrieben sein.
Um das nochmals zu betonen: Perl ist ein so komplexes Thema, dass wir nur eine kurze Einführung geben können. Wir kratzen die Gesamtmenge der über Perl verfügbaren Informationen also höchstens an. Wenn Sie tiefer in die Materie einsteigen wollen, können wir Ihnen "Programmieren mit Perl" und das "Perl Kochbuch", beide erschienen im O'Reilly-Verlag, wärmstens empfehlen.
Damit Sie sich in den ersten Abschnitten nicht allzu sehr langweilen, geben wir Ihnen jetzt schon einen Überblick über das Tutorial: wir beginnen mit einem "Hallo Welt"-Programm und erklären, wie man es zum Laufen bringt. Danach gehen wir auf CGI im Allgemeinen ein und nehmen das "Hallo Welt"-Programm detailliert auseinander. Wir fahren fort mit einer Beschreibung allgemeiner Sprachelemente. Dieser Abschnitt wird etwas trocken, da ziemlich theoretisch, aber trotzdem notwendig, um spätere, etwas praktischer orientierte Beispiele verstehen zu können. Da geht es dann beispielsweise um den Zugriff auf CGI-Daten.
|
|
|
6.3.2
Hallo Welt
6.3.2.1 Hallo Code
Öffnen Sie einen beliebigen Texteditor (also nicht Word oder ähnliche Programme, sondern beispielsweise Notepad). Wundern Sie sich nicht - Perl wird mit Hilfe eines Texteditors programmiert. Ein Zusammenklicken der Programme, wie z.B. in Visual Basic, gibt es in Perl erst einmal nicht. Geben Sie also in den Editor folgenden Code ein und speichern Sie die Datei ab:
#!/usr/bin/perl
use CGI::Carp qw(fatalsToBrowser);
print "Content-type: text/html\n\n";
print "Hallo Welt";
sleep 3600;
6.3.2.2 Laufzeit-Umgebung
Das weitere Vorgehen hängt davon ab, wo das Script laufen soll:
- Soll es unter Windows laufen, brauchen Sie die erste Zeile nicht, sie schadet aber auch nicht. Unser Tipp: einfach stehen lassen.
- Soll es dagegen unter Unix/Linux funktionieren, brauchen Sie die erste Zeile unbedingt. Auch müssen Sie herausfinden, ob der dort angegebene Pfad zu Perl überhaupt richtig ist. Wenn Sie den Pfad nicht kennen, z.B. weil das Script auf dem Server Ihres Providers laufen soll, erkundigen Sie sich beim Administrator bzw. beim Support Ihres Providers.
- Soll das Script lokal zum Testen ausgeführt werden? Dann entfernen Sie die zweite Zeile.
- Wenn das Script dagegen auf einem Internet-Server laufen soll, entfernen Sie die letzte Zeile.
6.3.2.3 Testen unter Windows
Möglicherweise sind Sie jetzt etwas erstaunt: lokal zum Testen ausführen? Ja, kein Problem. Perl läuft auf fast jedem Computer, natürlich auch unter Windows. Sie müssen sich nur den passenden Interpreter herunterladen: ActiveState ist der Quasi-Standard für Windows. Wenn der Interpreter dann installiert ist, können Sie einfach auf Ihre Perl-Dateien doppelklicken. Diese sollten allerdings die Endung .pl haben, um überhaupt erkannt zu werden.
Für das lokale Testen unter Windows gibt es auch die letzte Zeile im Script: sie verhindert, dass das Programm sich direkt wieder schließt. Wenn Sie auf einem Internet-Server arbeiten, ist das natürlich kontraproduktiv: das Programm soll sich ja schnell schließen und seine Ausgaben an den Browser schicken.
Wenn sich das Fenster trotz der letzten Zeile direkt wieder schließt, wird es komplizierter: Das deutet auf einen Fehler im Script hin. Obwohl in unseren Beispiel-Scripts keine Fehler sein sollten, werden Sie später wie jeder andere Programmierer auch einmal einen Fehler machen. Für einen solchen Fall eignet sich die folgende Kurz-Anleitung:
- Öffnen Sie die Eingabeaufforderung. Sie finden Sie im Startmenü unter "Programme"->"Zubehör".
- Wechseln Sie in das Verzeichnis, in dem Ihre Perl-Dateien liegen
- Geben Sie ein:
perl -c scriptname.pl
- Jetzt wird Ihr Script auf Fehler untersucht. Sie erhalten einen Report, wo der Fehler vermutet wird. Tipp: um diese Meldungen besser interpretieren zu können, sollten Sie sich einen Editor besorgen, der Zeilennummern anzeigt.
6.3.2.4 Installieren auf einem Webserver
Wenn Sie Ihr Script auf einem Webserver testen wollen, hängt das genaue Vorgehen von Ihrem Provider ab. Trotzdem sollte folgende - FTP-Kenntnisse voraussetzende - Anleitung Ihnen eine grobe Orientierung geben können.
- Bauen Sie eine FTP-Verbindung zu Ihrem Server auf
- Machen Sie das Verzeichnis für CGI-Programme auf Ihrem Server ausfindig. Meist heißt es
cgi-bin oder cgi-local. In Zweifelsfällen wird Ihr Provider Ihnen hier Auskunft geben können.
- Laden Sie die Datei in das Verzeichnis (ASCII-Modus benutzen!) und setzen Sie die richtigen Berechtigungen (zum Testen: chmod 777). Überprüfen Sie, ob die Datei auch die richtige Endung hat (meist
.pl oder .cgi)
- Nun können Sie das Script vom Browser aus ansprechen. Beispiel: einfach
http://www.xyz.de/cgi-bin/script.pl als URL eingeben. Was Sie genau eingeben müssen, hängt natürlich davon ab, wohin Sie das Script hochgeladen haben.
- Wenn jetzt etwas nicht klappt, liegt der Fehler höchstwahrscheinlich bei Ihnen. Das Error-Log kann fast immer helfen. Alternativ dazu können Sie häufig das Modul
CGI::Carp benutzen (siehe oberes Beispiel).
Das Beispiel-Script werden wir im übernächsten Abschnitt detailliert erläutern. Erst einmal ist jetzt jedoch das CGI-Modell an der Reihe.
|
|
|
6.3.3
Das CGI-Modell
CGI-Programme laufen nach einem simplen Muster ab:
- Der Browser sendet eine Anforderung an den Server. In der Anforderung enthalten sind Daten, auch Argumente genannt. Nur: wo sind diese Daten? Wenn z.B. eine URL ein Fragezeichen enthält, können Sie davon ausgehen, dass alles, was danach folgt, Argumente sind.
- Das entsprechende Programm bekommt diese Daten zur Verfügung gestellt und verarbeitet sie.
- Das Programm gibt Daten an die Standard-Ausgabe aus, die an den Browser geschickt werden. Die Standard-Ausgabe können Sie auch unter Windows an vielen Beispielen bewundern: wann immer Sie beispielsweise eine MS-DOS-Eingabeaufforderung öffnen, wurde das, was Sie dort als Text sehen, von den entsprechenden Programmen an die Standard-Ausgabe geschickt.
- Der Browser zeigt die empfangenen Daten an: Sie müssen also HTML versenden.
Wenn Sie Ihre Programme lokal testen, steht dieser CGI-Background nicht zur Verfügung, außer, Sie haben selbst einen Server installiert. Sie müssen dann die Daten, die eigentlich via CGI kommen sollten, manuell einspeisen. Das hört sich wesentlich schlimmer an, als es ist - aber dazu weiter unten mehr.
|
|
|
6.3.4
Hallo Welt im Detail
Erinnern Sie sich noch an das kleine Beispiel-Script? Hier haben wir es noch einmal:
#!/usr/bin/perl
use CGI::Carp qw(fatalsToBrowser);
print "Content-type: text/html\n\n";
print "Hallo Welt";
sleep 3600;
Wir wollen es nun Zeile für Zeile durchgehen:
Die erste Zeile ist nur wichtig für Unix-Anwender. Sie sagt dem Betriebssystem, wo es Perl findet.
Die zweite Zeile sorgt dafür, dass Fehlermeldungen an den Browser geschickt werden. Normalerweise würde der Browser nur einen "Internal Server Error" zu sehen bekommen. Das klappt natürlich nur dann, wenn das Script auf einem Internet-Server läuft, und auch dann nicht immer: bei besonders schwerwiegenden Fehlern versagt die Anweisung oft.
Zusätzlich ist hier zu sehen, dass die Anweisung mit einem Semikolon abgeschlossen wird. Das gilt für jede Anweisung und ist eine der häufigsten Fehlerquellen.
Die dritte Zeile gibt einen HTML-Header aus. Der wird benötigt, um dem Browser zu signalisieren, dass nun HTML-Anweisungen folgen. Der Header steht in Anführungszeichen: das ist bei allen Zeichenketten so. Innerhalb der Zeichenkette sehen Sie die Sequenz \n. Die wird umgewandelt in einen Zeilenumbruch, jedoch nicht in einen HTML-Zeilenumbruch. Zur Ausgabe wird die Funktion print verwendet, die alles, was hinter ihr folgt, an die Standardausgabe sendet.
Die vierte Zeile ist nicht aufregend: wieder print, Anführungszeichen und ein Semikolon.
Die fünfte Zeile ist nur wichtig, wenn Sie unter Windows Perl-Scripts mit einem Doppelklick ausführen wollen. Ohne diese Zeile würde sich das Ausgabefenster direkt wieder schließen, so dass Sie die Ausgaben nicht lesen könnten.
Nicht direkt dem Beispiel zu entnehmen ist eine andere fundamentale Eigenschaft von Perl: Es wird zwischen Groß- und Kleinschreibung unterschieden. Print ist also etwas anderes als print.
|
|
|
6.3.5
Wichtige Sprachelemente
Wir werden uns nun systematisch wichtigen Perl-Sprachelementen zuwenden. Behalten Sie immer die Erkenntnisse aus vorhergehendem Abschnitt im Hinterkopf - besonders der Semikolon ist wichtig, wenn Sie eigene Programme schreiben.
Wir haben diesen Abschnitt mit einigen Beispielen garniert. Wenn Sie die Beispiele ausprobieren wollen, müssen Sie die Prozedur aus dem ersten Abschnitt wiederholen - Texteditor öffnen, Beispiel dort einfügen, Datei speichern und schließlich den Perl-Interpreter starten. Wenn Sie unter Windows arbeiten, empfehlen wir Ihnen das sleep 3600; am Ende des Codes. Die Beispiele sind nicht für einen (direkten) Einsatz im Web gedacht. Soll heißen: um die Beispiele im Internet ansehen zu können, müssen Sie sie entsprechend anpassen. Dabei halten Sie sich am besten an das Hallo-Welt-Programm, aus dem Sie die letzten beiden Zeilen entfernen und durch den Beispiel-Code ersetzen. Wenn Sie die Beispiele unter Linux ausprobieren wollen, müssen Sie natürlich noch die erste Zeile des HalloWelt-Programms hinzufügen.
Wenn Sie innerhalb der Beispiele Zeilen sehen, die mit einem Größer-Zeichen (>) beginnen, gehört diese Zeile nicht zum Code selbst. So ausgezeichnete Zeilen enthalten das, was bei einem Ausführen des zugehörigen Beispiels ausgegeben würde.
Wir sind nun startklar für das eigentlich Tutorial und beginnen mit einer recht einfachen Lektion: den Kommentaren.
6.3.5.1 Der Kommentar
Kommentare werden vom Perl-Interpreter ignoriert. Sie sind also nur für den Menschen gedacht, der den Quellcode später einmal lesen soll. Überschätzen Sie sich nicht: Sie werden, wenn Sie nach einem halben Jahr versuchen, Ihren alten Code zu bearbeiten, einige sinnvolle Kommentare zu schätzen wissen.
Kommentare setzt man durch das Raute-Zeichen (#). Alles, was hinter diesem Zeichen bis zum Ende der Zeile folgt, wird ignoriert.
Ein Beispiel:
# Jetzt kommt der HTML-Header:
print "Content-type: text/html\n\n";
Übrigens ist die erste Zeile des "Hallo Welt"-Programms eine Ausnahme: sie wird nicht ignoriert, obwohl sie mit einer Raute beginnt. Solche Ausnahmen sind selten. Bleiben Sie also fürs Erste bei der Faustregel, dass Rauten immer Kommentare einleiten.
Der Kommentar ist ein nützliches Mittel, wenn es darum geht, ein Script zu debuggen. Folgendes Script ist fehlerhaft (und die Ausgabe kommt von Perl und sagt Ihnen, dass da etwas nicht stimmt):
print "abc;
> Can't find string terminator '"' ...
Wo ist der Fehler? Sie können einfach die Zeile, in der Sie den Fehler vermuten, auskommentieren, um herauszufinden, ob Sie mit Ihrer Vermutung richtig lagen:
# Liegt der Fehler hier?
# print "abc;
> ...
6.3.5.2 Blöcke
Blöcke in Perl sind eine simple Sache: sie beginnen mit einer geschweiften Klammer und enden mit einer geschweiften Klammer:
{
# Ich bin im Block
print "abc";
}
Sie können Blöcke setzen, wo immer Sie wollen. Denken Sie nur daran, dass zu einer öffnenden Klammer auch immer eine schließende gehört.
Auch Verschachtelungen sind möglich:
{
# Ich in Block 1
{
# Und ich bin ich Block 2
}
}
Mit Blöcken lassen sich einige nützliche Dinge anstellen. Lassen Sie sich bitte vorerst damit vertrösten, dass Blöcke enorm wichtig sind für Perl - ohne sie kein größeres Programm.
6.3.5.3 Variablen
Variablen sind wie Container. Sie stecken etwas hinein, und dort bleibt es, bis Sie es herausholen. Praktischerweise sind diese Container ziemlich flexibel: im Prinzip können Sie herein stecken, was immer Sie wollen. Sie müssen noch nicht einmal wissen, was genau im Container ist, um mit ihm arbeiten zu können.
Gerade letzter Aspekt macht die Programmierung erst flexibel: Variablen ermöglichen es, abstrakt zu programmieren.
6.3.5.3.1 Variablen setzen
Variablen beginnen in Perl immer mit dem Dollar-Zeichen ($, wird übrigens gerne vergessen und sorgt dann für Fehler). Mit dem Gleichheitszeichen wird Variablen ein Wert zugewiesen:
$variable = "wert";
Selbstverständlich ist es auch möglich, einer Variable den Wert einer anderen zuzuweisen:
$variable1 = $variable2;
Bitte beachten Sie: Der Wert von $variable2 wird dupliziert. Wenn Sie also später irgend etwas mit $variable1 anstellen wollen, wirkt sich das nicht auf $variable2 aus.
6.3.5.3.2 Notationen
Achten Sie darauf, immer die richtigen Notationen für Strings (Zeichenketten, also im Grunde alles, was keine Zahl ist) und Zahlen zu verwenden. Strings stehen in Anführungszeichen, Zahlen werden so geschrieben, wie man es aus dem Alltag kennt. Nur das bei uns übliche Komma muss durch den Punkt ersetzt werden, wenn mit gebrochenen Zahlen gearbeitet werden soll:
$var = "zeichenkette";
$var = 12;
$var = 12.2;
Vollkommen falsch wäre:
$var = zeichenkette;
Achten Sie auch darauf, nicht aus Versehen einen Variablennamen in Anführungszeichen zu setzen.
6.3.5.3.3 Quoting und Interpolation
Interpolation
Sehen Sie sich folgenden Code an:
$variable1 = "Ich denke, ";
$variable2 = "$variable1 also bin ich";
print $variable2;
> Ich denke, also bin ich

Wenn Sie innerhalb doppelter Anführungszeichen einen Variablennamen verwenden, wird der durch den Wert der Variable ersetzt. Wenn Sie dieses Verhalten nicht wünschen, verwenden Sie einfach Anführungszeichen:
$variable1 = "Ich denke, ";
$variable2 = '$variable1 also bin ich';
print $variable2;
> $variable1 also bin ich

Andere Quoting-Mechanismen
Das Setzen eines Strings in Anführungszeichen nennt man "Quoting", weil hier Perl klar gemacht wird, dass es sich um eine Zeichenkette handelt, und nicht etwa um den Namen einer Variablen oder einen Befehl. Sie kennen jetzt schon zwei Quoting-Zeichen: doppelte und einfache Anführungszeichen. Wäre doch gelacht, wenn es nicht noch mehr gäbe:
$var = qq(Ich denke, also bin ich);
$var2 = qq($var <= berühmtes Zitat);
$var3 = q($var <= berühmtes Zitat);
# \n in der nächsten Zeile - was ist das?
# Siehe dazu den nächsten Abschnitt
print $var2, "\n";
print $var3, "\n";
> Ich denke, also bin ich <= berühmtes Zitat
> $var <= berühmtes Zitat

qq() erfüllt also die gleiche Funktion wir doppelte Anführungszeichen, q() dagegen arbeitet wie einfache Anführungszeichen.
Wofür braucht man so viele Quoting-Mechanismen? Sehen Sie sich folgendes Beispiel an:
# Da stimmt doch was nicht...
print "Paul sagt:"Ich bin Paul"";
> Bareword found where operator expected...
Das Problem ist hier, dass innerhalb der Zeichenkette das Zeichen verwendet werden soll, das die Zeichenkette eigentlich umschließt. Deshalb verwendet man hier einen anderen Quoting-Mechanismus...
print qq(Paul sagt:"Ich bin Paul");
> Paul sagt:"Ich bin Paul"Paul sagt:"Ich bin Paul"
Sonderzeichen
In einem vorherigen Beispiel wurde das verwendet:
print $var2, "\n";
Wir wissen von print, dass es alles ausgibt, was hinter ihm steht. Und wir sahen bei der Ausführung des Beispiels, dass hier in zwei Zeilen ausgegeben wurde. Genau dafür war das rätselhafte \n verantwortlich: Es heißt "Zeilenumbruch hier". Selbstverständlich lässt es sich auch direkt verwenden:
print "Viele\n\nviele\n\nZeilen";
> Viele
>
> viele
>
> Zeilen
Das funktioniert nur in doppelten Anführungszeichen oder qq(). In einfachen Anführungszeichen würde es einfach ignoriert.
Andere solche Zeichen sind \t (Tabulator) oder \\ (Backslash). Der Backslash innerhalb einer Zeichenkette gibt dem nächsten Zeichen oft eine andere Bedeutung. Daher müssen, wenn ein Backslash ausgegeben werden soll, zwei Backslashes verwendet werden:
# \n soll ausgegeben werden, kein
# Zeilenumbruch
print "\n"; # Falsch!
print "\\n"; # Richtig!
Dieser Mechanismus wird auch dann wichtig, wenn Sonderzeichen ausgegeben werden sollen, beispielsweise das @:
# @ mit Backslash:
print "webmaster\@aboutwebdesign.de";
> webmaster@aboutwebdesign.de
6.3.5.3.4 Namensräume
Wenn Sie eine Variable setzen, können Sie ihre Gültigkeit begrenzen. Soll heißen: Sie definieren eine Variable, die nur von bestimmten Stellen (ihrem Block) aus zugänglich ist.
Welche Gründe könnte es geben, das zu tun? Im Allgemeinen wird es als guter Stil angesehen, Variablen lokal zu deklarieren, ihre Gültigkeit also damit zu begrenzen. Diese Vorgehensweise verhindert Konflikte: manchmal verwendet man den Namen einer Variablen aus Versehen doppelt. Wenn die Variable dann global (also unbegrenzt gültig) ist, hat man ein Problem. Zudem verhindert man so unnötigen Speicherbereich, denn sobald der Gültigkeitsbereich einer Variablen verlassen wurde, wird die Variable gelöscht.
Wenn Sie sich dafür entscheiden, Variablen lokal zu machen (es gibt nur sehr wenige Fälle, in denen das nicht angebracht ist), verwenden Sie das Schlüsselwort my, wenn Sie auf die Variable das erste Mal zugreifen. Die Variable ist dann nur innerhalb des Blocks gültig, in dem sie erzeugt wurde.
Spätere Zugriffe auf die Variable laufen genauso ab wie Zugriffe auf globale Variablen:
# Globale Variable
$var1 = "abc";
# Zugriffe:
print $var1;
$var1 = "fjfjf";
# Lokale Variable
my $var2 = "abc";
# Zugriffe genauso:
print $var2;
$var2 = "fjfjf";
Um das Konzept des Blocks in Zusammenhang mit lokalen Variablen noch einmal zu verdeutlichen, haben wir hier noch ein Beispiel:
{
# Globale Variable
$var1 = "testwert";
}
print $var1;
> testwert
{
# Lokale Variable, nur in
# diesem Block gültig
my $var2 = "testwert";
}
# Hier ist der Block verlassen,
# $var2 hat also keinen Wert
# mehr.
print $var2;
> (keine Ausgabe)

6.3.5.4 Operatoren
Operatoren sind die Sprachelemente, die andere Elemente miteinander verknüpfen. Die meisten Operatoren nehmen die beiden Dinge, die rechts und links neben ihnen stehen, und verknüpfen sie auf irgendeine Art miteinander. 5 + 4 ist ein gutes Beispiel, hier werden 5 und 4 zum Wert 9 verknüpft. Das nennt man übrigens Ausdruck: Erst werden alle Operatoren angewandt, dann ergibt das ein Ergebnis.
In Perl funktioniert das genau so, wie man es normalerweise erwarten würde:
6.3.5.4.1 String-Operatoren
Es gibt einen Operator, um zwei Strings miteinander zu verknüpfen: den Punkt-Operator.
$a = "String1 ";
$b = "String2";
print $a.$b;
> String1 String2

Dabei ist Perl im Umgang mit Strings und Zahlen äußerst flexibel. Sie können mit dem Punkt-Operator auch einen String mit einer Zahl oder eine Zahl mit einer Zahl verknüpfen. In solchen Fällen nimmt Perl einfach an, dass die Zahl ein String ist, denn Strings können schließlich auch Zahlen enthalten.
print "Zahl: ".10;
> Zahl: 10
# Klammerung notwendig, um
# klar zu machen, dass keine
# Kommazahl gemeint ist
print ((10).(10));
> 1010

6.3.5.4.2 Numerische Operatoren
Perl unterstützt alle bekannten numerischen Operatoren. Sie funktionieren alle nach diesem Muster:
$a = 5 + 4;
print $a,"\n";
> 9
$a = 10;
$b = 3;
$c = $a + $b;
print $c,"\n";
> 13
print 3*4,"\n";
> 12

Es gibt die Operatoren + (Addition), - (Subtraktion), * (Multiplikation), / (Division) und ** (Potenzierung).
6.3.5.4.3 Abkürzungen
Perl-Programmierersollen faul sein. Damit müssen sie es einfach hassen, zu viel tippen zu müssen. Daher wurden einige Abkürzungen geschaffen, um so etwas wie $var1 = $var1 + 5; abzukürzen (erhöht $var1 um 5). Man kann stattdessen einfach $var1 += 5; schreiben.
Das klappt noch mit einigen anderen Operatoren:
$v += 5;
$v *= 5;
$v /= 5;
$v .= "Anhaengsel";
Zusätzlich dazu wurde noch eine spezielle Möglichkeit geschaffen, das Erhöhen einer Variable um 1 eleganter zu formulieren:
$c++ erhöht die Variable $c um 1. $c-- tut genau das Gegenteil.
6.3.5.4.4 Logische Operatoren
Logische Operatoren arbeiten etwas anders: Sie arbeiten nur mit den Werten "wahr" und "falsch", symbolisiert durch 1 und 0.
Dabei gelten nur 0-Werte, leere und nicht definierte Werte als falsch, alle anderen sind wahr.
Logische Operatoren werten zunächst die Werte aus, auf die sie angewendet werden, d.h. sie überprüfen, ob diese Werte wahr oder falsch sind. Dann verknüpfen sie die beiden Werte.
Der Operator and gibt 1 zurück, wenn beide Werte, auf die er angewendet wird, wahr sind. Der Operator or verlangt, dass mindestens einer dieser Werte wahr sein muss, wenn eine 1 zurückgegeben werden soll.
Der Operator not dagegen wird nur auf einen Wert angewendet: Er kehrt ihn einfach um.
Folgende Beispiele werden das vielleicht etwas verdeutlichen:
# Wahr, da 1 immer wahr
print (1 and 1);
> 1
# and verlangt, dass beide wahr sein müssen,
# gibt jetzt also Falsch zurück
print (0 and 1);
> 0
print (1 or 1);
> 1
# or dagegen reicht es, wenn einer
# der Werte wahr ist
print (1 or 0);
> 1
# not kehrt um
print (not 1);
> 0
print (not 0);
> 1
# Das klappt auch wunderbar mit Zeichenketten,
# die prinzipiell wahr sind, solange sie nicht
# leer sind
print ('a' and 1);
> 1
6.3.5.4.5 Vergleichsoperatoren
Vergleichsoperatoren ähneln den logischen Operatoren: sie geben als Ergebnis immer Wahr oder Falsch zurück.
Jedoch ist ihre Funktion etwas komplexer als die der logischen Operatoren: sie vergleichen die beiden Werte, wie der Name eben schon sagt.
Hier sollte zwischen Zeichenketten- und Zahlenkettenvergleichen unterschieden werden. Die wichtigsten Operatoren sind wohl die, die auf Gleichheit prüfen: eq und ==, ersterer für Strings, letzterer für Zahlen:
print (1 == 1);
> 1
print (1 == 12);
> 0
print ("gut" eq "schlecht");
> 0
print ("eins" eq "eins");
> 1
Logischerweise gibt es auch Umkehr-Operatoren für einen Test für Nicht-Gleichheit: für Zeichenketten ist das ne, für Zahlen dagegen !=.
Auf die anderen Operatoren für Strings gehen wir hier nicht weiter ein - sie werden so gut wie nie benötigt. Anders dagegen sieht es mit den anderen Operatoren für Zahlenvergleiche aus, deren Bedeutung für die Praxis ungleich größer ist: > (größer), < (kleiner), <= (kleiner oder gleich) und >= (größer oder gleich). Angewendet werden sie genauso wie die anderen Vergleichsoperatoren.
6.3.5.4.6 Operatoren-Rangfolge
Bestimmt erinnern Sie sich noch an die alte mathematische Grundregel: Punktrechnung geht vor Strichrechnung. Diese Regel existiert auch in Perl:
print 8*5+3;
> 43

Aber beginnen wir etwas weiter vorne: Es ist möglich, beliebige Operatoren miteinander zu verknüpfen. Daher gibt es Regeln, die genau festlegen, welcher Operator jeweils Priorität hat. Daher mussten wir auch im letzten Abschnitt klammern: and hat eine so niedrige Priorität, dass anderenfalls der erste Werte von print ausgewertet würde.
Klammern jedoch haben grundsätzlich die höchste Priorität: es lohnt sich daher, viel und häufig zu klammern, um sich selbst vor Flüchtigkeitsfehlern zu schützen, gerade dann, wenn man Operatoren verwendet, deren Priorität nicht automatisch aus dem Mathematik-Unterricht bekannt ist.
6.3.5.5 Arrays
6.3.5.5.1 Definition
Wir hatten einmal gesagt, Variablen seien Container, die man mit beliebigem Inhalt füllen könne. Einen Beweis sind wir bisher schuldig geblieben: schließlich haben wir lediglich Zahlen und Zeichenketten in Variablen gespeichert. Wir werden nun zwei neuen Formen zuwenden, Daten zu speichern: Arrays und Hashes.
Arrays sind Listen. Eine ganz einfache Sache also. Verwendet werden sie so:
# Array erzeugen
@array = ('eins', 'zwei', 'drei');
# Ein Element der Liste ausgeben
print $array[0], "\n";
> eins
print $array[2], "\n";
> drei
# Ein Element zu setzen, ist genauso einfach
$array[2] = "neuer Wert!";
print $array[2], "\n";
> neuer Wert

Sie sehen, wir haben am Anfang etwas geschwindelt: Es gibt auch Variablen, die mit etwas anderem als dem Dollarzeichen beginnen. So z.B. das Array, das das @-Zeichen am Anfang trägt. Aber das nur dann, wenn auf das Array als Ganzes zugegriffen wird. Sonst wird weiterhin das altbekannte Dollarzeichen verwendet und die Variable wird "Skalar" genannt. Ein Array ist also logischerweise aus einer Reihe von Skalaren aufgebaut. Jedes einzelne Element des Arrays ist eine Variable wie jede andere und kann wiederum mit beliebigem Inhalt gefüllt werden.
Dabei ist Perl wie immer ziemlich flexibel. Sie können auch auf Elemente des Arrays zugreifen, die bisher noch gar nicht erzeugt wurden. Auch eine gegenseitige Zuweisung von Arrays ist möglich, genau wie bei Skalaren:
# Array als leere Liste erzeugen
# Ist sinnvoll, um sich selbst
# vor Fehlern zu schützen
@array = ();
$array[10] = "Das elfte Element";
print $arrray[10], "\n";
> "Das elfte Element";
# Array kopieren
@array2 = @array;

Fassen wir also noch einmal zusammen: Arrays sind Listen. Spricht man das gesamte Array an, verwendet man ein @-Zeichen vor dem Namen des Arrays. Will man einem ganzen Array Inhalt zuweisen, setzt man die Werte in runde Klammern und trennt sie mit Kommata. Will man dagegen auf ein einzelnes Element zugreifen, verwendet man das Dollarzeichen am Anfang und spezifiziert das Element, auf das zugegriffen werden soll, mit einem Zahlenwert, der in eckigen Klammern direkt hinter dem Array-Namen steht. Die Zählung dieser Werte beginnt bei 0, d.h. der Wert mit dem Index 0 ist der erste Wert und der Index 10 steht für den elften Wert.
6.3.5.5.2 Die Länge von Arrays
Manchmal müssen Sie herausfinden, welchen Wert der größte Index des Arrays hat. Verwenden Sie in einem solchen Fall die Schreibweise $#array. $#array+1 gibt also an, wie viele Elemente im Array vorhanden sind:
# my funktioniert auch mit Arrays
my @array = ('eins','zwei', 'drei');
print "Das Array hat so viele Elemente:", $#array+1;

Sehr hilfreich ist das, wenn Sie nicht wissen, wie groß ein Array eigentlich ist, z.B. weil es mit CGI-Daten gefüllt wurde:
# my funktioniert auch mit Arrays
my @array = ('eins','zwei', 'drei', 'hundert');
# Letztes Element ausgeben:
print $array[$#array];

6.3.5.5.3 Array-Funktionen
Es gibt einige nützliche Funktionen, die beim Umgang mit Arrays sehr hilfreich sind. Sie werden jetzt zum ersten Mal mit anderen Funktionen als print konfrontiert: Gehen Sie davon aus, dass diese neuen Funktionen sehr ähnlich arbeiten. Viele Funktionen liefern einen Rückgabewert, der dann in einer Variable gespeichert werden kann. Fast alle Funktionen erwarten auch, so wie print, Argumente. Die sollten dann in runden Klammern stehen, um Probleme zu vermeiden. Die folgenden Beispiele werden das etwas klarer machen.
pop
pop tut zwei Dinge gleichzeitig: Es entfernt das letzte Element eines Arrays und liefert es zurück.
# Jetzt hat @array drei Elemente
my @array = ('eins','zwei', 'drei');
# Nach der nächsten Zeile sind es nur
# noch zwei Elemente
my $letzter_wert = pop(@array);
print $letzter_wert;
> drei

push
push fügt eine Liste am Ende eines Arrays an. Dabei kann diese hinzuzufügende Liste natürlich auch aus nur einem Element bestehen:
my @array = ('eins','zwei', 'drei');
push(@array, 'vier');
# Letztes Element ausgeben:
print $array[3], "\n";
> vier
# Und jetzt: ein Array an ein anderes
# anhängen
my @array2= ('fuenf', 'sechs');
push(@array, @array2);
# Letztes Element ausgeben:
print $array[3], "\n";
> sechs

shift und unshift
shift und unshift arbeiten genauso wie pop und push. Sie entfernen das erste Element (shift) und fügen etwas an den Anfang des Arrays an (unshift).
my @array = ('eins','zwei', 'drei');
my $erstes_element = shift(@array);
# Erstes Element ist entfernt,
# jetzt ist zwei vorne
print $array[0];
> zwei
unshift(@array, $erstes_element);
# Und jetzt ist eins wieder vorne:
print $array[0];
> eins

join
join fügt alle Elemente eines Elements zu einem String zusammen. Zwischen die einzelnen Elemente kommt ein Trennzeichen:
my @gaeste = ('Klaus', 'Hans', 'Alex');
print "Eingeladen: ", join(', ', @gaeste);

Das Trennzeichen ist also das erste Argument, das Array, aus dem eine Zeichenkette gemacht werden soll, ist das zweite Argument. Das Array wird dabei nicht verändert.
sort
sort sortiert ein Array und gibt das Ergebnis zurück. Das ursprüngliche Array wird dabei nicht verändert:
my @a = ('x', 'z', 'y');
my @sorted = sort(@a);
print join(',', @sorted);

Dabei kann explizit zwischen numerischer und alphabetischer Sortierung gewählt werden:
my @a = (1, 2, 3, 10);
my @numerisch = sort {$a <=> $b} (@a);
my @alphabetisch = sort {$a cmp $b} (@a);
print "Numerisch: ", join(',', @numerisch), "\n";
print "Alphabetisch: ", join(',', @alphabetisch), "\n";
> Numerisch: 1,2,3,10
> Alphabetisch: 1,10,2,3

Wie Sie sehen, führt also eine alphabetische Sortierung, die übrigens Standard ist, wenn man sort ohne Zusatz verwendet, zu seltsamen Ergebnissen, wenn Zahlen sortiert werden sollen.
reverse
reverse kehrt die Reihenfolge der Elemente in einem Array um und gibt das Ergebnis zurück. Das Ausgangs-Array bleibt unberührt.
my @a = (1, 2, 3, 10);
my @umgekehrt = reverse(@a);
print "Ursprünglich: ", join(',', @a), "\n";
print "Umgekehrt: ", join(',', @umgekehrt), "\n";
> Ursprünglich: 1,2,3,10
> Umgekehrt: 10,3,2,1
6.3.5.6 Hashes
6.3.5.6.1 Definition
Hashes werden auch assoziative Arrays genannt. Soll heißen: auch Hashes sind Listen, auf die jedoch mit einer Zeichenkette, nicht mit einer Zahl zugegriffen wird. Diese Zeichenkette wird Schlüssel genannt. Die Werte innerhalb eines Hashes haben keine feste Reihenfolge.
Sehen Sie sich folgendes Beispiel an:
my %hash;
$hash{a} = 'Test-Wert';
print $hash{a};
> Test-Wert

So weit also recht einfach: statt des @-Zeichens haben wir hier ein Prozent-Zeichen. Anstelle eckiger Klammern verwenden wir geschweifte.
Praktisch sind Hashes, weil ihre Handhabung in vielen Fällen umkomplizierter ist als die Verwendung eines Arrays:
my %kunde;
$kunde{name} = "Meier";
$kunde{strasse} = "Mainweg";
$kunde{ort} = "Muenchhausen";
$kunde{telefon} = "44593";

6.3.5.6.2 Hash-Funktionen
Genauso wie für Arrays gibt es auch für Hashes bestimmte Funktionen, die den Umgang mit ihnen erleichtern.
keys
Wer irgendwie auf alle Werte eines Hashes zugreifen will, muss die Schlüssel kennen. keys gibt eine Liste aller Schlüssel eines Hashes zurück.
my %kunde;
$kunde{name} = "Meier";
$kunde{strasse} = "Mainweg";
$kunde{ort} = "Muenchhausen";
$kunde{telefon} = "44593";
my @schluessel = keys(%kunde);
print join(', ', @schluessel);
# Die Reihenfolge der Schlüssel
# ist bei Ihnen eventuell
# anders!
> telefon, ort, strasse, name

Ist Ihnen aufgefallen, dass wir es hier wieder mit einem Array zu tun haben? Man wird die Dinger aber auch einfach nicht los.. ;-)
Um jetzt alle Werte wirklich sinnvoll verarbeiten zu können, brauchen Sie noch ein bisschen mehr Hintergrundwissen. Damit müssen Sie sich leider bis zum Abschnitt über Schleifen gedulden. Dort finden Sie dann aber auch ein sinnvolles Beispiel.
delete
Um ein Schlüssel-Wert-Paar aus einem Hash zu löschen, verwenden Sie die delete-Funktion:
my %kunde;
$kunde{name} = "Meier";
$kunde{strasse} = "Mainweg";
$kunde{ort} = "Muenchhausen";
$kunde{telefon} = "44593";
delete $kunde{telefon};
my @schluessel = keys(%kunde);
print join(', ', @schluessel);
# Die Reihenfolge der Schlüssel
# ist bei Ihnen eventuell
# anders!
> ort, strasse, name

6.3.5.7 Andere Funktionen
Es gibt noch viele andere Funktionen, die dem Programmierer das Leben erleichtern. Die müssen Sie kennen, bevor Sie ernsthafte Anwendungen schreiben können.
6.3.5.7.1 chop/chomp
chop entfernt das letzte Zeichen einer Zeichenkette:
my $zeichenkette = "test";
chop($zeichenkette);
print $zeichenkette;
> tes

Die Zeichenkette wird dabei also grundsätzlich verändert. chomp überprüft vorher, ob das letzte Zeichen ein \n (Zeilenumbruch) ist. Nur dann wird es entfernt.
6.3.5.7.2 index
index sucht eine Zeichenkette innerhalb einer anderen und gibt ihre Position zurück:
my $zeichenkette = "abcdefg";
print index($zeichenkette, 'c');
> 2

Sie sehen, dass hier das erste Zeichen die Position 0 hat. Wird die Teilzeichenkette nicht gefunden, wird -1 zurückgegeben. Es ist zusätzlich möglich, als drittes Argument noch eine Startposition für die Suche anzugeben.
6.3.5.7.3 substr
substr extrahiert einen Teil einer Zeichenkette:
my $zeichenkette = "abcdefg";
print substr($zeichenkette, 3, 3);
> def

Der erste Parameter ist also der String, aus dem extrahier wird. Der zweite Parameter gibt die Startposition an, und der dritte, wie viele Zeichen extrahiert werden sollen.
Es ist optional möglich, noch einen vierten Parameter anzugeben. Wenn das getan wird, wird die extrahierte Teilzeichenkette durch den vierten Parameter ersetzt. Im Zusammenspiel mit index lässt sich so ein kleines Programm bauen, das das erste Vorkommen einer Zeichenkette durch eine andere ersetzt. Hier der Code:
my $basis_zeichenkette = "Klaus sucht das Haus!";
my $suchen = "Klaus";
my $ersetzen = "Peter";
my $position = index($basis_zeichenkette, $suchen);
substr($basis_zeichenkette, $position, length($suchen), $ersetzen);
print $basis_zeichenkette;
> Peter sucht das Haus

Unberücksichtigt bleibt leider, dass die Möglichkeit, dass der Such-String gar nicht im Ausgangs-String vorhanden ist, ignoriert wird. Zusätzlich benutzen wir die Funktion length, die Sie bisher noch nicht kennen. Sie ermittelt - Überraschung! - die Länge einer Zeichenkette.
6.3.5.7.4 length
length ermittelt die Länge einer Zeichenkette:
my $zeichenkette = "abcdefg";
print length($zeichenkette);
> 7

6.3.5.7.5 die
Die Funktion die beendet das Programm. Ein Beobachter von außen könnte zu dem Schluss kommen, dass der Tod gewaltsam war ;-). Soll heißen: die wird eingesetzt, um unerwartete Fehler abzufangen.
die("Fehler bei XYZ...");
Das erste Argument ist optional und wir ausgegeben.
6.3.5.7.6 exit
exit wird verwendet, um das Programm natürlich zu beenden. Parameter sind keine zwingend erforderlich.
6.3.5.7.7 eval
eval ist eine enorm praktische, gleichzeitig aber auch etwas komplizierte Funktion. Sie wird entweder verwendet, um Fehler abzufangen, oder um Perl-Code auszuführen, der zum Zeitpunkt der Programmierung eventuell noch gar nicht bekannt ist.
Das Abfangen von Fehlern wird in diesem Beispiel gezeigt:
eval {
# Division durch Null ist nicht
# erlaubt!
print 10/0;
};
print $@;
> Illegal division by zero...
Die Spezialvariable $@ wird nur dann gesetzt, wenn beim letzten eval ein Fehler aufgetreten ist. Lag dagegen kein Fehler vor, wird die Variable explizit geleert. Es ist möglich, das mit Bedingungsanweisungen zu verknüpfen, aber dazu später mehr.
Vermeiden Sie, solange Sie noch am Anfang Ihrer Perl-Karriere stehen, die Verwendung von eval zum Ausführen von Code. Wir zeigen Ihnen trotzdem, wie es geht:
my $code = qq(print "ABC";);
eval($code);
> ABC

Der Unterschied zum vorherigen Beispiel: es wird eine Zeichenkette, kein Block an eval übergeben.
Achten Sie darauf, in solchen Fällen grundsätzlich die Variable $@ zu überprüfen. Im Abschnitt "Bedingungen" gibt es ein Beispiel dazu.
6.3.5.7.8 Zeit-Funktionen
time gibt die Anzahl der Sekunden seit dem 1.1.1970 zurück (zumindest ist das auf den meisten Systemen so. Der Macintosh aber zählt z.B. die Sekunden seit einem Datum im Jahre 1904).
localtime verarbeitet diese Zahl und macht eine lokale Zeitangabe daraus: Es werden Sekunden, Minuten, Stunden, Tag, Monat, Jahr, Tag des Monats und Tag des Jahres zurückgegeben. Ein weiterer Rückgabewert ist wahr, wenn zu dem übergebenen Zeitpunkt die Sommerzeit gilt.
Um beispielsweise das aktuelle Datum auszugeben, schreiben Sie:
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$sommerz) = localtime(time);
$year = $year + 1900;
$mon = $mon + 1;
print "Es ist der $mday.$mon.$year";

Übrigens ist das ein gutes Beispiel, um zu sehen, wie Listen zurückgegeben werden.
Ansonsten ist der Code simpel. Sie müssen nur darauf achten, dass die Angaben ihre kleinen Tücken haben: zum Jahr muss 1900 dazuaddiert werden, zum Monat 1.
6.3.5.7.9 Funktionen selbst definieren
Wäre doch gelacht, wenn man so praktische Funktionen nicht auch selbst definieren könnte. Natürlich geht es, und es ist ziemlich einfach.
Der folgende Code zeigt die wichtigen Elemente einer Funktionsdefinition:
print &summe(3,2);
sub summe
{
my $argument = shift;
my $argument2 = shift;
return ($argumentd + $argument2);
}

Funktionsdefinitionen werden eingeleitet vom Schlüsselwort sub. Danach folgt der Funktionsname und ein Block. Der Block enthält den Code, der zur Funktion gehört. Innerhalb der Funktion stehen die Argumente im Array @_ zur Verfügung. Tricky: wenn shift kein Argument bekommt, arbeitet es automatisch mit dem @_-Array.
Wenn man eine Rückgabe erzeugen will, verwendet man das Schlüsselwort return. Argument ist entweder ein Rückgabewert oder auch eine Liste.
Aufgerufen wird die Funktion wie alle vorherigen Funktionen auch. Klammern sind Pflicht, vor den Funktionsnamen sollte ein Und-Zeichen (&) gestellt werden.
Übrigens lässt sich unser Suchen-und-Ersetzen-Beispiel von eben auch als Funktion definieren:
sub ersetzen
{
my $basis_zeichenkette = $_[0];
my $suchen = $_[1];
my $ersetzen = $_[2];
my $position = index($basis_zeichenkette, $suchen);
substr($basis_zeichenkette, $position, length($suchen), $ersetzen);
return $basis_zeichenkette;
}
print &ersetzen("Ich will ein Haus", "Haus", "Computer");

Wir haben hier eine etwas andere Form gewählt, auf die Parameter zuzugreifen. Wir sagten ja, dass die Parameter im Array @_ zur Verfügung stehen. Genauso, wie man auf Elemente des Array @gaeste mit $gaeste[0] zugreifen kann, funktioniert hier der Zugriff über $_[0] etc.
Es ist übrigens unwesentlich, von wo die Funktion aufgerufen wird. Eben stand der Aufruf über der Funktion, jetzt unter ihr. Es ist genauso möglich, dass der Aufruf am Anfang der Datei steht und die Funktion selbst ganz unten.
Funktionen sind eine sehr praktische Sache. Sie schaffen damit Ordnung in Ihrem Code. Verwenden Sie sie, wann immer es angemessen scheint!
6.3.5.8 Bedingungen
6.3.5.8.1 if
Um irgendwann einmal auf ein Ereignis reagieren zu können, muss man unterscheiden: wurde Taste A oder Taste B gedrückt? Hat die Datei mehr oder weniger als 10.000 Zeilen?
Für die Bearbeitung solcher Fragen gibt es die verzweigten Bedingungen. Mit ihnen lässt sich das ausdrücken, was im Deutschen mit den Wörtern "Wenn ..., dann ...", "Wenn nicht das, anstatt dessen aber etwas anderes zutrifft, dann ..." und "sonst" ausdrücken lässt. Im Klartext: praktisch beliebig komplexe Ausdrücke sind formulierbar. Sehen Sie sich folgendes Code-Beispiel in Pseudo-Sprache an:
Wenn die Zahl A größer als 5 ist, führe aus:
{
Wenn die Zahl B gleich 10 ist, führe aus:
{
irgendeine Anweisung;
}
Und für alle andere Fälle führe das aus:
{
irgendeine Anweisung;
}
}
Wenn die Zahl A dagegen gleich 5 ist, führe aus:
{
irgendeine Anweisung;
}
Und für alle andere Fälle führe das aus:
{
irgendeine Anweisung;
}
Recht einfach verständlich, nicht wahr? Übrigens zeigt dieses Beispiel eine Verschachtelung: es ist möglich, innerhalb eines Blocks weitere Verschachtelungen durchzuführen.
In Perl sieht das nicht viel anders aus. Sie verwenden einfach die Operatoren, die Sie schon kennen. Folgendes Beispiel hat die gleiche Funktion wie vorheriger Pseudo-Code, funktioniert aber nicht direkt in Perl, da der Interpreter Probleme mit irgendeine Anweisung; bekommen würde.
my $a = 5;
my $b = 12;
if ($a > 5)
{
if ($b = 10)
{
irgendeine Anweisung;
}
else
{
irgendeine Anweisung;
}
}
elsif ($a == 5)
{
irgendeine Anweisung;
}
else
{
irgendeine Anweisung;
}
Wie deutlich wird, sind Bedingungen grundsätzlich in Klammern zu schreiben. Dabei handelt es sich übrigens um Ausdrücke. Wenn Sie sich das und die Funktionsweise von Operatoren noch einmal ins Gedächtnis rufen wollen, sollten Sie den entsprechenden Abschnitt noch einmal lesen.
Im Beispiel ist zu sehen, dass else für "sonst" steht. Auch der Rest ist recht einfach zu verstehen: if leitet eine bedingte Verzweigung ein. Wenn man zusätzliche, parallele Bedingungen verwenden will, schreibt man danach elsif. Dieser Teil kann nur dann ausgeführt werden, wenn die vorherige if-Bedingung nicht zutraf. Es ist auch möglich, mehrere elsif-Blöcke hintereinander zu verwenden.
Bedingungen sind für viele Anwendungen zwingend erforderlich. So z.B. auch für das Sicherstellen eines korrekten Ablaufs, indem man beispielsweise das Ergebnis einer eval-Funktion testet. Das geht so:
eval {
# Division durch Null ist nicht
# erlaubt!
print 10/0;
};
if ($@)
{
die("Oh oh.. hier liegt ein Fehler vor!");
}
Wir erinnern uns: $@ ist nur dann nicht leer, wenn ein Fehler vorlag. Nur dann ist $@ also wahr, und dann wird die die-Anweisung ausgeführt.
6.3.5.8.2 Andere Möglichkeiten
Es gibt noch eine andere, schnellere Form einer Bedingung, die allerdings nicht immer anwendbar ist. Oft werden Sie so etwas wie das hier sehen:
open(DATEI, "<test") || die ("Datei konnte nicht geöffnet werden");
Das || ist eine stärker bindende Form des or, hat also eine höhere Priorität. Beide Operatoren zeigen ansonsten das gleiche Verhalten. or funktioniert folgendermaßen: Erst wird das ausgewertet, was links steht, dann das, was rechts steht. Wenn das, was links steht, aber schon wahr ist, wird der rechte Teil gar nicht mehr ausgewertet.
Das obige Beispiel funktioniert so: die open-Funktion (die im Übrigen gleich besprochen wird) gibt Wahr zurück, wenn sie ordnungsgemäß funktioniert hat. Gab es jedoch einen Fehler, wird Falsch zurückgegeben. Nur dann wird auch der rechte Teil ausgewertet, die die-Anweisung. Um die auszuwerten, muss sie jedoch erst einmal ausgeführt werden, womit das Programm dann beendet ist.
6.3.5.9 Schleifen
Stellen Sie sich vor, Sie müssten ein- und denselben Code mehrmals ausführen. Ihn mehrmals einzutippen, wäre weder elegant noch flexibel, ist also keine gute Lösung. Wie gut, dass es Schleifen gibt: Die nämlich führen einen Block mehrmals hintereinander aus. Wann Schluss ist, können Sie genau festlegen.
6.3.5.9.1 Die for-Schleife
for-Schleifen werden auch "Zählschleifen" genannt, weil bei ihnen eine Variable immer weiter hochgezählt wird. Hat die Variable einen bestimmten Wert erreicht, so wird die Schleife beendet:
for (my $i = 0; $i < 10; $i++)
{
print $i;
}
> 0123456789

Innerhalb der Klammern der for-Schleife wird erst die Variable auf einen Startwert gesetzt, dann wird eine Bedingung formuliert, die gelten muss, solange die Schleife ausgeführt wird, und zum Schluss kommt noch das, was mit der Variable nach einem Schleifendurchlauf gemacht wird: hier wird sie jedes Mal um 1 erhöht. Die Teile werden mit einem Semikolon getrennt.
6.3.5.9.2 Die while-Schleife
Steigen wir direkt ein:
while($a == 10)
{
...
}
Die while-Schleife wird also ausgeführt, solange der Ausdruck in Klammern wahr ist.
foreach
Die foreach-Schleife dient dazu, eine Liste der Reihe nach abzuarbeiten:
my @liste = ('a', 'b');
foreach my $element (@liste)
{
print $element
}
> ab

Dabei kann die Variable natürlich frei gewählt werden. Übrigens wird der Zugriff auf alle Elemente eines Hashes praktisch immer mit foreach realisiert:
my %kunde;
$kunde{name} = "Meier";
$kunde{strasse} = "Mainweg";
$kunde{ort} = "Muenchhausen";
$kunde{telefon} = "44593";
foreach my $key (keys %kunde)
{
my $wert = $kunde{$key};
print "$key = $wert";
}
> telefon = 44593 ort = Muenchhausen strasse = Mainweg name = Meier

Trickreich, nicht wahr? Erst wird eine Liste aller Hash-Schlüssel erzeugt, dann wird diese Liste abgearbeitet und jedes Mal der zugehörige Wert ausgegeben.
6.3.5.10 Dateizugriff
Perl wurde entwickelt, um Dateien schnell verarbeiten zu können. Wir zeigen Ihnen, wie man Dateien zeilenweise einliest:
6.3.5.10.1 Datei lesen
my $dateiname = "/data/xyz.dat";
open(DATEI, '<'.$dateiname) or die "Kann $dateiname nicht öffnen";
while(<DATEI>)
{
my $zeile = chomp($_);
# Jetzt irgendwas mit der Zeile machen
}
close(DATEI);
open öffnet eine Datei. Das erste Argument ist dabei ein Name für das Dateihandle (kann ziemlich frei gewählt werden, pro Datei möglichst ein Handle), das zweite der Pfad zur Datei. Soll die Datei geöffnet werden, muss dem Pfad ein < vorangestellt werden. Eine or-Abfrage, ob die Datei erfolgreich geöffnet werden konnte, ist unverzichtbar!
Danach wird die Datei mit while ausgelesen: Bei jedem Aufruf gibt <DATEIHANDLE> die nächste Zeile von DATEIHANDLE zurück. Erst, wenn DATEIHANDLE am Ende ist, wird Falsch zurückgegeben.
Innerhalb der while-Schleife kann dann über die Variable $_ auf die aktuelle Zeile zugegriffen werden.
Am Ende eines Dateizugriffs steht immer das Schließen des Handles mit close.
6.3.5.10.2 Datei schreiben
Das Schreiben einer Datei verläuft sehr ähnlich:
# Was in die Datei rein soll?
my $towrite = "xyz";
my $dateiname = "/data/xyz.dat";
open(DATEI, '>'.$dateiname) or die "Kann $dateiname nicht öffnen";
print DATEI $towrite;
close(DATEI);
Der Unterschied zum Lesen: wir verwenden print für den Schreibvorgang und verwenden ein > anstelle eines <. Wer diesen Code ausführt, löscht den alten Inhalt der Datei. Wer das nicht möchte, ersetzt das > durch ein >>, dann werden die mit print geschriebenen Daten ans Ende der Datei gehängt.
6.3.5.10.3 Datei sperren
Stellen Sie sich vor, zwei Leute schreiben gleichzeitig eine Datei. Das kann nur zu Unordnung führen. Daher gibt es einen Mechanismus, Dateien zu sperren.
use Fcntl;
open(DATEI, '>'.$dateiname) or die "Kann $dateiname nicht öffnen";
flock(DATEI, LOCK_EX) or die "Kann $dateiname nicht sperren";
Danach geht es wie gewohnt weiter. Das macht aber nur dann Sinn, wenn nicht nur Schreib-, sondern auch Lesezugriffe gesperrt werden:
use Fcntl;
open(DATEI, '<'.$dateiname) or die "Kann $dateiname nicht öffnen";
flock(DATEI, LOCK_SH) or die "Kann $dateiname nicht sperren";
|
|
|
6.3.6
Fortgeschrittene Programmierkonzepte
Sie werden im Folgenden etwas über fortgeschrittene Programmierkonzepte erfahren. Soll heißen: Wenn Sie sich die Zeit nehmen, die hier vorgestellten Konzepte zu verstehen, werden Sie wirklich davon profitieren. Wir beginnen mit einer Möglichkeit, Perl-Code über verschiedene Dateien zu verteilen. Dabei beschreiben wir sowohl, wie man externe Perl-Module verwendet, als auch, wie selbst Code ausgelagert werden kann. Danach reißen wir das Thema der objektorientierten Programmierung kurz an. OOP ist oft unverzichtbar, wenn fremde Quellcodes oder von Anderen programmierte Klassen verwendet werden sollen. Wir beschränken uns dabei darauf, zu besprechen, wie OOP verwendet wird. Wie selbst OOP programmiert wird, würde den Rahmen dieses Kapitels sprengen.
6.3.6.1 Quellcode auslagern
Oft ist es hilfreich, Perl-Code über mehrere Dateien zu verteilen. Das schafft Übersicht. Es gibt in Perl zudem eine einfache Möglichkeit, auf den Code von anderen Programmierern, in Modulen gespeichert, zuzugreifen. So muss man das Rad nicht ständig neu erfinden. Die beiden Themen gehören zusammen, weil beide darauf angewiesen sind, auf irgendeine Art und Weise externe Dateien einzubinden.
6.3.6.1.1 Perl-Module
Perl-Module sind eine tolle Sache: Sie geben Zugriff auf ein unermessliches Archiv von vorprogrammierten Funktionen, CPAN genannt. Im CPAN finden sich Module für fast jede denkbare Anwendung, so z.B. für alle häufiger angewendeten Netz-Protokolle. Ein FTP-Server ist mit dem passenden CPAN-Modul beispielsweise gar kein Problem.
Wir wollen Ihnen nun zeigen, wie Module installiert und verwendet werden.
Module installieren
Zunächst einmal gilt es, sich das gewünschte Modul aus dem Netz zu besorgen. Das macht allerdings nur Sinn, wenn Sie auch administrativen Zugriff auf den Rechner verfügen, auf dem das Modul installiert werden soll. Wollen Sie dagegen ein Modul auf einem Internet-Server verwenden, so ist das nicht ohne Weiteres möglich: Das müssen Sie dann mit dem verantwortlichen Mitarbeiter des Providers abklären.
Wenn Sie ein Modul aber lokal installieren wollen, ist das nicht weiter schwierig: Unter Windows verwenden Sie einfach den ppm. Wie man ihn genau bedient, wird in der ActiveState-Perl-Anleitung erklärt. Hier nur die Kurzform: Sie klicken auf "Ausführen" im Start-Menü und geben in das Eingabefeld ppm ein. Sie bestätigen und eine Text-Konsole öffnet sich. Dort geben Sie install Modul-Name ein.
Wenn Sie ein anderes Betriebssystem verwenden, ist die Prozedur etwas komplexer: Zunächst einmal laden Sie sich das gewünschte Modul vom CPAN herunter. Module sind dort fast immer im .tar.gz-Format gespeichert.Enthalten ist eine Readme-Datei, die genau beschreibt, wie das Modul installiert werden kann. Normalerweise müssen Sie lediglich vier oder fünf Befehle ausführen, dann ist das Modul installiert. Kleiner Haken: Oft wird ein C-Compiler benötigt, der allerdings auf Unix-Systemen sowieso fast immer vorhanden ist.
Module verwenden
Verwenden Sie einfach den use-Befehl, um ein Modul einzubinden:
use CGI;
Um diesen Befehl verwenden zu können, müssen Sie den Namen des Moduls kennen, den Sie der Dokumentation entnehmen können. Es ist zusätzlich möglich, anzugeben, dass nur bestimmte Teile eines Moduls geladen werden sollen:
use CGI::Carp qw(fatalsToBrowser);
Module importieren die Funktionen, die sie zur Verfügung stellen, in den Namensraum, aus dem sie aufgerufen werden. Soll heißen: Wenn Sie ein Modul aufgerufen haben, können Sie seine Funktionen einfach direkt verwenden.
Die Funktionen eines Moduls
Nur woher erfahren Sie, welche Funktionen ein Modul bietet und wie diese verwendet werden? Die Antwort ist einfach und für Sie wahrscheinlich nicht befriedigend: Sie müssen die Dokumentation des Moduls durchgehen. Dort werden Sie meist auch Beispiele zur Verwendung finden. In diesem Tutorial besprechen wir lediglich die Verwendung von zwei Modulen, CGI und DBI.
6.3.6.1.2 Selbst Code auslagern
Wenn Sie nicht gerade selbst ein Modul programmieren wollen (das ist nicht ganz einfach) und Ihren eigenen Code trotzdem auf verschiedene Dateien aufteilen wollen, gibt es natürlich eine Möglichkeit.
Namensräume
Vorher jedoch müssen Sie noch etwas über Namensräume wissen. Beginnen wir mit einer simplen Aussage: Globale Variablen sind gar nicht global. Sie sind lediglich innerhalb ihres Packages einfach anzusprechen. Wenn Sie nicht explizit ein Package angeben, geht Perl davon aus, dass Sie das Standard-Package main verwenden wollen. Wenn Sie dagegen ein anderes Package verwenden wollen, müssen Sie den Namen des Packages im Variablen-Bezeichner angeben:
$variable = "abc";
# Das gleiche:
$main::variable = "abc";
Der Package-Name steht also am Anfang des Variablen-Bezeichners, gefolgt von einem doppelten Doppelpunkt.
Sie können selbstverständlich explizit angeben, wie das aktuelle Package heißen soll. Verwenden Sie dafür den Befehl package. Auch Package-übergreifende Zugriffe sind möglich, wie das nächste Beispiel zeigt.
Bitte beachten Sie: Variablen, die mit my erzeugt wurden, fallen nicht unter diesen Mechanismus. Sie sind innerhalb ihres Blocks verfügbar, nicht innerhalb ihres Packages.
Kommen wir nun zum eben angekündigten Beispiel:
package Variablen;
$eins = "a";
$zwei = "b";
package main;
print $Variablen::eins, $Variablen::zwei;
> ab

Code verteilen
Und wo ist der Zusammenhang zu unserem eigentlichen Thema? Wir schlagen vor, jeder einzelnen Datei ihren eigenen Package-Namen zu geben. Die Dateien sollten dabei ins gleiche Verzeichnis gelegt werden, damit der folgende Beispiel-Code funktioniert.
Inhalt der Datei test.pl:
require "datei1.pl";
print $p1::variable;
print &p1::funktion;
Inhalt der Datei datei1.pl:
package p1;
$variable = "test-variable ";
sub funktion
{
return "test-rückgabe";
}
Die Ausgabe:
> test-variable test-rückgabe
Sie sehen also: require bindet eine andere Datei ein. Um ärgerliche Probleme zu vermeiden, sollten Sie auf jeden Fall so vorgehen, wie in unserem Beispiel gezeigt, nämlich pro Datei ein Package zu definieren.
Wenn Sie trotzdem Fehlermeldungen angezeigt bekommen (das passiert dann, wenn das Arbeitsverzeichnis nicht gleich dem Verzeichnis ist, in dem das Script liegt), dann müssen Sie an den Anfang des Scripts ein chdir '/pfad/des/scripts'; stellen.
6.3.6.2 OOP in Perl
Um das gleich vorneweg zu stellen: wir gehen hier nicht darauf ein, wie selbst Klassen in Perl erstellt werden können. Wir beschränken uns darauf, zu zeigen, wie Objekte verwendet werden. Dieses Wissen benötigen Sie, weil beispielsweise viele Module ihre Schnittstelle ojektorientiert zur Verfügung stellen.
Wir wollen auch hier nicht weiter auf die Konzepte der OOP (Objektorientierten Programmierung) eingehen. Im JavaScript-Know-How-Kapitel gibt es dazu etwas detailliertere Informationen. Da dieses Tutorial jedoch auch ohne Lesen der JavaScript-Abschnitte verständlich sein soll, hier das wichtigste in Kürze: Klassen sind Baupläne für Objekte. Objekte können Funktionen und Variablen enthalten, OOP-spezifisch Methoden und Eigenschaften genannt. Von einer Klasse können beliebig viele Objekte konstruiert werden, dieser Vorgang wird Instanzierung genannt. Objekte werden in Variablen gespeichert.
6.3.6.2.1 new
Ein Objekt wird konstruiert, indem man das Schlüsselwort new verwendet:
my $cgi = new CGI;
Bitte lassen Sie sich von solchen Konstrukten nicht verwirren:
use CGI;
my $cgi = new CGI;
Die use-Anweisung hat nichts mit OOP zu tun. Sie bindet lediglich das CGI-Modul ein.
Die danach folgende Zeile dagegen hat eine Menge mit OOP zu tun: der Name der Variablen ist frei wählbar, dass hier Modulname, Klassenname und Variablenname übereinstimmen, ist keineswegs zwingend. Der Klassenname (das CGI hinter dem new) ist dagegen nicht frei wählbar, sondern durch die im CGI-Modul definierte Klasse vorgegeben. Oder, anders: alles, bis auf den Variablennnamen $cgi, ist nicht frei wählbar.
6.3.6.2.2 Zugriff auf Methoden und Eigenschaften
Sie greifen auf Methoden und Eigenschaften eines Objekts mit Hilfe des ->-Operators zu. Dabei ist es egal, ob es sich um eine Eigenschaft oder Methode handelt, der Operator wird immer in der gleichen Art und Weise verwendet:
use CGI;
my $query = new CGI;
# Jetzt: Zugriff auf Eigenschaft
# Übrigens: diese Eigenschaft existiert
# nicht wirklich, dient also nur
# als Beispiel
$query->eigenschaft = "abc";
# Oder auch: Eigenschaft auslesen
my $wert = $query->eigenschaft;
# Jetzt kommt die Methode (existiert
# übrigens wirklich)
# Auch Methoden können wie Funktionen Werte
# zurückgeben und mit Argumenten gefüttert
# werden.
my $parameter = $query->param('xyzz');
6.3.6.3 Fazit
Wenn Sie mit OOP und Modulen Probleme haben, wären Sie nicht der Erste. Es gibt kaum einen Perl-Beginner, der diese Konzepte im ersten Anlauf versteht. Die folgenden Abschnitte setzen beide Techniken ein: Sehen Sie sich die einfach einmal an, das wird helfen, wenn Sie noch Verständnisschwierigkeiten haben.
|
|
|
6.3.7
Datenbanken
Um den folgenden Abschnitt verstehen zu können, müssen Sie ein wenig über SQL wissen. Das sollte aber kein Problem sein, schließlich haben wir auch zu diesem Thema ein Kapitel.
6.3.7.1 Grundsätzliches
Um SQL-Datenbanken ansprechen zu können, müssen Sie über ein installiertes DBI-Modul verfügen. Wenn Sie Perl auf einem Webserver mit Datenbank-Unterstützung verwenden, ist das DBI-Modul meist schon vorinstalliert. Wenn Sie jedoch lokal testen wollen, kommen Sie um eine manuelle Installation des Moduls nicht herum. Unter Windows gibt es dazu den ppm von ActiveState, wer andere Betriebssysteme verwendet, lädt sich das Modul aus dem CPAN und befolgt die Anweisungen in der Readme-Datei.
Neben dem DBI-Modul selbst benötigt man noch einen zur Datenbank passenden DBD-Treiber. Auch den erhält man mit Hilfe des ppm oder über das CPAN.
Steigen wir nun in die Materie ein: zunächst muss das DBI-Modul eingebunden werden:
use DBI;
6.3.7.2 Datenbank ansprechen
Jetzt stellen wir eine Verbindung zur Datenbank her:
my $dbname=" ";
my $username=" ";
my $pw=" ";
my $data1 = "DBI:mysql:$dbname";
my $data2 = DBI->connect($data1, $username, $pw, { RaiseError => 1 }) || die("Kann DB nicht öffnen!");
Damit das funktioniert, müssen die drei Variablen am Anfang natürlich mit sinnvollen Werten gefüllt werden: Sie benötigen also einen Benutzernamen und ein Passwort. Ihr Provider bzw. Datenbank-Administrator wird Ihnen diese Daten mitteilen.
Das Beispiel ist übrigens für MySQL ausgelegt: Wenn Sie eine andere Datenbank verwenden, müssen Sie sich den passenden DBD-Treiber herunterladen und seinen Namen in die zweite Zeile von unten einsetzen.
Wenn ein Fehler bei der Datenbankverbindung auftritt, wird mit die eine Fehlermeldung ausgegeben. Ansonsten steht Ihnen mit $data2 nun ein Interface zur Datenbank zur Verfügung. Erinnern Sie sich, dass wir gesagt hatten, dass Variablen sehr flexibel in ihrem Inhalt sein können? Hier enthält die Variable nun ein Objekt.
6.3.7.3 Abfrage durchführen
Eine Abfrage funktioniert nach diesem Muster: Sie definieren eine SQL-Anweisung, die der Datenbank übergeben wird. Dann prüfen Sie, was die Datenbank als Ergebnis zurückliefert.
my $sql="SELECT * FROM test"; # SQL-Befehl
my $abfr1=$data2->prepare($sql);
$abfr1->execute;
# Datensätze abrufen
while (@ergf = $abfr1->fetchrow_array)
{
# Hier: Ergebnisse verarbeiten. Den Wert des ersten Daten-
# feldes des aktuellen Datensatzes finden Sie unter
# $ergf[0], den des zweiten unter $ergf[1], den des dritten
# unter $ergf[2] usw.
}
$abfr1->finish;
Dort, wo die Kommentarzeilen stehen, müssen Sie also etwas mit den Ergebnissen machen. Jeder Durchlauf der while-Schleife holt sich einen neuen Datensatz und schreibt die Werte der Datenfelder der Reihe nach in @ergf.
6.3.7.4 Anfrage durchführen
Anfragen brauchen Sie, wenn Sie z.B. etwas in die Datenbank schreiben wollen. Das Muster ähnelt dabei sehr dem der Anfrage:
my $sql="DROP TABLE Test"; # SQL-Befehl
eval {
my $anfr=$data2->prepare($sql);
$anfr->execute;
};
if ($@)
{
die "Fehler: $@!";
}
Wie funktioniert dieser Code? Wir haben den Teil, in dem auf Gültigkeit des SQL-Befehls geprüft wird, in ein eval-Konstrukt verpackt. Dadurch werden Fehler abgefangen. Gleichzeitig wäre es aber leichtsinnig, Ihr Programm trotz eines möglichen Fehlers nicht zu unterbrechen. Daher die Prüfung der Variable $@, die nur einen Wert enthält, wenn die vorherige Anweisung einen Fehler zurücklieferte.
6.3.7.5 Verbindung schließen
Nicht vergessen werden sollte das Schließen der Datenbank-Verbindung am Ende Ihres Programms:
$data2->disconnect;
6.3.7.6 Beispiel-Programm
Wir stellen Ihnen nun ein kleines, vollständiges Beispiel-Programm vor. Es geht davon aus, dass Sie eine Adressen-Datenbank mit den Datenfeldern name, wohnort und telefon betreiben. Diese Datenbank heißt im Beispiel adressen.
# HTML-Header und Begrüßung
print "Content-type: text/html\n\n";
print "Guten Tag! Ihre Adress-Datenbank:<br><br>";
print "<table>";
print "<tr><th>Name</th><th>Wohnort</th><th>Telefonnummer</th></tr>";
use DBI;
# Hier richtige Angaben eintragen!
my $dbname="test";
my $username="root";
my $pw="";
# Datenbank öffnen
my $data1 = "DBI:mysql:$dbname";
my $data2 = DBI->connect($data1, $username, $pw, { RaiseError => 1 }) || die("Kann DB nicht öffnen!");
# SQL-Anweisung
my $sql="SELECT * FROM adressen";
my $abfr1=$data2->prepare($sql);
$abfr1->execute;
# Datensätze abrufen
while (@ergf = $abfr1->fetchrow_array)
{
my $name = $ergf[0];
my $ort = $ergf[1];
my $telefon = $ergf[2];
# qq kann sich über mehrere Zeilen erstrecken:
print qq(
<tr>
<td>$name</td>
<td>$ort</td>
<td>$telefon</td>
</tr>
);
}
print "</table>";
$abfr1->finish;
Wir werden dieses Programm im nächsten Abschnitt noch etwas erweitern.
|
|
|
6.3.8
Interaktion mit der Umgebung
Perl ist ein guter Nachbar, heißt es. Daher wollen wir Ihnen nun einige Möglichkeiten zeigen, über den Tellerrand des Perl-Programms hinauszublicken.
6.3.8.1 Andere Programme starten
Manchmal ist es nützlich, ein anderes Programm für seine eigenen Zwecke zu verwenden. In Perl gibt es drei verschiedene Möglichkeiten, ein anderes Programm zu starten:
6.3.8.1.1 exec
Die exec-Funktion führt ein externes Programm aus und kehrt dabei nicht zum Perl-Programm zurück, solange kein Fehler aufgetreten ist.
exec('notepad.exe');
6.3.8.1.2 system
system funktioniert wie exec, mit dem Unterschied, dass system zum Perl-Programm zurückkehrt.
6.3.8.1.3 Backticks
Wer ein Programm nicht nur ausführen, sondern auch seine Ausgaben an die Standard-Ausgabe (STDOUT) sammeln will (das funktioniert nur bei Kommandozeilen-basierten Programmen), verwendet am besten den Backtick-Mechanismus:
my $output = `dir c:`;
print $output;
6.3.8.2 CGI
6.3.8.2.1 Zugriff
Das CGI-Modul hilft beim Zugriff auf CGI-Daten und bei der Erzeugung von HTML-Dateien. Glücklicherweise ist es in der Perl-Standarddistribution enthalten, kann also ohne vorherige Installation genutzt werden. Sie werden hier wieder auf Objekte treffen: Zunächst wird ein CGI-Objekt erzeugt, dann wird mit Hilfe seiner Methoden auf die CGI-Daten zugegriffen. Diese Daten sind in Form einzelner Parameter abgespeichert. Der Zugriff darauf funktioniert wie hier zu sehen:
use CGI;
my $cgi_objekt = new CGI;
my $parameter = $cgi_objekt->param('parameter-name');
6.3.8.2.2 Übergabe von Daten
Das CGI-Modul bietet noch viele andere Funktionen, die jedoch für einen Perl-Einsteiger nicht weiter wichtig sind. Wir belassen es daher bei der Erklärung der param-Methode. Bleibt eventuell die Frage offen, wie Sie überhaupt Daten via CGI übergeben können.
Nehmen wir an, Sie hätten das letzte Beispiel-Programm auf Ihren Webserver gelegt. Es ist nun unter der URL http://www.xyz.de/cgi-bin/script.pl erreichbar. Das CGI-Protokoll unterscheidet zwei Modi: GET und POST. Der GET-Modus wird verwendet, wenn Parameter an die URL angehangen werden. Das könnte dann so aussehen:
http://www.xyz.de/cgi-bin/script.pl?parameter-name=abc&nochn_parameter=a
Die POST-Methode wird üblicherweise im Zusammenspiel mit HTML-Formularen verwendet:
<form action="http://www.xyz.de/cgi-bin/script.pl" method="post">
Bitte Wert eingeben: <input type="text" name="parameter-name">
<input type="submit">
</form>
6.3.8.2.3 Beispiel-Programm
Wir haben unseren Adressmanager aus dem Datenbank-Abschnitt noch etwas erweitert: nun können auch neue Daten hinzugefügt werden.
use CGI;
my $cgi = new CGI;
my $modus = $cgi->param('Modus');
print "Content-type: text/html\n\n";
print "Guten Tag! Ihre Adress-Datenbank:<br><br>";
print "<table>";
print "<tr><th>Name</th><th>Wohnort</th><th>Telefonnummer</th></tr>";
use DBI;
my $dbname="test";
my $username="root";
my $pw="";
my $data1 = "DBI:mysql:$dbname";
my $data2 = DBI->connect($data1, $username, $pw, { RaiseError => 1 }) || die("Kann DB nicht öffnen!");
# Wenn der Modus add ist, dann neue Daten hinzufügen
if ($modus eq "add")
{
# SQL-Anweisung konstruieren:
my $n = $cgi->param('name');
my $o = $cgi->param('ort');
my $t = $cgi->param('telefon');
my $sql = qq(INSERT INTO adressen VALUES("$n", "$o", "$t"));
eval {
my $anfr=$data2->prepare($sql);
$anfr->execute;
};
if ($@)
{
die "Fehler beim Hinzufügen: $@!";
}
}
my $sql="SELECT * FROM adressen";
my $abfr1=$data2->prepare($sql);
$abfr1->execute;
# Datensätze abrufen
while (@ergf = $abfr1->fetchrow_array)
{
my $name = $ergf[0];
my $ort = $ergf[1];
my $telefon = $ergf[2];
# qq kann sich über mehrere Zeilen erstrecken:
print qq(
<tr>
<td>$name</td>
<td>$ort</td>
<td>$telefon</td>
</tr>
);
}
print "</table>";
$abfr1->finish;
# Code für Formular
print qq(
<br><br>
<b>Neuen Datensatz hinzufügen</b>
<form>
<input type="hidden" name="Modus" value="add">
Name:
<input type="text" name="name"><br>
Ort:
<input type="text" name="ort"><br>
Telefon:
<input type="text" name="telefon"><br>
<input type="submit">
</form>
);
|
|
|
|