Tobi: neuster Gästebuch Eintrag oben

Hallo Forum

Ich habe ein Gästebuch aus einem Einsteigerperlbuch genommen und auch ein bißchen umgeschrieben. Es funktioniert einwandfrei, bis auf die Kleinigkeit, dass die neusten Einträge nicht oben stehen. Das habe ich mit reverse @array versucht, wie unten zu sehen ist. Ich habe es wahrscheinlich nur falsch eingesetzt. Kann mir da jemand von euch helfen?
(Im Archiv habe ich nichts nützliches gefunden...)

Vielen Dank Tobi

#!C:\Perl\bin\perl.exe -w
&SeitenKopf('Gästebuch-Eintrag');
$htmlgb = 'c:/xitami/webpages/gbuch.htm';
$gbdatenbank = 'c:/xitami/cgi-bin/gbuch.dat';
$maxeintraege = 100;
$zaehler = 0;
$maxalter = 365;
($x, $x, $x, $tag, $mon, $jahr, $x, $jt) = localtime(time);
if ($tag < 10) { $tag = '0'.$tag; }
if (++$mon <10) { $mon = '0'.$mon; }
$jahr = $jahr + 1900;
$datum = $tag . '.' . $mon . '.' . $jahr;
$neuedaten = &CGIDatenlesen;
$neuedaten =~ s/%0D//gio;
$neuedaten =~ s/%0A/ /gio;
%neudat = &CGIDatenaufbereiter($neuedaten);
if (( length ($neudat{'name'}) < 3 ) or ( length ($neudat{'text'}) < 10 ))
{
  print ('<body text="#00FF00" bgcolor="#000000" link="#FF0000" alink="#FFFF00" vlink="#FF0000"><font face="ARIAL">Der Name muss mindestens 3 und der Text mindestens 10 Zeichen lang sein.</font><br>');
  &SeitenEnde;
}
while (($schl, $x) = each %neudat) {
  $neudat{$schl} =~ s/[<>]//go;
}
open (DB, ">>$gbdatenbank") or die ("Kann Gästebuchdatenbank nicht öffnen");
print DB ("$datum-$jt <>$neudat{'name'}<>$neudat{'email'}<>$neudat{'homepage'}<>$neudat{'ort'}<>$neudat{'text'}\n");
close (DB);
open (DB, "<$gbdatenbank");
while (defined ($zeile = <DB>))
{
  if ($zeile =~ m/^(\d\d.\d\d.(\d{4}))-(.{1,3})/o)
  {
    $satzdat = $1;
    $tagesdiff = ($3 - $jt) - ($jahr - $2) * 365;
    if ( abs($tagesdiff) < $maxalter )
    {
      if ( $zaehler < $maxeintraege ) {
        $datenfuergb[$zaehler++] = $satzdat . $';
      }
      else
      {
        shift @datenfuergb;
        $datenfuergb[$maxeintraege] = $satzdat . $';
      }
    }
  }
  else
  {
    print ('Fehler im Datumsfeld der Datenbank!');
    &SeitenEnde;
  }
}
close (DB);
open (HTML, "<$htmlgb");
@altesgb = <HTML>;
close (HTML);
open (HTML, ">$htmlgb");
until ($altesgb[0] =~ m/<!--GBBEGIN-->/io)
{
  print HTML $altesgb[0];
  shift @altesgb;
}
print HTML $altesgb[0];
shift @altesgb;
print HTML ('<center>');
&NeuAusgabe;
print HTML ("</center>\n");
until ($altesgb[0] =~ m/<!--GBENDE-->/io) {
  shift @altesgb;
}
print HTML @altesgb;
close (HTML);
print ('<body text="#00FF00" bgcolor="#000000" link="#FF0000" alink="#FFFF00" vlink="#FF0000"><font face="ARIAL">Ihr Eintrag wurde in das Gästebuch übernommen! Falls Sie ihn nicht sofort im Gästebuch entdecken können, verwenden Sie den "Neu laden"-Knopf Ihres Web-Browsers.</font><br>');
&SeitenEnde;

sub NeuAusgabe
{
  open(DB);
  @entries = <DB>;
  close(DB);
  @entries = reverse(@entries);     #### hier ist mein Versuch ####

foreach $dbeintrag (@datenfuergb)
  {
    ($datum, $name, $email, $homepage, $ort, $text) = split (/<>/, $dbeintrag);
    print HTML ("<table border=0 width=95%><tr><td>");
    print HTML ("Name: $name <br>");
    if($email eq "") {
    print HTML ("");
    }
    else {
    print HTML ("eMail: <a href="mailto:$email">$email</a><br>");
    }
    if($homepage eq "") {
    print HTML ("");
    }
    else {
    print HTML ("Homepage: <a href="$homepage">$homepage</a><br>");
    }
    if($ort eq "") {
    print HTML ("");
    }
    else {
    print HTML ("Land: $ort<br>");
    }
    print HTML ("Schrieb am $datum:<br><br></td></tr>");
    print HTML ("<tr><td>$text</td></tr>");
    print HTML ("</table><br><hr>");
  }
}

