sergej: Formulardaten übergeben (CGI+Perl?)

Hallo Folks,

Bin erst seit einer Woche am Perl-Script programmieren und probiere jetzt langsam die CGI-Scripte aus.

Ich möchte online über den Browser neue Links über Formular hinzufügen!

Zu meiner Frage:
Kann man CGI und Perl vermischen?
werden die Parameter übergeben und wird db.txt aktualisiert?
Habe heute leider keine Möglichkeit dies zu Testen.

Folgendes Formular (voererst) in HTML:
________________________
<FORM name=Formular onsubmit="return chkFormular()" action=../cgi-bin/links.pl method=post>
  <PRE>
  Name der Adresse                  : <INPUT size=40 name=URL_NAME>
  URL Adresse (www.name.de)   : <INPUT size=40 name=URL>
  Wähle Quickbar:      <INPUT TYPE=RADIO VALUE="ht" NAME="THEMA">HTMLWorld<INPUT TYPE=RADIO VALUE="mw" NAME="THEMA">Movieworld<BR>

Link:    <INPUT type="submit" value="hinzufügen"><INPUT type="reset" value="Alles Löschen">

</PRE>
 </FORM>
________________________

in Perl/CGI: links.pl
________________________
#!/usr/bin/perl
use CGI;
#zur Fehlerausgabe auf dem Browser
use CGI::Carp qw(fatalsToBrowser);

$q=new CGI;

#Eingaben einlesen
my $u_name=$q->param('URL_NAME');
my $url=$q->param('URL');
my $thema=$q->param('THEMA');

my $inFile = 'db.txt'; # Linksammlung im Format Thema+URL+Name
my $HFile  = 'dbh.txt'; # Help-Datei

sub Einfuegen{
flock(FH, LOCK_EX);
open(FHOLD, "< $inFile") or die "Kann $inFile nicht oeffnen!/n";
open(FHNEW, "> $HFile") or die "Kann $HFile nicht oeffnen!/n";
 while (<FHOLD>) {
  print FHNEW $_;
      if(eof(FHOLD)) {
     print FHNEW $thema."+".$url."+".$u_name"\n";
  }
 }
 flock(FH, LOCK_UN);
 close(FHOLD);
 close(FHNEW);
 unlink($inFile);
 rename($HFile, $inFile)          or die "can't rename $HFile to $inFile: $!";
}

&Einfuegen;
________________________________________________

Ein anderer Perl-Script gibt die Links in Form von Quickbar aus,
dabei werden die Quickbars nach Themen sortiert.

Danke auch für die Verbesserungs-Vorschläge,

