mit Perl - der Friedrich-List

Werbung
Dynamische Webseiten (CGI)
mit Perl
Teile der Präsentation von A. Grupp, [email protected]
Planung der Inhalte?
 Ein Perl-Crashkurs
 Eine Einführung in die Welt der Protokolle
anhand http
 Eine Einführung in das Common Gateway Interface
 Entwicklung webbasierender Applikationen mit
Datenbankanbindung (SQL-Server)
Dynamisch? CGI? Sonst noch was?
Verwendete Software








Linux als Serverbetriebssystem
Apache-Webserver als Serverprogramm (httpd)
Texteditor
ftp-Client (WS_FTP-LE)
Browser (MSIE od. Netscape)
Standard-Perl-Interpreter
Apache-Servererweiterung mod_perl
MySQL-Datenbankserver
HTML ohne Perl!
 Der Browser nimmt die URL in der Adressleiste entgegen
 und leitet sie in Form einer http-Anfrage an den Webserver
(httpd) weiter. Dabei sprechen beide die Sprache "http"!
 Der Server stellt die gewünschte Information zusammen
und leitet sie wieder auf "http-ianisch" an den Browser
zurück.
HTML mit Perl (CGI)




Die Anfrage geht nicht an eine statische Datei
Es wird vielmehr über den httpd ein Programm aufgerufen
Dieses erzeugt dynamisch Daten (z.B. HTML)
Die "frisch" erzeugten Daten gehen über den httpd an den
Anfragenden zurück
HTML-File zum Aufruf des CGI-Programms
„world.pl“
<html>
<body bgcolor="#ffffff" text="#000000">
<h1>Hello world</h1>
Ein Klick auf den grauen Knopf listet das<br>
CGI-Programm world.pl auf.<br>
<p>
<form action="cgi-bin/world.pl" method="post">
<input type="submit" value="Programm aufrufen">
</form>
</body>
</html>
CGI-Programm „world.pl“


