Richard: Daten werden nicht in Hash eingelesen

Hallo

Ich habe mit dem nachfolgenden Script zwei Probleme, die vermutlich in einem Fehler im Umgang mit Hashes zu suchen sind. Ich weiss nicht, ob da ein Zusammenhang besteht:

1. Wenn ich das Script im Browser ausführe, werden die im Formular erfassten Daten nicht übernommen, die Bestätigungsseite wird angezeigt ohne die eingegebenen Daten und die Gästebucheinträge sind leer. Ich krieg keine Fehlermeldung im Browser und auch nicht im Logfile und hab deshalb keine Ahnung, wo ich suchen soll.

2. Wenn ich das Script auf der Command Line ausführe, kriege ich mit Hinweis auf jene Zeilen, in denen jeweils ein Hashelement angesprochen wird, die Fehlermeldung "Use of uninitialized value ...". Dies aber erst in der Subroutine "confirmation" und nicht schon bei der elsif-Prüfung, wo die Elemente ja eigentlich das erste Mal angesprochen werden. Ich bin mir nicht bewusst, dass nicht nur der betreffende Hash sondern auch die einzelnen Hashelemente deklariert werden sollten, und hab auch nicht herausgefunden wie das gehen sollte.

Hier das Script:

#!c:/program files/perl/bin/perl -w

use diagnostics;        # nur beim Debuggen einschalten!
use strict;             # schaltet "use strict"-Pragma ein
use CGI::Carp qw(fatalsToBrowser);
my ($outfile);          # Deklaration der Variablen

use lib "http://129.132.128.47/cgi-bin";

require "cgi-lib.pl";   # parsing der FORM-Daten und Ausgabe der Variablen
use CGI qw/param/;
my %besucherdaten;       # Hash "besucherdaten" wird deklariert

require "datum.pl";     # eine Routine fuer das Datum
my $date = &ctime(time);
chop($date);

&ReadParse(%besucherdaten);

Prüfung, ob zwingende Felder ausgefüllt wurden

if (undef $besucherdaten{'username'})
{no_name();}
elsif (undef $besucherdaten{'city'})
{no_city();}
elsif (undef $besucherdaten{'comments'})
{no_comments();}
else {url_test();}

Feld "username" wurde nicht ausgefüllt, Fehlerseite wird angezeigt

sub no_name{
print "Content-type: text/html\n\n";
print "\n";
print "<HTML>\n";
print "<head><title>content missing in guestbook entry</title></head>\n";
print "<body bgcolor=black>\n";
print "<link rel=stylesheet type=text/css href=http://129.132.128.47/krausenet/css/richi.css>\n";
print "<h1>content missing in guestbook entry</h1>\n";
print "<p>you forgot to enter your name<br>\n";
print "please click the back-button of your browser to complete your guestbook entry</p>\n";
}

Feld "city" wurde nicht ausgefüllt, Fehlerseite wird angezeigt

sub no_city{
print "Content-type: text/html\n\n";
print "\n";
print "<HTML>\n";
print "<head><title>content missing in guestbook entry</title></head>\n";
print "<body bgcolor=black>\n";
print "<link rel=stylesheet type=text/css href=http://129.132.128.47/krausenet/css/richi.css>\n";
print "<h1>content missing in guestbook entry</h1>\n";
print "<p>you forgot to enter where you come from<br>\n";
print "please click the back-button of your browser to complete your guestbook entry</p>\n";
}

Feld "comments" wurde nicht ausgefüllt, Fehlerseite wird angezeigt

sub no_comments{
print "Content-type: text/html\n\n";
print "\n";
print "<HTML>\n";
print "<head><title>content missing in guestbook entry</title></head>\n";
print "<body bgcolor=black>\n";
print "<link rel=stylesheet type=text/css href=http://129.132.128.47/krausenet/css/richi.css>\n";
print "<h1>content missing in guestbook entry</h1>\n";
print "<p>you forgot to enter a comment<br>\n";
print "please click the back-button of your browser to complete your guestbook entry</p>\n";
}

Prüfung, ob eine home page angegeben wurde

sub url_test {
if (undef $besucherdaten{'homepage'})
{confirmation_no_url();}
else {confirmation();}
}

Alle zwingenden Felder ausser Home Page wurden ausgefüllt, Bestätigungsseite wird angezeigt

Eintrag im Gästebuch wird vorgenommen