Gruß Sergej

  1. Hi,

    Kann man CGI und Perl vermischen?

    CGI ist eine Schnittstelle, die Scripts in (quasi) beliebiger Sprache nutzt. Perl hat sich da recht gut etabliert. Von "vermischen" würde ich allerdings nicht reden, weil dies eine gewisse Gleichförmigkeit von CGI und Perl implizieren würde.

    werden die Parameter übergeben und wird db.txt aktualisiert?

    CGI definiert u.a. auch die Übergabe solcher Werte. In Perl greifst Du idealerweise mittels des Moduls CGI.pm darauf zu; siehe

    perldoc CGI

    Was Du mit der "db.txt" meinst, ist mir nicht klar.

    <FORM name=Formular onsubmit="return chkFormular()" action=../cgi-bin/links.pl method=post>

    Der Wert des action-Attributs _muss_ hier in Anführungszeichen stehen.

    URL Adresse (www.name.de)

    Das ist ein Hostname, keine URL und auch keine Adresse.

    #!/usr/bin/perl

    #!/usr/bin/perl -w
    use strict;

    Dadurch vermeidest Du Fehler.

    open(FHOLD, "< $inFile") or die "Kann $inFile nicht oeffnen!/n";

    Lass Dir noch $! ausgeben, siehe

    perldoc perlvar

    open(FHNEW, "> $HFile") or die "Kann $HFile nicht oeffnen!/n";

    Anhängendes Schreiben geht übrigens anders; siehe

    perldoc -f open
    perldoc perlopentut

    print FHNEW $thema."+".$url."+".$u_name"\n";

    Da du schon mit Doublequotes arbeitest, ist die Schreibweise "$thema+$url+$u_name\n" IMHO besser lesbar - und zudem um einen Syntaxfehler reduziert.

    close(FHNEW);

    Bei Schreibzugriffen kann auch das Schließen des Dateihandles schiefgehen. Fange also auch hier den Fehlerfall ab.

    unlink($inFile);
    rename($HFile, $inFile)          or die "can't rename $HFile to $inFile: $!";

    Schreib doch einfach anhängend :-) Das hat zudem den Vorteil, dass Du Dich nicht mit den Problemen paralleler Schreibzugriffe rumschlagen musst.

    Cheatah

    --
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. Moin Moin !

      Schreib doch einfach anhängend :-) Das hat zudem den Vorteil, dass Du Dich nicht mit den Problemen paralleler Schreibzugriffe rumschlagen musst.

      Naja, wenn zwei Prozesse gleichzeitig open FILE,">>file.ext" machen, kann's auch knallen. Also:

      perldoc flock

      und

      http://www.samag.com/documents/s=4075/sam1013019385270/sam0203i.htm

      Alexander

      --
      Nein, ich beantworte keine Fragen per eMail. Dafür ist das Forum da.
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so!"
      1. Hi,

        Naja, wenn zwei Prozesse gleichzeitig open FILE,">>file.ext" machen, kann's auch knallen.

        anhängendes Schreiben ist eine atomare Aktion. Das kann garantiert _nicht_ in die Hose gehen - höchstens die Reihenfolge ist nicht so, wie man es erwartet hat.

        Cheatah

        --
        X-Will-Answer-Email: No
        X-Please-Search-Archive-First: Absolutely Yes
        1. Hallo,

          Danke erstmal,
          ich gebe zu ich habe einiges von meinen alten Scripts übernommen.

          Hier die Korrektur: Anhängen ist logischer, klar ;-)
          sub Einfuegen{
           open(FH, ">> $inFile") or die "Kann $inFile nicht oeffnen!$! /n";
           flock(FH, LOCK_EX);
            while (<FHOLD>) {
             if(eof(FHOLD)) {
                print FHNEW "$thema+$url+$u_name"\n";
             }
            }
           flock(FH, LOCK_UN);
           close(FH);
          }
          &Einfügen;

          Werden die Parameter übergeben??
          db.txt ist einfach eine Datei inder beispiel folgendes steht:

          su+www.google.de+GOOGLE
          nf+www.t-online.de+T-Online
          ht+www.selfhtml.de+selfhtml
          _____________________________
          Danke Gruß Sergej

          1. Hallo,

            Danke erstmal,
            ich gebe zu ich habe einiges von meinen alten Scripts übernommen.

            Hier die Korrektur: Anhängen ist logischer, klar ;-)
            sub Einfuegen{
             open(FH, ">> $inFile") or die "Kann $inFile nicht oeffnen!$! /n";
             flock(FH, LOCK_EX);
              while (<FHOLD>) {
               if(eof(FHOLD)) {
                  print FHNEW "$thema+$url+$u_name"\n";
               }
              }

            Das '>>' soll doch bewirken, dass du Daten an eine Datei anhängst, warum willst du nochmal die ganze Datei einlesen?

            flock(FH, LOCK_UN);

            Unnötig und gefährlich, da in diesem kurzen Moment die Datei geändert werden könnte.

            close(FH);
            }
            &Einfügen;

            Das ist veraltete Schreibweise (mit dem '&'), dass solltest du nur verwenden, wenn du @_ expliziet an die Funktion übergebn möchtest.

            Werden die Parameter übergeben??
            db.txt ist einfach eine Datei inder beispiel folgendes steht:

            Welche Parameter?

            Struppi.

            1. Auf's neue:

              flock(FH, LOCK_UN);
              Unnötig und gefährlich, da in diesem kurzen Moment die Datei geändert werden könnte.

              Wenn ich 'flock(FH, LOCK_UN);' weg lasse, kann ich später nicht mehr anhängen, oder??

              Das ist veraltete Schreibweise (mit dem '&'

              sub weggelassen.

              Welche Parameter?

              Werden die Parameter nach Aufruf: <FORM...action="../cgi-bin/links_plus.pl" method=post>
               vom Formular(THEMA=blabla&URL=blabla&URL_NAME=blabla) eingelesen?

              links_plus.pl:
              ------------------
              #Eingaben einlesen
              my $u_name=$q->param('URL_NAME');
              my $url=$q->param('URL');
              my $thema=$q->param('THEMA');

              my $inFile = 'db.txt'; # Linksammlung im Format Thema+URL+Name

              #Eingaben anhängen
              open(FH, ">> $inFile") or die "Kann $inFile nicht oeffnen!$!/n";
              flock(FH, LOCK_EX);
                 print FH "$thema+$url+$u_name\n";
              flock(FH, LOCK_UN);
              close(FH);

              Danke,
              Gruß Sergej

              1. Hi,

                Wenn ich 'flock(FH, LOCK_UN);' weg lasse, kann ich später nicht mehr anhängen, oder??

                doch. Lies bitte

                perldoc -f flock

                wenn Du nicht sicher bist, was der Befehl macht.

                Werden die Parameter nach Aufruf: <FORM...action="../cgi-bin/links_plus.pl" method=post>
                vom Formular(THEMA=blabla&URL=blabla&URL_NAME=blabla) eingelesen?

                "Vom Formular eingelesen"? Der Browser übermittelt die Parameter an den Server; dieser leitet sie (als _eine_ Umgebungsvariable) an Dein Script weiter. In diesem werden sie mittels CGI::param zugänglich gemacht.

                Cheatah

                --
                X-Will-Answer-Email: No
                X-Please-Search-Archive-First: Absolutely Yes
                1. Hallo,

                  Hab was gefunden:

                  Ein open() prueft nicht, ob eine Datei geflockt ist. Jedem open() MUSS ein flock folgen. Da haelt das script dann an und wartet bis das vorherige flock aufgehoben wurde (durch flock(HANDLE,8) oder close).

                  "Vom Formular eingelesen"? Der Browser übermittelt die Parameter an den Server; dieser leitet sie (als _eine_ Umgebungsvariable) an Dein Script weiter. In diesem werden sie mittels CGI::param zugänglich gemacht.

                  Genau das meine ich ;-)
                  ____________________________________________

                  open(FH, ">> $inFile") or die "Kann $inFile nicht oeffnen!$!/n";
                  flock(FH, LOCK_EX); # oder flock(FH, 2);
                  ^^^^^^^^^  ^^^^^^^
                     print FHNEW "$thema+$url+$u_name \n";
                  close(FH);
                  flock(FH, LOCK_UN); #oder flock(FH, close);
                  ^^^^^^^^^  ^^^^^^^
                  _____________________________________________

                  Warum macht flock probleme? soll ich's einfach weglassen???

                  Gruß Sergej

                  1. Hallo,
                    ____________________________________________

                    open(FH, ">> $inFile") or die "Kann $inFile nicht oeffnen!$!/n";
                    flock(FH, LOCK_EX); # oder flock(FH, 2);
                    ^^^^^^^^^  ^^^^^^^
                    print FHNEW "$thema+$url+$u_name \n";
                    close(FH);
                     _____________________________________________

                    Warum macht flock probleme? soll ich's einfach weglassen???

                    Ich habs: das close() macht schon den flock weg!!! ;-)

                    Gruß Sergej

                    1. Hallo,

                      Lauter Fehler.....
                      ___________________________________________

                      open(FH, ">> $inFile") or die "Kann $inFile nicht oeffnen!$!/n";
                      flock(FH, LOCK_EX); # oder flock(FH, 2);
                      #^^^^^^^^  ^^^^^^^ Macht noch probleme!
                      print FH "$thema+$url+$u_name \n";
                      close(FH);
                      _____________________________________________

                      print FH korregiert .

                      Gruß Sergej

                      1. Danke Struppi Cheatah,

                        flock Problem verstanden! und gelöst, obwohl gar nich nötig in meinem Fall, stimmt schon.

                        das Skript ist richtig kurz geworden:
                        -------------------------
                        #!/usr/bin/perl -w
                        use strict;

                        use CGI;
                        #zur Fehlerausgabe auf dem Browser
                        use CGI::Carp qw(fatalsToBrowser);
                        my $q=new CGI;

                        #Eingaben einlesen
                        my $u_name=$q->param('URL_NAME');
                        my $url=$q->param('URL');
                        my $thema=$q->param('THEMA');

                        my $inFile = 'db.txt';

                        Eingaben anhängen

                        open(FH, ">> $inFile") or die "Kann $inFile nicht oeffnen!$!/n";
                        #flock(FH, LOCK_EX);
                           print FH "$thema+$url+$u_name \n";
                        close(FH);
                        -------------------------

                        Gruß Sergej


                        1. #!/usr/bin/perl -w
                          use strict;

                          use CGI;

                          Du brauchast noch

                          use Fcntl qw(:flock);

                          um LOCK_EX einzubinden.

                          #zur Fehlerausgabe auf dem Browser
                          use CGI::Carp qw(fatalsToBrowser);
                          my $q=new CGI;

                          #Eingaben einlesen
                          my $u_name=$q->param('URL_NAME');
                          my $url=$q->param('URL');
                          my $thema=$q->param('THEMA');

                          um Warnungen zu vermeiden, besser:

                          my $u_name = $q->param('URL_NAME') || '';
                          my $url  = $q->param('URL') || '';
                          my $thema=$q->param('THEMA') || '';

                          Ansonsten meckert Perl, wenn die Felder leer sind.

                          Struppi.

                  2. open(FH, ">> $inFile") or die "Kann $inFile nicht oeffnen!$!/n";
                    flock(FH, LOCK_EX); # oder flock(FH, 2);
                    ^^^^^^^^^  ^^^^^^^

                    Das ist gut.

                    print FHNEW "$thema+$url+$u_name \n";
                    close(FH);
                    flock(FH, LOCK_UN); #oder flock(FH, close);
                    ^^^^^^^^^  ^^^^^^^

                    Das ist unnötig.

                    Ein close macht das automatisch.

                    Warum macht flock probleme? soll ich's einfach weglassen???

                    Nein, flock macht keine Probleme, sondern du löst das flock zu früh.
                    zwischen deinem LOCK_UN und close FH kann die Datei verändert werden, ist aber evtl. noch nicht auf die Festplatte geschrieben.

                    Du sollst nur das unlock wegmachen.

                    Struppi.

                  3. Hi,

                    Ein open() prueft nicht, ob eine Datei geflockt ist.

                    stimmt.

                    Jedem open() MUSS ein flock folgen.

                    Stimmt nicht. Ein flock() brauchst Du nur dann, wenn Du die Datei gegen andere Zugriffe blockieren willst. Bei einem (reinen) Lesezugriff oder anhängendem Schreiben[1] ist dies nicht nötig.

                    "Vom Formular eingelesen"? Der Browser übermittelt die Parameter an den Server; dieser leitet sie (als _eine_ Umgebungsvariable) an Dein Script weiter. In diesem werden sie mittels CGI::param zugänglich gemacht.
                    Genau das meine ich ;-)

                    Wunderbar :-)

                    Warum macht flock probleme? soll ich's einfach weglassen???

                    Du brauchst es hier nicht.

                    Cheatah

                    [1] Es sei denn, Du willst mehrere Dinge nacheinander hineinschreiben, die unbedingt als Einheit existieren müssen.

                    --
                    X-Will-Answer-Email: No
                    X-Please-Search-Archive-First: Absolutely Yes