Webbasierte Adressdatenbank
AdressDB die Zweite
Das Script gibt es hier, einfach anklicken,
und als adress_2.pl abspeichern.
Für die ganz Ungeduldigen jetzt eine Kurzanleitung zur Installation: Zuerst holt man sich die Module DBI,
Text::CSV_XS, SQL::Statement und DBD::File entweder vom CPAN oder von ActiveState und installiert wie in
Installation von Perl Modulen beschrieben. Dann Skript ins cgi-bin Verzeichnis des
Webservers stellen und ausführbar machen (Linux Rechte 755). Beim ersten Mal mit adress_2.pl?init=1 aufrufen,
damit das Datenbankfile erstellt wird.
Eine Darstellung der Bildschirmausgabe spare ich mir, da hier keine Veränderungen gegenüber der Version 1
entstanden sind. Mein Versprechen das Skript würde nur ca 150 Zeilen lang lies sich allerdings nicht halten.
Jetzt liegen wir bei ca 270 Zeilen Code. Dafür ist das Programm auch für Ungeübte besser lesbar.
Wie funktioniert's?
Es haben sich nur dort Änderungen gegenüber adress_1.pl ergeben, wo auf die Daten zugegriffen wird. Wir benutzen
das DBI Modul und den DBD für eine Flatfile Datenbank. Die dazu notwendigen Variablen werden in Zeile 24-30 definiert.
in Zeile 36 verbinden wir uns mit der Datenbank. Alle Unterprogramme, die auf die Datenbank zugreifen, bekommen beim
Aufruf das Datenbankhandle $dbh
übergeben. In den Zeilen 40-62 verzweigen wir, je nach
gesetzten Parametern in die entsprechenden Unterprogramme. Um Daten Einzufügen oder zu Ändern
( &Einfuegen
), verwenden wir die UPDATE bzw INSERT Anweisung. Sollen Daten gelöscht werden
( &Loeschen
) definieren wir eine entsprechende SQL Anweisung in Zeile 163 und führen sie in
Zeile 165 aus. Das Suchen ( &Suchen
) ist jetz wesentlich einfacher, wir müssen nicht mehr das
ganze Textfile einlesen, sondern können mit einer SELECT Anweisung auf die Daten zugreifen (Zeile 186ff). Vorher
legen wir noch die Bedingung zum Suchen in der WHERE Anweisung fest (Zeile 178ff). Auch die Routine zum Füllen der
Eingabemaske mit Daten, wenn eine Änderung ansteht, läßt sich mit einer SELECT Anweisung (Zeile 236ff) durchführen.
Die notwendigen Parameter füllen wir aus eine Hashreferenz (Zeilen 243-245), die wir mit der
$row=$sth->fetchrow_hashref
Anweisung aus der Datenbank mit Daten belegen. Neu hinzugekommen
ist die Routine &init_db
. Hier erzeugen wir ein Verzeichnis addressbook
unterhalb des cgi-bin
Verzeichnises, in dem unser Perl Programm liegt. Dies hat den Vorteil,
daß die, den Webserver ausführende Instanz dort auch Schreibrechte hat. Allerdings vom Standpunkt der Sicherheit
aus gesehen ist dies eher bedenklich, da wir aber erst einmal grundsätzlich verstehen wollen, wie das Skript arbeitet, soll uns
die Sicherheit im Moment weniger belasten.
Das Skript adress_2.pl
1: #!/usr/bin/perl -w 2: 3: use CGI qw/:standard :netscape/; 4: use CGI::Carp qw/fatalsToBrowser/; 5: use strict; 6: use DBI; 7: 8: ################################################## 9: # adress_2.pl Copyright 1999 Dr. Thomas Wieland 10: # wieland@k-town.de 11: # fuer den Perl-Stammtisch im Rahmen des 12: # 1. Pirmasenser Internetclubs 13: ################################################## 14: 15: 16: ################################################## 17: # Variablendeklaration 18: ################################################## 19: 20: # Methode der Datenuebergabe im Formular GET oder POST 21: # POST, wenn Daten in URL nicht auftauchen sollen 22: my $method = 'GET'; 23: 24: my $DB_DIR = "./addressbook"; 25: my $DB_DSN = "DBI:CSV:f_dir=$DB_DIR"; 26: my $DB_USER = ""; 27: my $DB_PASSWD = ""; 28: 29: my @dbfields = qw/fname lname phone email street plz addr/; 30: my $dbflist = join(', ', @dbfields); 31: 32: print header(), 33: start_html(-BGCOLOR => 'white', 34: -title => 'Adress DB die Zweite'); 35: 36: my $dbh = DBI->connect($DB_DSN, $DB_USER, 37: $DB_PASSWD, { RaiseError => 1 }); 38: 39: 40: if (param('insert')) { 41: &Einfuegen($dbh, map { param($_) } @dbfields); 42: &Ueberschrift; 43: &Suchformular; 44: } elsif (param('delete')) { 45: &Loeschen($dbh); 46: &Ueberschrift; 47: &Suchformular; 48: } elsif (defined param('search')) { 49: &Ueberschrift; 50: &Suchen($dbh); 51: } elsif (param('edit')) { 52: &Ueberschrift; 53: &get_data($dbh); 54: &Eingabeformular; 55: } elsif(param('init')) { 56: &Ueberschrift; 57: &Suchformular; 58: init_db($dbh); 59: } else { 60: &Ueberschrift; 61: &Suchformular; 62: } 63: 64: print end_html(); 65: 66: $dbh->disconnect; 67: 68: ################################################## 69: sub Ueberschrift { 70: ################################################## 71: print center(h1("Adress DB die Zweite")), 72: hr; 73: } 74: 75: ################################################## 76: sub Suchformular { 77: ################################################## 78: print start_form(-method => $method), 79: p(a({href => url() . "?search="}, 80: " Alle Einträge")), 81: p("Suchbegriff: ", 82: textfield(-name => 'lname')), 83: p(" Bitte Nachname oder Vorname oder ". 84: "Anfangsbuchstabe eingeben (Groß und ". 85: "Kleinschreibung beachten)! "), 86: p(submit(-name => 'search', 87: -value => 'Suche starten'), 88: submit(-name => 'edit', 89: -value => 'Neuer Eintrag')), 90: end_form(); 91: } 92: 93: ################################################## 94: sub Eingabeformular { 95: ################################################## 96: print start_form(-method => $method), 97: hidden(-name => 'id'), 98: table({"border" => 1}, 99: TR(td("Vorname:"), 100: td(textfield(-name => 'fname', -size => 40))), 101: TR(td("Nachname:"), 102: td(textfield(-name => 'lname', -size => 40))), 103: TR(td("Telefon:"), 104: td(textfield(-name => 'phone', -size => 40))), 105: TR(td("Email:"), 106: td(textfield(-name => 'email', -size => 40))), 107: TR(td("Straße:"), 108: td(textfield(-name => 'street', -size => 40))), 109: TR(td("PLZ:"), 110: td(textfield(-name => 'plz', -size => 10))), 111: TR(td("Ort:"), 112: td(textfield(-name => 'addr', -size => 40))), 113: ), 114: p(submit(-name => 'insert', 115: -value => 'Speichern'), 116: submit(-name => 'delete', 117: -value => 'Eintrag löschen')), 118: end_form(); 119: } 120: 121: ################################################## 122: sub Einfuegen { 123: ################################################## 124: my ($dbh, $fname, $lname, $phone, 125: $email, $street, $plz, $addr) = @_; 126: 127: # id existiert Eintrag aendern 128: if (param('id')) { 129: my $id = param('id'); 130: 131: my $sql = qq[ 132: UPDATE addressbook 133: SET id='$id', fname='$fname', 134: lname='$lname', phone='$phone', 135: email='$email', street='$street', 136: plz='$plz', addr='$addr' 137: WHERE id = '$id']; 138: 139: $dbh->do($sql); 140: 141: # keine id vorhanden hinzufuegen 142: } else { 143: my $id = time . $$; # Generate ID 144: 145: my $sql = qq[ 146: INSERT INTO addressbook 147: (id, $dbflist) 148: VALUES ('$id', '$fname', '$lname', '$phone', 149: '$email', '$street', '$plz', '$addr')]; 150: 151: $dbh->do($sql); 152: } 153: 154: # alle Parameter param('..') loeschen 155: Delete_all(); 156: } 157: 158: ################################################## 159: sub Loeschen { 160: ################################################## 161: my $dbh = shift; 162: my $id = $dbh->quote(param('id')); 163: my $sql = qq[ DELETE FROM addressbook 164: WHERE id = $id]; 165: $dbh->do($sql); 166: 167: # alle Parameter param('..') loeschen 168: Delete_all(); 169: } 170: 171: ################################################## 172: sub Suchen { 173: ################################################## 174: my ($dbh) = shift; 175: my $where_clause = ""; 176: my ($sth, $row); 177: 178: # Wurde ein Suchparameter eingegeben 179: if (param('lname')) { 180: my $keyword = $dbh->quote(param('lname')."%"); 181: $where_clause = qq[ 182: WHERE fname CLIKE $keyword OR 183: lname CLIKE $keyword]; 184: } 185: 186: my $sql = qq[ SELECT id, $dbflist 187: FROM addressbook 188: $where_clause 189: ORDER BY lname]; 190: 191: $sth = $dbh->prepare($sql); 192: 193: $sth->execute(); 194: 195: print "<center><TABLE BORDER=1>\n"; 196: print TR(map { th($_) } 197: qw/Name Telefon Email Straße PLZ Ort/); 198: 199: while ($row = $sth->fetchrow_arrayref) { 200: print "\n<TR>", 201: td(a({href => url() . "?id=$row->[0]&edit=1"}, 202: "$row->[2], $row->[1]")); 203: if ($row->[3]) { print td($row->[3]); 204: } else { print td(" ") 205: }; 206: if ($row->[4]) { print td(a({href => "mailto:$row->[4]"}, 207: "$row->[4]")); 208: } else { print td(" ") 209: }; 210: if ($row->[5]) { print td($row->[5]); 211: } else { print td(" ") 212: }; 213: if ($row->[6]) { print td($row->[6]); 214: } else { print td(" ") 215: }; 216: if ($row->[7]) { print td($row->[7]); 217: } else { print td(" ") 218: }; 219: } 220: print "</table>", 221: hr, a({href => url()}, "Zurück zum Anfang"), 222: "</center>"; 223: 224: $sth->finish(); 225: # alle Parameter param('..') loeschen 226: Delete_all(); 227: } 228: 229: ################################################## 230: sub get_data { 231: ################################################## 232: my $dbh = shift; 233: my ($key, $row); 234: if (defined(param('id'))) { 235: my $id = param('id'); 236: my $sql = qq[ SELECT id, $dbflist FROM addressbook 237: WHERE id = '$id' ]; 238: 239: my $sth = $dbh->prepare($sql); 240: $sth->execute; 241: 242: while ($row = $sth->fetchrow_hashref) { 243: foreach $key (keys %{$row}) { 244: param(-name => $key, -value => $row->{$key}); 245: } 246: } 247: } 248: } 249: 250: ################################################## 251: sub init_db { 252: ################################################## 253: my $dbh = shift; 254: 255: if(! -d $DB_DIR) { 256: mkdir($DB_DIR, 0755) || 257: die "Cannot create dir $DB_DIR"; 258: } 259: 260: my $sql=qq[CREATE TABLE addressbook ( 261: id char(20), fname char(40), 262: lname char(40), phone char(40), 263: email char(40), street char(40), 264: plz char(10), addr char(100) 265: )]; 266: 267: $dbh->do($sql); 268: }
Literaturhinweise:
- O Reilly Perl Module Doku
- perldoc CGI
Zurück zum Anfang dieses Projekts.