sub confirmation_no_url {
print "Content-type: text/html\n\n";
print "\n";
print "<HTML>\n";
print "<head><title>comment added to guestbook</title></head>\n";
print "<body bgcolor=black>\n";
print "<link rel=stylesheet type=text/css href=http://129.132.128.47/krausenet/css/richi.css>\n";

print "<h1>gigel confirmation: new comment added to guestbook</h1>\n";
print "on $date you submitted the following information:\n";

print "<table>\n";
print "<colgroup width=250>\n";
print "  </colgroup>\n";
print "<tr>\n";
print "  <td>your name is: </td>\n";
print "  <td><i>$besucherdaten{'username'}</i></td>\n";
print " </tr>\n";
print "<tr>\n";
print "  <td>you live in: </td>\n";
print "  <td><i>$besucherdaten{'city'}</i></td>\n";
print " </tr>\n";
print "<tr>\n";
print "  <td>the URL of your web site: </td>\n";
print "  <td><i>no homepage defined</i></td>\n";
print " </tr>\n";
print "<tr>\n";
print "  <td>your love message: </td>\n";
print "  <td><i>$besucherdaten{'comments'}</i></td>\n";
print " </tr>\n";
print "</table>\n";

print "<table>\n";
print "<tr>\n";
print "  <td valign=bottom style=height:100px>we hope you enjoyed visiting our site and thank you for leaving a note</td>\n";
print " </tr>\n";
print "  <td>click <a href=/krausenet/guestbook/guestbook.htm>here</a> if you want to read the guestbook now.</td>\n";
print "<tr>\n";
print "</table>\n";

$outfile = ">> c:/Program Files/Apache Group/Apache/htdocs/krausenet/guestbook/guestbook.htm";
open(OUTFILE, $outfile);
print OUTFILE "
<br>
<hr>
<br>
on $date <i>$besucherdaten{'username'}</i>
from <i>$besucherdaten{'city'}</i> left the following note:<p>
"<i>$besucherdaten{'comments'}</i>"
<br>
<br>
";
close(OUTFILE);
}

Alle zwingenden Felder wurden ausgefüllt, Bestätigungsseite wird angezeigt

Eintrag im Gästebuch wird vorgenommen

sub confirmation {
print "Content-type: text/html\n\n";
print "\n";
print "<HTML>\n";
print "<head><title>comment added to guestbook</title></head>\n";
print "<body bgcolor=black>\n";
print "<link rel=stylesheet type=text/css href=http://129.132.128.47/krausenet/css/richi.css>\n";

print "<h1>confirmation: new comment added to guestbook</h1>\n";
print "on $date you submitted the following information:\n";

print "<table>\n";
print "<colgroup width=250>\n";
print "  </colgroup>\n";
print "<tr>\n";
print "  <td>your name is: </td>\n";
print "  <td><i>$besucherdaten{'username'}</i></td>\n";
print " </tr>\n";
print "<tr>\n";
print "  <td>you live in: </td>\n";
print "  <td><i>$besucherdaten{'city'}</i></td>\n";
print " </tr>\n";
print "<tr>\n";
print "  <td>the URL of your web site: </td>\n";
print "  <td><i>$besucherdaten{'homepage'}</i></td>\n";
print " </tr>\n";
print "<tr>\n";
print "  <td>your love message: </td>\n";
print "  <td><i>$besucherdaten{'comments'}</i></td>\n";
print " </tr>\n";
print "</table>\n";

print "<table>\n";
print "<tr>\n";
print "  <td valign=bottom style=height:100px>we hope you enjoyed visiting our site and thank you for leaving a note</td>\n";
print " </tr>\n";
print "  <td>click <a href=/krausenet/guestbook/guestbook.htm>here</a> if you want to read the guestbook now.</td>\n";
print "<tr>\n";
print "</table>\n";

$outfile = ">> c:/Program Files/Apache Group/Apache/htdocs/krausenet/guestbook/guestbook.htm";
open(OUTFILE, $outfile);
print OUTFILE "
<br>
<hr>
<br>
on $date <i>$besucherdaten{'username'}</i>
from <i>$besucherdaten{'city'}</i> left the following note:<p>
"<i>$besucherdaten{'comments'}</i>"
<br>
<br>
visit my home page: $besucherdaten{'homepage'}
<br>
";
close(OUTFILE);
}