Ein Problem ist allerdings dass der httpd im Gegensatz zu *.html- oder *.gif-Dateien
keine Ahnung hat welche Art von Daten das CGI-Skript produziert.
Diese Information (letzte Zeile des http-Headers) muß deshalb vom CGI-Skript über
den Content-Type selbst geliefert werden.
#!/usr/bin/perl -w
use strict;
print "Content-type: text/html\n";
print "\n";
print "<html><head><title>Hello world</title>";
print "</head><body>";
print "<h1>Willkommen beim CGI-Programm</h1>\n\n";
print "<h1>Hello world</h1>\n";
print "</body></html>";
Umgebungsvariablen
Ein installierter Webserver stellt eine bestimmte Anzahl von
CGI-Umgebungsvariablen zur Verfügung, denen vom System
bei jedem Aufruf eines CGI-Programms gewisse Werte
zugewiesen werden.
Andererseits kann auch ein CGI-Programm diesen Variablen
Werte zuweisen, die dann innerhalb des CGI-Programms
verwendet werden können.
CGI-Umgebungsvariablen existieren immer und sind
vollständig unabhängig von anderen selbstdefinierten
Variablen.
Zugriff auf die Umgebungsvariablen in Perl:
print $env(‘Name_der_Umgebungsvariablen‘)
Umgebungsvariable - CONTENT_LENGTH
In der Variablen CONTENT_LENGTH wird die Anzahl der Zeichen
gespeichert, die beim Aufruf des CGI-Programms über die Methode
post übergeben wurden.
HTML-Dokument mit CGI - Aufruf:
<html>
<head><title>Umgebungsvariable - CONTENT_LENGTH</title></head>
<body>
<h1>Testformular</h1>
<form action=„cgi-bin/test.pl“ method=post>
Name: <input size=40 maxlength=40 name=“AnwenderName“><br>
Text: <textarea rows=% cols=70 name=„Kommentartext“ wrap=virtual></textarea><p>
<input type=submit value=“Absenden“>
</form>
</body>
</html>
Umgebungsvariable - CONTENT_LENGTH
CGI-Skript test.pl mit HTML-Ausgabe
#!/usr/bin/perl
read(STDIN, $DATEN, $ENV{‘CONTENT_LENGTH‘});
print “CONTENT-type: text/html\n\n“;
print “<html><head><title>CGI-Reaktion</title></head>\n“;
print „<body><h1>Reaktion des CGI-Programms</h1>\n“;
print $env{‘CONTENT_LENGTH‘};
print “</body></html>\n“;
Weiter Umgebungsvariablen
CONTENT_TYPE
GATEWAY_INTERFACE
HTTP_ACCEPT
HTTP_REFERER
HTTP_USER_AGENT
QUERY_STRING
REMOTE_HOST
REQUEST_METHOD
SCRIPT_NAME
SERVER_NAME
SERVER_PORT
SERVER_SOFTWARE
# gibt Auskunft über den verwendeten MIME-Typ
# Versionsnummer der unterstützten CGI-Schnittstelle
# Liste der MIME-Typen (Dateitypen), welche der Browser
# verarbeiten kann
# URL-Adresse von der aus das CGI-Skript aufgerufen wurde
# Informationen über den Browser
# Wird ein HTML-Formular von einem Anwender ausgefüllt
und abgesendet, so stehen in der Umgebungsvariablen
QUERY_STRING die ausgefüllten Formulardaten
# Domain-Adresse des Server-Rechners
# Versandmethode post oder get
# URL-Adresse des CGI-Skripts
# Name oder IP-Adresse des Servers
# Portnummer des WebServers
# Produktsoftware des WebServes
Übungsaufgabe
Erstellen Sie analog der Umgebungsvariablen CONTENT_LENGTH,
das entsprechende HTML-Formular bzw. Perl-Skript zur Ausgabe
verschiedener Umgebungsvariablen.
HTML-Formular zur Ausgabe
verschiedener Umgebungsvariablen
<html>
<body bgcolor="#ffffff" text="#000000">
<h1>Umgebungsvariablen</h1>
Ein Klick auf den grauen Knopf listet alle<br>
Umgebungsvariablen unseres lokalen Webservers<br>
auf. Die Installation und Einrichtung wurde<br>
bereits in Teil I dieses Buches besprochen.<p>
<form action="cgi-bin/env.pl" method="post">
<input type="submit" value="ENV auflisten">
</form>
</body>
</html>
Eine mögliche Lösung zum env.pl
#!/usr/bin/perl
# Bei Apache unter Windows #!c:/Perl/bin/perl.exe
# Art der Daten
print "Content-Type: text/html\n\n";
# Seitenbeginn und Tabelle
print "<html>\n<body>\n";
print "<table>\n";
print "<tr>\n<th>Schlüssel</th>\n";
print "<th>Wert</th>\n</tr>\n";
# die einzelnen Wertepaare
while(@array=each(%ENV))
{
# Tabellenzeile
print "<tr>\n<td>";
print "$array[0]</td>\n<td>";
print "$array[1]</td>\n</tr>\n";
}
# Seitenende
print "</table>\n</body>\n</html>";
Formulare in HTML (1)
Formulare in HTML (2)
...
<form action=“cgi-bin/test.pl" method="get">
<p>Nachname:<input type="text" name="nname"></p>
<p>Vorname:<input type="text" name="vname"></p>
<p><input type=reset
value="Kommando zurück"></p>
<p><input type=submit value="Haben fertig ..."></p>
</form>
...
Der "type" legt die Art
des Formularelements
fest
Jedes Formular-Element ist mit
einem "Namen" versehen
Formulare in HTML (3)
...
<form action=“cgi-bin/test.pl" method="get">
<p>Nachname:<input type="text" name="nname"></p>
<p>Vorname:<input type="text" name="vname"></p>
<p><input type=reset
value="Kommando zurück"></p>
<p><input type=submit value="Haben fertig ..."></p>
</form>
...
Der "action"-Parameter des <form>Tags legt fest welche URL für die
Verarbeitung der Formulardaten
zuständig ist wenn die "submit"Schaltfläche gedrückt wird.
Formulare in HTML (4)
Bei Verwendung der "get"-Methode werden die Formulardaten
einfach an den URL angehängt:
test.pl nname=
Muster
?
&
vname=
Hugo
 http://<server>/<akt.-Verz.>/test.pl?nname=Muster&vname=Hugo
