cgi und Datenbank
ashbury
- cgi
0 Helmut Weber0 marc0 Helmut Weber0 ashbury0 Helmut Weber0 marc0 Helmut Weber0 marc
Hi, ich verwende bisher erfolgreich und sehr gerne cgi basierte Formulare. Die Daten der html Formulare werden mir somit als Email zugesendet und dem Benutzer ebenfalls. Frage: ist es grundsätzlich möglich - ohne viel Aufwand -, dass diese Formulardaten in eine Datenbank (mysql) eingelesen werden?
Gruß and alle!
Hallo ashbury,
Grundsätzlich JA!
Ohne Informationen zur verwendeten Programmiersprache lässt sich aber nicht viel mehr dazu sagen.
Zum Beispiel in Perl:
CPAN-Module DBI und DBD::mysql.
Gruß
Helmut Weber
Hallo Helmut,
könnte ich Dir mal ein einfaches Skript von mir schicken und Du sagst mir obs und wies geht!?! Das wäre supi!
Danke und Gruß, Marc
Hallo ashbury,
Grundsätzlich JA!
Ohne Informationen zur verwendeten Programmiersprache lässt sich aber nicht viel mehr dazu sagen.
Zum Beispiel in Perl:
CPAN-Module DBI und DBD::mysql.Gruß
Helmut Weber
Hallo Marc,
könnte ich Dir mal ein einfaches Skript von mir schicken und Du sagst mir obs und wies geht!?! Das wäre supi!
Lass uns Dein Problem doch hier im Forum lösen, dann haben evtl. auch Andere etwas davon ;)
Eine ausführliche Dokumentation zum DBI-Modul findest Du im CPAN unter:
http://search.cpan.org/~timb/DBI-1.48/DBI.pm
Du kannst die relevanten Code-Abschnitte deines Skriptes mit den dazugehörigen Fehlermeldungen gerne hier im Forum posten, oder bei langen Skripten diese hier verlinken.
Ich bin sicher, dass die Gemeinschaft des Forums Dir schneller und effektiver helfen kann als ich alleine!
Gruß
Helmut Weber
Hi nochmal, also hier das Skript, welches z.Zt. gut läuft. Es fehlt eben eine SQL Anbindung, damit die Daten 001-016 eingelesen werden können.
#! /usr/local/bin/perl
print "Content-type: text/html\n\n";
$mailprog="/usr/lib/sendmail";
%daten=&Eingabe;
%datum=&zeit;
$parameter = &Formateingaben(%daten);
$empfaenger="test@test.de";
if (!$daten{'001 Kongressgebühr'}) { &fehler("Kongressgebühr"); }
if (!$daten{'002 Anrede'}) { &fehler("Anrede"); }
if (!$daten{'004 Vorname'}) { &fehler("Vorname"); }
if (!$daten{'005 Name'}) { &fehler("Name"); }
if (!$daten{'009 PLZ'}) { &fehler("PLZ"); }
if (!$daten{'010 Ort'}) { &fehler("Ort"); }
if (!$daten{'011 Bundesland'}) { &fehler("Bundesland"); }
if (!$daten{'012 Telefon'}) { &fehler("Telefon"); }
if (!$daten{'014 E-Mail'}) { &fehler("E-Mail"); }
open (MAIL, "|$mailprog $empfaenger") || die "Kann Mailprogramm in $mailprog nicht finden: $! \n";
print MAIL "From: $daten{'014 E-Mail'} ($daten{'004 Vorname'} $daten{'005 Name'})\n";
print MAIL "Reply-To: $daten{'014 E-Mail'}\n";
print MAIL "To: $empfaenger\n";
print MAIL "Subject: Anmeldung zum Kongress\n\n";
print MAIL "Hallo, ich bin der automatische Formularauswerter.\n\n";
print MAIL "Am $datum{'datum'} um $datum{'uhr'} hat sich ein Teilnehmer in das Anmeldeformular eingetragen. Nachfolgend die Daten:\n\n";
print MAIL "001 Kongressgebühr: $daten{'001 Kongressgebühr'}\n";
print MAIL "002 Anrede: $daten{'002 Anrede'}\n";
print MAIL "003 Titel: $daten{'003 Titel'}\n";
print MAIL "004 Vorname: $daten{'004 Vorname'}\n";
print MAIL "005 Name: $daten{'005 Name'}\n";
print MAIL "006 Institution: $daten{'006 Institution'}\n";
print MAIL "007 Strasse: $daten{'007 Strasse'}\n";
print MAIL "008 Hausnummer: $daten{'008 Hausnummer'}\n";
print MAIL "009 PLZ: $daten{'009 PLZ'}\n";
print MAIL "010 Ort: $daten{'010 Ort'}\n";
print MAIL "011 Bundesland: $daten{'011 Bundesland'}\n";
print MAIL "012 Telefon: $daten{'012 Telefon'}\n";
print MAIL "013 Fax: $daten{'013 Fax'}\n";
print MAIL "014 E-Mail: $daten{'014 E-Mail'}\n";
print MAIL "015 Homepage: $daten{'015 Homepage'}\n";
print MAIL "016 Info: $daten{'016 Info'}\n";
close (MAIL);
open (MAIL, "|$mailprog $daten{'014 E-Mail'}") || die "Kann Mailprogramm in $mailprog nicht finden: $! \n";
print MAIL "From: $empfaenger\n";
print MAIL "Reply-To: $empfaenger\n";
print MAIL "To: $daten{'014 E-Mail'}\n";
print MAIL "Subject: Ihre Anmeldung zum Kongress\n\n";
print MAIL "Hiermit bestätigen wir Ihnen die Anmeldung.\n\n";
print MAIL "Am $datum{'datum'} um $datum{'uhr'} haben Sie das Anmeldeformular ausgefüllt.\n";
print MAIL "Nachfolgend Ihre Anmeldedaten:\n\n";
print MAIL "001 Kongressgebühr: $daten{'001 Kongressgebühr'}\n";
print MAIL "002 Anrede: $daten{'002 Anrede'}\n";
print MAIL "003 Titel: $daten{'003 Titel'}\n";
print MAIL "004 Vorname: $daten{'004 Vorname'}\n";
print MAIL "005 Name: $daten{'005 Name'}\n";
print MAIL "006 Institution: $daten{'006 Institution'}\n";
print MAIL "007 Strasse: $daten{'007 Strasse'}\n";
print MAIL "008 Hausnummer: $daten{'008 Hausnummer'}\n";
print MAIL "009 PLZ: $daten{'009 PLZ'}\n";
print MAIL "010 Ort: $daten{'010 Ort'}\n";
print MAIL "011 Bundesland: $daten{'011 Bundesland'}\n";
print MAIL "012 Telefon: $daten{'012 Telefon'}\n";
print MAIL "013 Fax: $daten{'013 Fax'}\n";
print MAIL "014 E-Mail: $daten{'014 E-Mail'}\n";
print MAIL "015 Homepage: $daten{'015 Homepage'}\n";
print MAIL "016 Info: $daten{'016 Info'}\n";
close (MAIL);
my (@x)=split(/\n/,$parameter);
foreach $i (@x)
{
($k,$v)=split(/: /,$i);
$str.="<td align=right>$k</td><td align=left>$v</td><tr>\n" if $k;
}
print <<EOF;
<html>
<head>
<title>Kongress</title>
</head>
<body bgcolor=eff3f5>
<table cellpadding="10">
<td>
<font size=3 face=ARIAL>Wir bedanken uns für Ihre Anmeldung.</font><br>
<br>
<table>
<td align=left width="569"><font color=000000 face=ARIAL><font size=+1>Ihr Formular wurde abgeschickt.</font><br>
<font size=3 face=ARIAL><font color=#000000>Sollten Sie Änderungen vornehmen wollen,können Sie die "Zurück/BACK-Schaltfläche" Ihres Browsers oder den <a href="javascript:history.back()" target="_self">zurück</a> Link nutzen.<br>
Als Bestätigung erhalten Sie eine E-Mail von uns mit den hier angegebenen Daten. Gleichzeitig können Sie diese Seite auch <a href="javascript:self.print()">ausdrucken</a>.<br>
</font></td>
</table>
<br>
<div align="center">
<font size=3 face=ARIAL>Folgende Daten haben Sie in das Formular eingetragen:<br>
<table width="573" table cellpadding="4" border=1 align="left" bgcolor=#c1ced7>
$str
<tr>
<td> </td>
</tr>
</table>
</body></HTML>
EOF
sub Formateingaben
{
local (*in) = @_ if @_ == 1;
local (%in) = @_ if @_ > 1;
local ($out, $key, $output);
$output = "\n\n";
foreach $key (sort keys(%in))
{
foreach (split("\0", $in{$key}))
{
($out = $_) =~ s/\n/\n/g;
$output .= "$key: $out\n";
}
}
$output .= "\n";
return $output;
}
sub Eingabe
{
if ($ENV{'QUERY_STRING'})
{
$daten=$ENV{'QUERY_STRING'};
} else
{ read (STDIN, $daten, $ENV{'CONTENT_LENGTH'}); }
if (@ARGV) { @datensaetze=@ARGV; } else {
@datensaetze = split(/&/, $daten); }
foreach $satz (@datensaetze)
{
($name, $wert) = split(/=/, $satz);
$wert =~ tr/+/ /;
$wert =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$wert =~ s/<(([^ >]|\n)*)>//g;
$name =~ tr/+/ /;
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
chomp $wert;
$wert=~s/\n/<br>/g;
$FORM{$name} = $wert;
}
return %FORM;
}
sub fehler
{
my $fehler_grund=$_[0];
print "<p><center><table border=5>\n";
print "<td bgcolor=#c1ced7 align=center width=440><h1><font color=#ff3060><u></u></font></h1>";
print "<font color=#000000><font size=+1>- Sie haben ein wichtiges Feld nicht ausgefüllt -</font><p>";
print "Drücken Sie die Zurück/BACK-Schaltfläche Ihres Browsers oder den <a href='javascript:history.back()' target=_self>zurück</a></font> Link und vervollständigen bzw. korrigieren ";
print "Sie das Feld<br> <font color=#ff3060><strong>$fehler_grund</strong></font>.<br><br>";
print "</table>";
exit;
}
sub zeit
{
local(@z)=localtime;
foreach $i (@z) { if (length($i)<2) { $i="0".$i; } }
local(%azeit);
local($uhr)="$z[2]:$z[1]:$z[0]";
local($monat)=($z[4]+1);
if (length($monat)<2) { $monat="0".$monat; }
$z[5]=(1900+$z[5]);
local($datum)="$z[3].$monat.$z[5]";
$azeit{'uhr'}=$uhr;
$azeit{'datum'}=$datum;
return %azeit;
}
Hallo Marc,
Dein Skript liest Formulardaten ein, verschickt diese per E-Mail und stellt diese per HTML auf dem Browser dar.
Soweit waren wir ja schon ;)
Jetzt nehm ich mal an, dass Du die Daten dauerhaft speichern möchtest. Bevor Du Dir Gedanken über eine Datenbank machst, musst Du überlegen, für welchen Zweck Du die Daten dauerhaft speichern möchtest. Evtl. ist es viel Einfacher die Daten in einer Textdatei zu speichern, um diese später wieder auszulesen.
Solltest Du nach dieser Überlegung zum Entschluss kommen, Du benötigst unbedingt eine Datenbank, so musst Du Dir um folgende Dinge Gedanken machen:
Dann musst Du Dir deine Datenbank und die Datentabellen einrichten, und erst dann geht es an die programmtechnische Umsetzung.
Diese Arbeiten kann bzw. möchte ich Dir nicht abnehmen. Wenn Du mir in einem Skriptbeispiel zeigts, wie Du versucht hast die Daten in eine Datenbank anzulegen, dann kann ich Dir helfen den Fehler zu finden. Aber die Grundgedanken musst Du schon selbst erarbeiten.
Gruß
Helmut Weber
Hallo Helmut, danke für Deine Antwort. Ich hatte Dich zunächst falsch verstanden. Selbstverständlich hatte ich schon versucht, eine Datenbankanbindung zu erreichen. Bisher ohne Erfolg. Aber zunächst zum grundsätzlichen:
Ich habe einmal ein ganz einfaches Beispiel erzeugt:
Eine Fehlermeldung erhalte ich immerhin nicht, wenn ich das ganze auf meinem Server teste, trotzdem enden die Daten nicht in der Tabelle auf dem Server.
Vielleicht kannst Du nochmal das jetzige Skript begutachten. Der relevante teil ist wohl #Datenbank Anbindung. Vielen Dank! marc
Das ganze sieht dann so aus:
#! /usr/local/bin/perl
print "Content-type: text/html\n\n";
$mailprog="/usr/lib/sendmail";
%daten=&Eingabe;
%datum=&zeit;
$parameter = &Formateingaben(%daten);
if (!$daten{'Kongressgebühr'}) { &fehler("Kongressgebühr"); }
use CGI;
use DBI;
my $DB_NAME = "db_test";
my $DB_DSN = "DBI:mysql:database=$DB_NAME";
my $DB_USER = "User_test";
my $DB_PASSWD = "Passwort_test";
my $dbh = DBI->connect($DB_DSN, $DB_USER, $DB_PASSWD) or die "Fehler bei Datenbankverbindung: $!";
my $sql = "INSERT INTO test VALUES ('$daten')";
my $sth = $dbh->prepare( $sql ) ||
die "Kann Statement nicht vorbereiten: $DBI::errstr\n";
$dbh->disconnect;
my (@x)=split(/\n/,$parameter);
foreach $i (@x)
{
($k,$v)=split(/: /,$i);
$str.="<td align=right>$k</td><td align=left>$v</td><tr>\n" if $k;
}
print <<EOF;
<html>
<head>
<title>Kongress</title>
</head>
<body bgcolor=eff3f5>
<table cellpadding="10">
<td>
<font size=3 face=ARIAL>Wir bedanken uns für Ihre Anmeldung.</font><br>
<br>
<table>
<td align=left width="569"><font color=000000 face=ARIAL><font size=+1>Ihr Formular wurde abgeschickt.</font><br>
</table>
<br>
<div align="center">
<font size=3 face=ARIAL>Folgende Daten haben Sie in das Formular eingetragen:<br>
<table width="573" table cellpadding="4" border=1 align="left" bgcolor=#c1ced7>
$str
<tr>
<td> </td>
</tr>
</table>
</body></HTML>
EOF
sub Formateingaben
{
local (*in) = @_ if @_ == 1;
local (%in) = @_ if @_ > 1;
local ($out, $key, $output);
$output = "\n\n";
foreach $key (sort keys(%in))
{
foreach (split("\0", $in{$key}))
{
($out = $_) =~ s/\n/\n/g;
$output .= "$key: $out\n";
}
}
$output .= "\n";
return $output;
}
sub Eingabe
{
if ($ENV{'QUERY_STRING'})
{
$daten=$ENV{'QUERY_STRING'};
} else
{ read (STDIN, $daten, $ENV{'CONTENT_LENGTH'}); }
if (@ARGV) { @datensaetze=@ARGV; } else {
@datensaetze = split(/&/, $daten); }
foreach $satz (@datensaetze)
{
($name, $wert) = split(/=/, $satz);
$wert =~ tr/+/ /;
$wert =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$wert =~ s/<(([^ >]|\n)*)>//g;
$name =~ tr/+/ /;
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
chomp $wert;
$wert=~s/\n/<br>/g;
$FORM{$name} = $wert;
}
return %FORM;
}
sub fehler
{
my $fehler_grund=$_[0];
print "<p><center><table border=5>\n";
print "<td bgcolor=#c1ced7 align=center width=440><h1><font color=#ff3060><u></u></font></h1>";
print "<font color=#000000><font size=+1>- Sie haben ein wichtiges Feld nicht ausgefüllt -</font><p>";
print "</table>";
exit;
}
sub zeit
{
local(@z)=localtime;
foreach $i (@z) { if (length($i)<2) { $i="0".$i; } }
local(%azeit);
local($uhr)="$z[2]:$z[1]:$z[0]";
local($monat)=($z[4]+1);
if (length($monat)<2) { $monat="0".$monat; }
$z[5]=(1900+$z[5]);
local($datum)="$z[3].$monat.$z[5]";
$azeit{'uhr'}=$uhr;
$azeit{'datum'}=$datum;
return %azeit;
}
Hallo Marc,
Okay, das sieht ja schon viel besser aus ;)
my $sql = "INSERT INTO test VALUES ('$daten')";
my $sth = $dbh->prepare( $sql ) ||
die "Kann Statement nicht vorbereiten: $DBI::errstr\n";
$dbh->disconnect;
Ein INSERT-Befehl bei SQL brauch immer ein Feld/Wert-Paar, um zu wissen, welchen Wert in welches Feld zu schreiben ist.
In deinem Fall:
"INSERT INTO test ('Kongressgebühr') VALUES ('". $daten{'001 Kongressgebühr'}. "')"
Hierbei ist noch anzumerken, dass es sicherer ist, auf Groß-/Kleinschreibung und auf Umlaute bzw. Sonderzeichen in den Bezeichnungen von Feldern, Variablen und Übergabewerte zu verzichten. Dies gilt für Datenbanken, Programmiersprachen und HTML-Formulare. Diese Angaben können nämlich von System zu System anderst interpertiert werden, und können Probleme verusrachen.
Wenn Du später deine Tabelle erweitern möchtest, musst Du auch deine SQL-Anweisung anpassen:
"INSERT INTO test ('feld1', 'feld2') VALUES ('daten1', 'daten2')"
Bis hierhin hat das DBI-Modul deine SQL-Anweisung nur vorbereitet, jedoch noch nicht ausgeführt. Um deine INSERT-Anweisung nun auch auszuführen muss nach dem "prepare" ein "execute" erfolgen:
$sth->execute();
Oder in deinem Fall die einfachere Lösung, Du fasst beide Schritte in einer Anweisung zusammen:
my $sth = $dbh->do( $sql ) ||
die "Kann Statement nicht vorbereiten: $DBI::errstr\n";
Noch ein paar Tipps zu deinem Programm:
Hoffe Dir geholfen zu haben, und stehe bei weiteren Fragen natürlich Rde und Antwort ;)
Gruß
Helmut Weber
Hi Helmut,
vielen Dank für Deine Hilfe. Jetzt hat es zumindest einmal geklappt Daten in eine SQL Tabelle zu schreiben. Mehr wollte ich auch gar nicht.
Noch eine kleine Frage ist aufgekommen: in der perl Datei, die auf meinem Server in einem Verzeichnis liegt, sind ja nun das Passwort und der Zugriff auf die Datenbank gespeichert. Kann diese Datei nicht von außen eingelesen werden? Oder wie kann man sich vor Mißbrauch schützen? Die Datei hat ja 755 Rechte.
Danke und Gruß, Marc
Hallo Marc,
vielen Dank für Deine Hilfe. Jetzt hat es zumindest einmal geklappt Daten in eine SQL Tabelle zu schreiben. Mehr wollte ich auch gar nicht.
Schön das es jetzt funktioniert ;)
Noch eine kleine Frage ist aufgekommen: in der perl Datei, die auf meinem Server in einem Verzeichnis liegt, sind ja nun das Passwort und der Zugriff auf die Datenbank gespeichert. Kann diese Datei nicht von außen eingelesen werden? Oder wie kann man sich vor Mißbrauch schützen? Die Datei hat ja 755 Rechte.
Der Webserver ist normalerweise so konfiguriert, das er Datein mit der Endung .pl oder .cgi nicht an den Browser zurück gibt, sondern durch den Perl-Kompiler jagt.
Wenn nun aus irgendeinem Grund eine falsche Konfiguration des Webservers erfolgt, kann es vorkommen, dass der Webserver die Datein, anstatt durch den Kompiler zu jagen, diese im Klartext an den Browser ausgibt (Was schon vorgekommen ist!).
Jetzt sind die Zugangsdaten zu deiner Datenbank natürlich einsehbar. Wenn Du Dich also nicht nur auf die Konfiguration des Webserver verlassen möchtest, gibt es auch die Möglichkeit die geheimen Daten in eine externe Datei auszulagern, und diese außerhalb des Zugriffbereiches des Webserver abzulegen.
Gruß
Helmut Weber