Bin dankbar für jeden Tip
Gruss
Richard

  1. Hoi,

    [...]

    Prüfung, ob zwingende Felder ausgefüllt wurden

    if (undef $besucherdaten{'username'})
    {no_name();}
    elsif (undef $besucherdaten{'city'})
    {no_city();}
    elsif (undef $besucherdaten{'comments'})
    {no_comments();}
    else {url_test();}
    [...]

    Ich glaube, du moechtest eher

    if(defined $besucherdaten{'username'})

    oder

    if(exists $besucherdaten{'username'})

    benutzen :-)

    Gruesse,
     CK

    1. Hallo Christian

      Es geht darum, zu prüfen, ob die jeweiligen Elemente  keine Werte zugewiesen erhalten haben. Geht das mit undef denn nicht?

      Richard

      Hoi,

      [...]

      Prüfung, ob zwingende Felder ausgefüllt wurden

      if (undef $besucherdaten{'username'})
      {no_name();}
      elsif (undef $besucherdaten{'city'})
      {no_city();}
      elsif (undef $besucherdaten{'comments'})
      {no_comments();}
      else {url_test();}
      [...]

      Ich glaube, du moechtest eher

      if(defined $besucherdaten{'username'})

      oder

      if(exists $besucherdaten{'username'})

      benutzen :-)

      Gruesse,
      CK

      1. Hallo,

        Lies mal http://learn.to/quote.

        Es geht darum, zu prüfen, ob die jeweiligen Elemente  keine Werte
        zugewiesen erhalten haben.

        Ja, das habe ich gesehen.

        Geht das mit undef denn nicht?

        Nein. Du moechtest 'perldoc -f exists', 'perldoc -f undef' und
        'perldoc -f defined' lesen. Alternativ natuerlich auch auf
        http://www.perldoc.com/. Mit 'undef $variable' "ent-definierst"
        du eine Variable: der interne Referenz-Zaehler wird um eins
        dekrementiert. Ein 'undef $hash{element}' ist allerdings falsch.
        Dafuer gibt es 'delete' (perldoc -f delete). Du moechtest pruefen, ob
        der Schluessel im Hash existiert und einen definierten Wert hat.
        Also:

        if(exists $hash{schluessel} && defined $hash{schluessel}) {
         ...
        }

        Gruesse,
         CK

        1. Ich hab learn.to/quote gelesen, aber ich verstehe nicht ganz, was Du mir damit sagen willst. Hätt ich nicht das ganze Script posten sollen?

          Ich hab das Script nun umgeschrieben wie folgt, nun wird aber nach dem Absenden offenbar immer die Subroutine no_name aufgerufen, auch wenn ein Name eingegeben wird (keine Fehlermeldung im Log). Ich hab das mit weiteren Subroutinen gelöst, elsif funktioniert ja dann mit exists und defined nicht mehr:

          Prüfung, ob zwingende Felder ausgefüllt wurden

          if (exists $besucherdaten{'username'} && defined $besucherdaten{'username'})
          {test_city();}
          else {no_name();}

          sub test_city{
          if (exists $besucherdaten{'city'} && defined $besucherdaten{'city'})
          {test_comments();}
          else {no_city();}
          }

          sub test_comments{
          if (exists $besucherdaten{'comments'} && defined $besucherdaten{'comments'})
          {url_test();}
          else {no_comments();}
          }

          Gruss
          Richard

          1. Hallo,

            Ich hab das Script nun umgeschrieben wie folgt, nun wird aber nach dem Absenden offenbar immer die Subroutine no_name aufgerufen, auch wenn ein Name eingegeben wird (keine Fehlermeldung im Log). Ich hab das mit weiteren Subroutinen gelöst, elsif funktioniert ja dann mit exists und defined nicht mehr:

            Solltest Du das Formular mit der HTTP-Methode POST abgesendet haben, so kann ich mir gut vorstellen, daß das nicht funktioniert.
            Du solltest entweder CGI.pm _oder_ cgi-lib.pl verwenden, wobei ich Dir aus mehreren Gründen eher CGI.pm empfehlen würde.
            Beide Module zusammen eingesetzt kann, vor allem bei POST, nicht funktionieren, da beide versuchen die Daten von STDIN zu lesen, was allerdings nur bei einem erfolgreich sein kann. Das zweite Modul, in Deinem Falle also cgi-lib.pl und ReadParse hat das Nachsehen, wodurch auch keine Daten in dem Hash landen.

            BTW. wußte ich gar nicht, daß ReadParse in der Wiese funktionieren kann, so wie Du es aufrufst. Ich kenne nur die Form
            ReadParse(*benutzerdaten)
            Woebei dann neben einem Hash auch ein Array und ein Skalar beschrieben wird.

            Grüße
              Klaus

            1. Hallo,

              Ich hab das Script nun umgeschrieben wie folgt, nun wird aber nach dem Absenden offenbar immer die Subroutine no_name aufgerufen, auch wenn ein Name eingegeben wird (keine Fehlermeldung im Log). Ich hab das mit weiteren Subroutinen gelöst, elsif funktioniert ja dann mit exists und defined nicht mehr:

              Solltest Du das Formular mit der HTTP-Methode POST abgesendet haben, so kann ich mir gut vorstellen, daß das nicht funktioniert.

              Gemäss dem selfhtml-Artikel von Rolf Rost (Formularauswertung mit cgi-lib.pl sollte das keine Rolle spielen? Ich benutze POST, habs aber nun auch mit GET versucht, brachte aber keine Änderung.

              Du solltest entweder CGI.pm _oder_ cgi-lib.pl verwenden, wobei ich Dir aus mehreren Gründen eher CGI.pm empfehlen würde.

              Bis anhin hab ich cgi-lib.pl verwendet.

              Beide Module zusammen eingesetzt kann, vor allem bei POST, nicht funktionieren, da beide versuchen die Daten von STDIN zu lesen, was allerdings nur bei einem erfolgreich sein kann. Das zweite Modul, in Deinem Falle also cgi-lib.pl und ReadParse hat das Nachsehen, wodurch auch keine Daten in dem Hash landen.

              BTW. wußte ich gar nicht, daß ReadParse in der Wiese funktionieren kann, so wie Du es aufrufst. Ich kenne nur die Form
              ReadParse(*benutzerdaten)

              Werden Hashes nicht mit dem Prozentzeichen deklariert?

              Woebei dann neben einem Hash auch ein Array und ein Skalar beschrieben wird.

              Grüße
                Klaus

            2. Hallo,

              Ich hab das Script nun umgeschrieben wie folgt, nun wird aber nach dem Absenden offenbar immer die Subroutine no_name aufgerufen, auch wenn ein Name eingegeben wird (keine Fehlermeldung im Log). Ich hab das mit weiteren Subroutinen gelöst, elsif funktioniert ja dann mit exists und defined nicht mehr:

              Solltest Du das Formular mit der HTTP-Methode POST abgesendet haben, so kann ich mir gut vorstellen, daß das nicht funktioniert.
              Du solltest entweder CGI.pm _oder_ cgi-lib.pl verwenden, wobei ich Dir aus mehreren Gründen eher CGI.pm empfehlen würde.
              Beide Module zusammen eingesetzt kann, vor allem bei POST, nicht funktionieren, da beide versuchen die Daten von STDIN zu lesen, was allerdings nur bei einem erfolgreich sein kann. Das zweite Modul, in Deinem Falle also cgi-lib.pl und ReadParse hat das Nachsehen, wodurch auch keine Daten in dem Hash landen.

              ok - sieht so aus, wie wenn ich einen Mix aus cgi.pm und cgi-lib.pl verwendet habe. Liegt wohl daran, dass ich Perl-Anfänger bin und die Scripts, die ich als Vorlage hatte, nicht alle dieselben Module/Library verwendeten ;-) und ich nicht in der Lage war, dies zu erkennen...

              Ich werde also cgi.pm verwenden und versuche gerade zu verstehen, wie ich dann an die Formlardaten komme. Ist das mit
              my %besucherdaten = $cgi->param()
              richtig?

              BTW. wußte ich gar nicht, daß ReadParse in der Wiese funktionieren kann, so wie Du es aufrufst. Ich kenne nur die Form
              ReadParse(*benutzerdaten)
              Woebei dann neben einem Hash auch ein Array und ein Skalar beschrieben wird.

              Grüße
                Klaus

              1. use Mosche;

                ok - sieht so aus, wie wenn ich einen Mix aus cgi.pm und cgi-lib.pl verwendet habe. Liegt wohl daran, dass ich Perl-Anfänger bin und die Scripts, die ich als Vorlage hatte, nicht alle dieselben Module/Library verwendeten ;-) und ich nicht in der Lage war, dies zu erkennen...

                Ich werde also cgi.pm verwenden und versuche gerade zu verstehen, wie ich dann an die Formlardaten komme. Ist das mit
                my %besucherdaten = $cgi->param()
                richtig?

                Noe.

                my $value = $cgi->param('key');

                oder

                my @list_of_keys = $cgi->param();

                use Tschoe qw(Matti);

                1. ok - vielen Dank

                  use Mosche;

                  ok - sieht so aus, wie wenn ich einen Mix aus cgi.pm und cgi-lib.pl verwendet habe. Liegt wohl daran, dass ich Perl-Anfänger bin und die Scripts, die ich als Vorlage hatte, nicht alle dieselben Module/Library verwendeten ;-) und ich nicht in der Lage war, dies zu erkennen...

                  Ich werde also cgi.pm verwenden und versuche gerade zu verstehen, wie ich dann an die Formlardaten komme. Ist das mit
                  my %besucherdaten = $cgi->param()
                  richtig?

                  Noe.

                  my $value = $cgi->param('key');

                  oder

                  my @list_of_keys = $cgi->param();

                  use Tschoe qw(Matti);