Der httpd und die Formulardaten
http://<server>/<akt.-Verz.>/test.pl?nname=Muster&vname=Hugo
Der Webserver erkennt nun anhand des Fragezeichens im URL
den für ihn relevanten Teil. Er trennt den Anhang - unseren
Planwagentreck - ab und stellt diesen dem CGI-Skript als Inhalt
der Umgebungsvariablen QUERY_STRING zur Verfügung.
Der URL für den httpd: http://<server>/<akt.-Verz.>/test.pl
QUERY_STRING = nname=Muster&vname=Hugo
Der Inhalt dieser Umgebungsvariablen ist unsern CGI-Skripten
über $ENV{'QUERY_STRING'} zugänglich und kann nun
weiterverarbeitet werden.
Verarbeitung des QUERY_STRING's
Zum Zerlegen der Zeichenkette wird die Funktion split() verwendet
split(/&/, $ENV{'QUERY_STRING'}
('nname=Meier&vname=Hans&ort=Tettnang
''
''
')
,
,
&
&
Das Ergebnis der split()-Funktion ist
somit ein "anonymes" Feld
Verarbeitung des QUERY_STRING's
Zum Zerlegen der Zeichenkette wird die Funktion split() verwendet
('nname=Meier&vname=Hans&ort=Tettnang
''
''
')
,
,
Dieses anonyme Feld wird nun in einem benannten Feld
(z.B @formulardaten) abgespeichert:
@formulardaten = split(/&/, $ENV{'QUERY_STRING'}
nname=Meier
vname=Hans
$formulardaten[0]
ort=Tettnang
$formulardaten[2]
$formulardaten[1]
Verarbeitung des QUERY_STRING's
Zum Zerlegen der Zeichenkette wird die Funktion split() verwendet
('nname=Meier&vname=Hans&ort=Tettnang
''
''
')
,
,
Dieses anonyme Feld wird nun in einem benannten Feld
(z.B @formulardaten) abgespeichert:
@formulardaten = split(/&/, $ENV{'QUERY_STRING'}
nname=Meier
vname=Hans
$formulardaten[0]
ort=Tettnang
$formulardaten[2]
$formulardaten[1]
Das CGI-Skript im Überblick
#!/usr/bin/perl -w
use strict;
my (@formulardaten, $formfeld, $name, $wert, %feld);
@formulardaten = split(/&/, $ENV{'QUERY_STRING'});
foreach $formfeld (@formulardaten){
($name, $wert) = split(/=/, $formfeld);
$feld{$name} = $wert;
}
print "Content-Type: text/html\n\n";
print "<html><head><title>Hallo</title></head>";
print "<body><h1>" .
"Hallo $feld{'vname'} $feld{'nname'}" .
"</h1></body></html>";
Das Formular im Überblick
<html><head><title>Formulartest CGI</title></head>
<body><p>Bitte geben Sie Ihren Namen ein:</p>
<form method="get" action=“cgi-bin/test.pl">
<table><tr>
<td>Nachname:</td>
<td><input type="text" size="20" name="nname"></td>
</tr><tr>
<td>Vorname:</td>
<td><input type="text" size="20" name="vname"></td>
</tr>
</table>
<p><input type="submit" value="Absenden"></p>
</form>
</body>
</html>
Nächste Übungsaufgabe!
 Erstellen Sie ein HTML-Formular mit vier Eingabefeldern zur Erfassung des
Vornamen, Nachnamen, Strasse und Wohnort von Personen
 Programmieren Sie ein Perl-CGI-Skript zur Verarbeitung der Formulardaten.
Das Skript gibt beispielsweise nach Eingabe von:
Nachname:
Vorname:
Strasse:
Wohnort:
Mustermann
Franz
Hauptstr.16
Ulm
im Browser das Feedback
Hallo Franz Mustermann!
Sie wohnen in der Hauptstr.16 in Ulm
zurück.
MIME-Codierung im URL (I)
 In einem URL dürfen nur druckbare Zeichen aus dem
Standard-ASCII-Zeichensatz (0-127) auftreten. Insbesondere
nationale Sonderzeichen (z.B. äöüßÄÖÜßàá) sind verboten.
 Auch Leerzeichen können in einem URL nicht auftreten.
 Diverse Zeichen wie beispielsweise %+&= sind bereits für
andere Aufgaben vorgesehen und können ebenfalls so nicht
direkt auftauchen.
Für all diese Zeichen gibt es deshalb eine andere
Darstellungsform entsprechend dem
RFC2396 "Uniform Resource Identifiers (URI): Generic Syntax".
MIME-Codierung im URL (II)
 Ein Leerzeichen wird deshalb zu einem '+'
 Nationale Sonderzeichen werden durch ihre hexadezimale
Darstellung entsprechend ASCII-Zeichensatz dargestellt. Zur
Erkennung dieser Hex-Zeichen wird ein "%" vorangestellt.
Damit ergibt sich beispielsweise für den Buchstaben "Ö"
innerhalb eines URL's die Kodierung "%D6".
Aus "Karl Österle" wird damit "Karl+%D6sterle"
MIME-Codierung im URL (III)
Ein möglicher Code zur Rücktransformation dieser Darstellung
sieht folgendermaßen aus:
$wert =~ tr/+/ /;
$wert =~ s/%([a-fA-F0-9]{2})/pack("C", hex($1))/eg;
 Mittels der translate-Operation "tr//" werden alle "+" Zeichen in
ein Leerzeichen umgewandelt.
 Die substitute-Operation "s//" sucht zuerst nach dem
Suchmuster "%hexhex" und merkt sich dabei die beiden
gefundenen Hex-Zeichen in der Perl-Variablen $1 (das "Merken"
wird dabei duch die beiden runden Klammern bewerkstelligt).
Mittels hex() wird $1 dann in eine Binärzahl und diese wiederum
durch pack() in ein Zeichen umgewandelt.
MIME-Codierung im URL (IV)
#!/usr/bin/perl -w
use strict;
my (@formulardaten, $formfeld, $name, $wert, %feld);
@formulardaten = split(/&/, $ENV{'QUERY_STRING'});
foreach $formfeld (@formulardaten){
($name, $wert) = split(/=/, $formfeld);
$wert =~ tr/+/ /;
$wert =~ s/%([a-fA-F0-9]{2})/pack("C", hex($1))/eg;
$feld{$name} = $wert;
}
print "Content-Type: text/html\n\n";
print "<html><head><title>Hallo</title></head>";
print "<body><h1>" .
"Hallo $feld{'vname'} $feld{'nname'}" .
"</h1></body></html>";
Datentransfer mit POST -Request (I)
 Größere Datenmengen (lange Texte, Dateiuploads, ...) können nicht
mehr an den URL angehängt werden
 In solchen Fällen werden die Daten im Datenbereich eines httpPOST-Requests übertragen.
POST /cgi-bin/test.pl HTTP/1.1
Host: www.nowhere.com
Content-Length: 23
nname=Muster&vname=Hugo
Datentransfer mit POST -Request (II)
 Die Daten eines POST-Requests stehen uns nun leider nicht mehr
in der Umgebungsvariablen QUERY_STRING zur Verfügung.
 Es müssen stattdessen die richtige Anzahl an Zeichen (Wert steht
in der Umgebungsvariablen CONTENT_LENGTH) von der
Standardeingabe eingelesen werden.
read(STDIN, $daten, $ENV{'CONTENT_LENGTH'});
Die Daten die ursprünglich in der Umgebungsvariablen
QUERY_STRING zur Verfügung standen sind nun im Skalar
$daten enthalten. Das Format hat sich dabei nicht geändert!
Datentransfer mit POST -Request (III)
 Über die Umgebungsvariable REQUEST_METHOD kann ein Skript
sogar feststellen welche Methode im Formular verwendet wurde.
 Damit ist ein universelles Einlesen der Formulardaten möglich:
if($ENV{'REQUEST_METHOD'} eq 'GET'){
$daten = $ENV{'QUERY_STRING'};
}
else{
read(STDIN, $daten, $ENV{'CONTENT_LENGTH'});
}
@formulardaten = split(/&/, $daten);
 Formular fertig !!! 
#!/usr/bin/perl -w
use strict;
my (@formulardaten, $formfeld, $name, $wert, $daten, %feld);
if($ENV{'REQUEST_METHOD'} eq 'GET'){
$daten = $ENV{'QUERY_STRING'}; }
else{
read(STDIN, $daten, $ENV{'CONTENT_LENGTH'});}
@formulardaten = split(/&/, $daten);
@formulardaten = split(/&/, $ENV{'QUERY_STRING'});
foreach $formfeld (@formulardaten){
($name, $wert) = split(/=/, $formfeld);
$wert =~ tr/+/ /;
$wert =~ s/%([a-fA-F0-9]{2})/pack("C", hex($1))/eg;
$feld{$name} = $wert;
}
print "Content-Type: text/html\n\n";
print "<html><head><title>Hallo</title></head>";
print "<body><h1>Hallo $feld{'vname'} $feld{'nname'}".
"</h1></body></html>";
Datenbank-Anbindung unter Windows (I)
- Erstellen Sie in ACCESS eine Datenbank mit zwei Tabellen und je drei Spalten.
- Jede Tabelle benötigt einen eindeutigen Schlüssel (key), der die einzelnen Datensätze identifiziert.
Tabelle Adressen:
Adressenlisten-Nr (key)Vorname
1
Walter
2
Frank
3
Tester
4
Willi
5
Robert
Nachname
Müller
Testmann
Testmensch
Wuff
Mustermayer
Tabelle Rechnungen
- Hier wird gespeichert , welche Person welche Artikel gekauft hat.
RechnungsNr (key)
1
2
3
4
5
Adressenlisten-Nr
- Datenbank speichern unter C:\perltest\testdb.mdb
1
1
3
2
2
Artikelname
Eis
Butter
Eis
Salat
Margarine
Datenbank-Anbindung unter Windows (II) - ODBC
- Um die Datenbank von Perl aus ansprechen zu können, muss diese dem Betriebssystem zugänglich gemacht
werden.
- ODBC-Manager (Open Database Connectivity) - Zugriff auf eine Datenbank ohne das zugehörige Programm
Konfiguration des ODBC - Managers:
- Systemsteuerung / ODBC-Datenquellen (32bit) / System DNS
- Hinzufügen / Microsoft Access-Treiber (*.mdb)
- Fertigstellen
- Weitere Informationen:
- Datenquellenname (Name mit dem wir die Datenbank mit Perl über
ODBC später ansprechen). Beispiel: Testdatenbank.
- Beschreibung
- Datenbank
(Auswählen / C:\perltest\testdb.mdb)
- Zugriff auf die ACCESS - Datenbank
- Abfragen starten
- Daten hinzufügen
- Daten löschen
Datenbank-Anbindung unter Windows (III) - SQL
Ziel: Wir möchten wissen, welche Artikel Walter Müller gekauft hat?
Weg: Abfrage erstellen.
SQL: Abfragen werden mit einer eigenen Sprache für Datenbanken, SQL, geschrieben und können jeder Datenbank
gestellt werden. Ob wir hier also ACCESS, Oracle oder MySQL verwenden, spielt für die Abfrage keine Rolle.
Grundgerüst einer Abfrage :
SELECT werte FROM tabellen WHERE bedingungen;
Einfachste Form einer Abfrage:
SELECT * FROM Adressen;
Lösung:
SELECT Rechnungen.Artikelname
FROM Adressen, Rechnungen
Where Adressen.Vorname=Walter AND
Adressen.Nachname=Müller AND
Adressen.AdressenlistenNr=Rechnungen.AdressenlistenNr;
Anmerkung:
Da die Felder Vorname und Nachname eventuell in mehreren Tabellen vorkommenm, muss bei der Verwendung
mehrerer Tabellen für die Suche vor alle Felder immer der Name der zugehörigen Tabelle geschrieben werden. Als
Trennzeichen dient ein Punkt. Die Verknüpfung zwischen den beiden unabhängigen Tabellen erfolgt nun über den
Schlüssel AdressenlistenNr. Dieser muss in beiden Tabellen vorhanden und identisch sein.
Datenbank-Anbindung unter Windows (IV) - Win32::ODBC
Win32::ODBC: Reines Windows Objekt bzw. Klasse. Beinhaltet alle erforderlichen Funktionen für den Umgang mit
einer Datenbank. Methoden repräsentieren die Fähigkeiten eines jeden Objektes. Eine Methode wird immer mit der
Pfeilnotation aufgerufen.: Bsp: $auto ->geschwindigkeit();
Beispiel 1 (Erste Verbindung mit der Datenbank):
#!/usr/bin/perl
use Win32::ODBC;
$dsn = "Testdatenbank";
# Variable dsn speichert den Namen unserer Datenbank
### TEIL I
if($db = Win32::ODBC ->new($dsn))
# Aufruf der Methode new.
{
print "Verbindung zu $dsn hergestellt.\n";
}
else
{
print "Verbindung zu $dsn fehlgeschlagen!\n";
print "Fehler: " . Win32::ODBC::Error() . "\n";
exit;
}
### TEIL II
$db->Close();
Datenbank-Anbindung unter Windows (V) - Abfragen
Beispiel 2 (Einfache Ausgabe aller Personen aus der Tabelle Adressen!):
#!/usr/bin/perl
use Win32::ODBC;
$dsn="Testdatenbank";
### TEIL I
if(!($db = Win32::ODBC ->new($dsn)))
# Entfernung des else Teils. Anstelle einer Erfolgsmeldung wird ein
{
# Abfrage Ergebnis ausgegeben!
print "Verbindung zu $dsn fehlgeschlagen!\n";
print "Fehler: " . Win32::ODBC::Error() . "\n";
exit;
}
### TEIL II
# Else Teil (Abfrage Ergebnis) beginnt bei erfolgreichem DB-connect!
$sql = "SELECT * FROM Adressen";
# Definition der SQL-Abfrage in der Variablen $sql
### TEIL III
if(!($db->Sql($sql)))
# Durchführung der eigentlichen Abfrage durch den Aufruf der Methode SQL()
{
# die als Parameter die zuvor gespeicherte Abfrage $sql erhält.
print "Fehler bei SQL-Abfrage!\n";
# Liefert die Abfrage keinen Rückgabewert beginnt Teil IV ansonsten Fehlerprint "Fehler: ".$db->Error()."\n";
# meldung!
$db->Close();
exit;
}
### TEIL IV
# Ergebnis - Ausgabe in einer mehrspaltigen Tabelle. Für die Ausgabe wird nun
while($db->FetchRow())
# jede Zeile mit Hilfe der Methoden FetchRow() und DataHash() in ein Hash
{
# gespeichert. FetchRow () liefert immer eine ganze Zeile, DataHash()
%hash = $db->DataHash();
# zerlegt diese Zeile in einzelne Hash-Elemente.
print "\n".$hash{"AdressenlistenNr"};
# Dieser Vorgang wird innerhalb einer while-Schleife solange wiederholt, bis
print " ".$hash{"Vorname"};
# alle Zeilen der Ergebnis-Tabelle ausgegeben worden sind. Ist keine weitere
print " ".$hash{"Nachname"};
# Zeile mehr vorhanden, liefert FetchRow() einen unwahren Rückgabewert
}
# und die Schleife wird beendet.
print "\n";
### TEIL V
# Verbindung zur Datenbank wird getrennt
$db->Close();
Datenbank-Anbindung unter Windows (VI) - Abfragen
Beispiel 3 (Ausgabe aller Artikelnamen die von Walter oder Willie gekauft wurden)
#!/usr/bin/perl
use Win32::ODBC;
$dsn="Testdatenbank";
### TEIL I
if(!($db=Win32::ODBC->new($dsn)))
{
print "Verbindung zu $dsn fehlgeschlagen!\n";
print "Fehler: " . Win32::ODBC::Error() . "\n";
exit;
}
### TEIL II
$sql = "SELECT Adressen.Vorname,Rechnungen.Artikelname FROM Adressen,Rechnungen WHERE
Adressen.AdressenlistenNr=Rechnungen.AdressenlistenNr AND (Adressen.Vorname='Walter'
OR Adressen.Vorname='Willie')";
### TEIL III
if($db->Sql($sql))
{
print "Fehler bei SQL-Abfrage!\n";
print "Fehler: ".$db->Error()."\n";
$db->Close();
exit;
}
### TEIL IV
while($db->FetchRow())
{
%hash = $db->DataHash();
print "\n".$hash{"Artikelname"};
print " (".$hash{"Vorname"}.")";
}
print "\n";
### TEIL V
$db->Close();
Datenbank-Anbindung unter Windows (VII) - Datensatz einfügen
Beispiel 4 (Einfügen eines neuen Datensatzes)
#!/usr/bin/perl
use Win32::ODBC;
$dsn="Testdatenbank";
### TEIL I
if(!($db=Win32::ODBC->new($dsn)))
{
print "Verbindung zu $dsn fehlgeschlagen!\n";
print "Fehler: " . Win32::ODBC::Error() . "\n";
exit;
}
### TEIL II
$sql = "INSERT INTO Adressen (Vorname,Nachname) VALUES ('Max','Mayer')";
### TEIL III
if($db->Sql($sql))
{
print "Fehler bei SQL-Abfrage!\n";
print "Fehler: ".$db->Error()."\n";
$db->Close();
exit;
}
print "Ein Datensatz hinzugefügt.\n";
### TEIL IV
$db->Close();
Datenbank-Anbindung unter Windows (VIII) - Datensatz entfernen
Beispiel 5 (Entfernen eines Datensatzes)
#!/usr/bin/perl
use Win32::ODBC;
$dsn="Testdatenbank";
### TEIL I
if(!($db=Win32::ODBC->new($dsn)))
{
print "Verbindung zu $dsn fehlgeschlagen!\n";
print "Fehler: " . Win32::ODBC::Error() . "\n";
exit;
}
### TEIL II
$sql = "DELETE * FROM Adressen WHERE Vorname LIKE 'W%'";
### TEIL III
if($db->Sql($sql))
{
print "Fehler bei SQL-Abfrage!\n";
print "Fehler: ".$db->Error()."\n";
$db->Close();
exit;
}
print "Datensatz (-saetze) entfernt.\n";
### TEIL IV
$db->Close();
MySQL Datenbank-Anbindung mit Perl - DBI / DBD
- Ähnlich wie ODBC, das Zugriff auf jede Datenbank unter Windows ermöglicht
- ermöglicht DBI , das sog. Perl Datenbank Interface den Datenbankzugriff auf MySQL-Datenbanken
- dabei kommuniziert das Interface mit einem Datenbank Treiber, dem DBD.
Installation der Perl DBI und der MySQL DBD
Perl besteht aus einer Reihe von Modulen. Jedes Modul erweitert die Fähigkeiten von MySQL. Es sind
eine große Menge von Modulen für Perl verfügbar.
Unter Windows:
Nachdem sie Perl installiert haben, wechseln sie in das Perl - Verzeichnis. Hier finden Sie ein
Unterverzeichnis namens bin. Suchen Sie nach dem PPM-Programm (Perl Package Manager), dieses
kleine Programm findet Perl Module im Internet, lädt diese auf die lokale Festplatte und installiert sie
automatisch.
Um die DBI zu installieren, doppelklicken sie auf die PPM-Datei. Daraufhin öffnet sich ein DOS-Fenster.
Stellen Sie eine Verbindung mit dem Internet her und geben sie folgendes ein:
PPM> install DBI
#Installation des DBI-Interface beginnt.
Nach erfolgreicher Installation können sie den DBD-Treiber installieren:
PPM> install DBD-MySQL
MySQL Datenbank-Anbindung mit Perl - DBI / DBD
Unter Linux:
1. Downloaden Sie das DBI sowie das DBD von der MySQL-Webseite (www.mysql.com) und kopieren Sie
sie in das Verzeichnis /home/perl
2. Entpacken Sie die DBI-Datei
3. Nach dem erfolgreichen Entpacken können Sie die Datei kompilieren. Wechseln Sie hierfür in das neu
erstellte DBI-1.11 Verzeichnis.
4. Erstellen Sie die make-Datei:
shell> perl Makefile.pl
5. Einfügen des Moduls in die richtigen Verzeichnisse:
shell> make
# Einige Daten fliegen über den Bildschirm
shell>make test
# Bildschirm füllt sich erneut mit einer Menge Daten
shell> make install
# Erfolgreiches Installieren des Perl DBI ?!?
6. Entpacken Sie die DBD-Datei, wie sie es auch mit der DBI-Datei gemacht haben, ändern Sie lediglich
den Dateinamen.
7. Nach dem Entpacken geben sie folgende Anweisung ein:
shell> perl Makefile.pl
8. Sie sollten nun mit 5 verschiedenen Auswahlmöglichkeiten konfrontiert sein. Wählen Sie folgende
Möglichkeit: MySQL and mSQL (either of mSQL 1 or mSQL 2)
# mSQL ist ein früher Vorgänger von MySQL
9. Beantworten Sie im folgenden alle ihnen gestellten Fragen und beobachten Sie den TestDatenbankaufbau, nachdem sie einen Benutzernamen, das Passwort und einen Hostnamen eingeben
haben.
Erstes Perl Script zur MySQL Datenbank-Anbindung
#!usr/bin/perl -w
use DBI;
$dbh = DBI->connect ('DBI:mysql:ohlhauser_db:localhost', 'root','')
or die "Fehler beim Verbinden mit Datenbank : $DBI::errstr\n";
# Einfügen der Werte
# $dbh->do führt die in Klammern stehende Anweisung sofort aus. Diese Methode wird
# verwendet für Anweisungen wie INSERT, UPDATE, CREATE oder DROP.
$dbh->do("INSERT INTO schueler (name, vorname, geschlecht, geboren, betrieb)
VALUES ('Haug','Uli','m','1982-01-01','Boss')");
# Verbindung zur Datenbank schließen
$dbh->disconnect;
exit;
Das Datenbank-Handle: $dbh
Das Datenbank-Handle, $dbh, hat viele Methode, die mit ihm assoziert werden können:
•$dbh->do(SQL-Anweisung)
Diese Anweisung führt die in Klammern stehende SQL-Anweisung sofort aus. Diese Methode wird
verwendet, wenn sie Anweisungen wie INSERT, UPDATE, CREATE oder DROP, die keinen
Ergebnissatz zurückgeben, benutzen.
•$dbh->prepare(SQL-Anweisung)
Diese Anweisung generiert ein Anweisungs-Handle. Es verfügt über Methoden und Eigenschaften,
die verwendet werden können, um die darin enthaltenen Daten zu beschreiben und zu
manipulieren.
1. execute(): Diese Methode führt die SQL-Anweisung aus, die in der prepare Methode übergeben
wurde.
2. fetchrow_hashref(): Diese Methode gibt ein assoziatives Array mit den Werten des
Ergebnissatzes in einer Name=Wert-Paar-Relation zurück.
3. finish(): Diese Anweisung zerstört das Anweisungs-Handle und gibt Ressourcen wieder frei.
4. rows(): Diese Anweisung gibt die Anzahl der Datensätze zurück, die ein Ergebnis enthalten
•$dbh->disconnect
Diese Anweisung schließt die Verbindung zur Datenbank.
Die prepare()-Methode und das Anweisungs-Handle
#!usr/bin/perl -w
use DBI;
$dbh = DBI->connect ('DBI:mysql:ohlhauser_db:localhost', 'root','')
or die "Fehler beim Verbinden mit Datenbank : $DBI::errstr\n";
$sth = $dbh->prepare("SELECT * From schueler WhERE betrieb='Boss'");
# Erstellen des Anweisungs-Handle und Übergabe an die Variable $sth
$sth->execute();
# Anfrage wird an die Datenbank gesendet und ein Ergebnissatz zurückgegeben
while($ref = $sth->fetchrow_hashref())
{
print "$ref->{'name'} $ref->{'vorname'}";
print "\n";
}
$sth->finish();
$dbh->disconnect;
exit;
# Jede Datenzeile wird durchlaufen
# und ausgegeben!
# Übungsaufgabe: Führen Sie weitere Abfragen aus!!!
CGI, Perl, DBI und MySQL
Aufgabe: Erstellen einer Webseite, die Daten über ein Formular abfragt und diese anschließend in die schuelerTabelle der nachname_db Datenbank einfügt.
HTML-Quellcode des Formulars
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Language" content="en-us">
<meta name="GENERATOR" content="Mozilla/4.75 [de] (Windows NT 5.0; U) [Netscape]">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Vendor</title>
</head>
<body>
<form method=post action= "cgi-bin/schueler.pl"> 
<table BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH="555" HEIGHT="27" >
<tr>
<td COLSPAN="3" WIDTH="824" HEIGHT="27">
<center><b>Wilhelm-Schickard-Schule Tübingen</b></center><br>
</td>
</tr>
<tr>
<td COLSPAN="3" WIDTH="524" HEIGHT="27">
<center><b>Hinzufügen von neuen IT-Schülern in die MySQL-Datenbank nachname_db<br>
Bitte das Formular ausfüllen!</b></center>
</td>
</tr>
<tr>
<td><br></td>
</tr>
HTML-Quellcode des Formulars
<tr>
<td COLSPAN="3" WIDTH="524" HEIGHT="27" BGCOLOR="#9C9C4E"><b> Name: </b><input
type="text" name="Nachname" size="51"></td>
</tr>
<tr>
<td COLSPAN="3" WIDTH="524" HEIGHT="27" BGCOLOR="#9C9C4E"><b>Vorname: </b><input
type="text" name="Vorname" size="51"></td>
</tr>
<tr>
<td COLSPAN="3" WIDTH="50" HEIGHT="27" BGCOLOR="#9C9C4E"><b>Geschlecht: </b><input
type="text" name="Geschlecht" size="20"></td>
</tr>
<tr>
<td COLSPAN="3" WIDTH="524" HEIGHT="27"
BGCOLOR="#9C9C4E"><b>geboren:    </b><input type="text"
name="Geboren" size="51"></td>
</tr>
<tr>
<td COLSPAN="3" WIDTH="524" HEIGHT="27" BGCOLOR="#9C9C4E"><b>Betrieb: </b><input
type="text" name="Betrieb" size="51"></td>
</tr>
<tr><td><br></td>
</tr>
<tr>
<td COLSPAN="3" WIDTH="801" HEIGHT="27"><input type="submit" value="Submit"
name="B1"><input type="reset" value="Reset" name="B2"></td>
</tr>
</table>
</form>
</body>
</html>
Perl-Skript, um Daten in die Datenbank einzufügen (schueler.pl)
#!/usr/bin/perl
use DBI;
############################################################################
# Connect to the MySQL WEB database
#
############################################################################
$dbh = DBI->connect ('DBI:mysql:ohlhauser_db:localhost', 'root','')
or die "Fehler beim Verbinden mit Datenbank : $DBI::errstr\n";
%postInputs = readPostInput();
$Nachname = $postInputs{'Nachname'};
$Vorname = $postInputs{'Vorname'};
$Geschlecht = $postInputs{'Geschlecht'};
$Geboren = $postInputs{'Geboren'};
$Betrieb = $postInputs{'Betrieb'};
$dbh->do("INSERT INTO schueler VALUES('$Nachname', '$Vorname',
'$Geschlecht', '$Geboren',
'$Betrieb')");
$dbh->disconnect;
Fortsetzung: Perl-Script, um Daten in die Datenbank einzufügen
############################################################################
# Subroutine für die Verarbeitung des Post Request in einen assoziativen
#
# array. Quellcode für alle CGI-Applikation gleich.
#
############################################################################
sub readPostInput{
my (%searchField, $buffer, $pair, @pairs);
if ($ENV{'REQUEST_METHOD'} eq 'POST'){
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
foreach $pair(@pairs){
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-f0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$name =~ tr/+/ /;
$name =~ s/%([a-fA-f0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$searchField{$name} = $value;
}
}
return (%searchField);
}
# Bestätigungsmeldung an den Browser, dass der Schüler erfolgreich in die Datenbank
# eingetragen ist
print
print
print
print
"Content-Type: text/html\n\n";
"<html><head><title>Datensatz hinzugefügt</title></head>";
"<body>Der Schüler ist hinzugefügt</body>";
"</html>";
Herunterladen