sub SeitenEnde
{
  print ('<br><hr><a href="/gbuch.htm"><font face="ARIAL">Zurück zum Gästebuch</font></a>');
  print ('</body></html>');
  die;
}
sub CGIDatenlesen
{
  local $cgidaten;
  if ( $ENV{REQUEST_METHOD} eq "POST" )
  {
    read ( STDIN , $cgidaten , $ENV{'CONTENT_LENGTH'} );
  }
  else
  {
    $cgidaten = $ENV{QUERY_STRING};
  }
  return $cgidaten;
}

sub CGIDatenaufbereiter
{
  local ($cgidatenskalar, $name, $daten);
  local @cgidatenliste;
  local %cgidatenhash;
  if ( $_[0] ) {
    $cgidatenskalar = $_[0];
  }
  else {
    print STDERR ("Es wurden keine Daten an den CGIDatenaufbereiter übergeben\n");
  }
  @cgidatenliste = split(/[&;]/ , $cgidatenskalar);
  foreach $listeneintrag (@cgidatenliste)
  {
    $listeneintrag =~ s/+/ /go;
    ($name, $daten) = split( /=/ , $listeneintrag );
    $name =~ s/%(..)/pack("c",hex($1))/ge;
    $daten =~ s/%(..)/pack("c",hex($1))/ge;
    $cgidatenhash{$name} = $daten;
  }
  return %cgidatenhash;
}

sub SeitenKopf
{
  local $title = $_[0];
  print ("Content-type: text/html\n\n");
  print ('<html>');
  print ('<head><title>');
  print $title;
  print ('</title></head>');
}

  1. Hi,

    mal abgesehen davon, daß dein Script viel zu umständlich ist, würde
    ich die Foreneinträge einfach schon falsch herum eintragen:

    in @eintraege sind die alten Foreneinträge gespeichert.

    open(DAT, ">buch.dat");   # Datei wird überschrieben

    $zahl = $#eintraege;         # Zahl der Einträge feststellen

    print DAT "$akt_eintrag\n"; # neuen Eintrag schreiben

    for($i=$zahl;$i>o;$i--;)
    {
    print DAT "$eintraege[$i]";
    }

    close(DAT);

    1. Sieht gut aus - CK1 - genau das meinte ich auch, Tobi !

      Zusätzlich würd' ich die Datei aber auch noch sperren, bevor ich sie manipuliere - sonst gleichzeitiges Überschreiben einer Datei !

    2. Hallo und Danke an euch Beide

      ich werde es gleich morgen nochmal durchprobieren und mich dann vieleicht (aber hoffentlich nicht) nochmal melden...

      Schönen Abend noch
      Tobi

  2. Hallo Tobi !

    Selbst kein Guru, versuch ich mal mein Glück ...

    Solch ein Problem hatt ich auch einmal - kann mich leider aber nimmer erinnern. Hab mich ins Beispiel noch nicht so reingelesen, daher eine Frage:

    @entries = reverse(@entries);     #### hier ist mein Versuch ####

    foreach $dbeintrag (@datenfuergb)

    wo kommt das array @datenfuergb her ? sollte doch @entries sein - oder ?

    Eine mögliche - wenn auch ungewöhnliche - Lösung:

    Nicht beim Lesen und Ausgeben sortieren, sondern bereits beim Schreiben immer in die erste Zeile schreiben - hab ich auch gemacht - funktioniert ganz gut - sortieren überflüssig.

    Hab mir allerdings noch keine Gedanken darüber gemacht, ob das Sortieren von großen Datenmengen oder das komplette Neuschreiben der Datei besser performt - aber an Geschwindigkeit mangelts meinem Gästebuch nicht!

    Wenn Du interessiert bist, schick ich dir gerne mein Gästebuch.

    Hoffe, gedient zu haben

    norbert =:-)

  3. Hallo Norbert und CK1

    Ich muß zugeben, dass ich es nicht geschafft habe die Hilfe von CK1 effizient umzusetzten, aber so habe ich es dann doch geschafft, als ich endlich begriff wie was warum funktioniert...

    --schnipp--
    open(DB, $gbdatenbank);
    @entries = <DB>;
    close(DB);

    @entries = reverse(@entries);

    open(DB, ">$gbdatenbank");
    print DB @entries;
    close(DB);

    open (DB, ">>$gbdatenbank") or die ("Kann Gästebuchdatenbank nicht öffnen");
    print DB ("$datum-$jt <>$neudat{'name'}<>$neudat{'email'}<>$neudat{'homepage'}<>$neudat{'ort'}<>$neudat{'text'}\n");
    close (DB);

    open(DB, $gbdatenbank);
    @entries = <DB>;
    close(DB);

    @entries = reverse(@entries);

    until (@entries <= $maxeintraege)  {
            pop(@entries);
        }

    open(DB, ">$gbdatenbank");
    print DB @entries;
    close(DB);
    --schnipp--

    es ist wirklich umständlich, war aber wenigstens einfach zu verstehen.

    Bis zum nächsten Mal ;)
    Tobi