Thomas: Premature end of script headers

Hallo!
Wenn ich mir über ein HTML-Formular die Einträge einer Datenbank mittels folgendem Perl-Skript anzeigen lassen möchte, bekomme ich immer die Fehlermeldung "Premature end of script headers". Wer kann mir sagen, woran dass liegen kann? In der Konsole lässt sich das Skript fehlerfrei compilieren, die Fehlermeldung erfolgt lediglich beim Aufruf über den Browser. Skript:

#!e:/perl/Perl/bin/perl -w

use strict;

use CGI qw (:standard);
use CGI::Carp qw (fatalsToBrowser);
use DBI;

my $DBH;
my $STH;
my $CGI;
my $antwort;

$CGI = new CGI();

###Eintrag oder Anzeige###

if($CGI->param("anzeige")){
anzeige($CGI, $DBH, $STH);
}

elsif($CGI->param("eintrag")){
eintragen($CGI, $DBH, $STH);
}

###Start Subroutine Anzeige###

sub anzeige{

$DBH = DBI->connect("DBI:CSV:db_aufgabe2=e:/apache/Apache2/cgi-bin")
            or die "Konnte keine Verbindung zur Datenbank herstellen:$!";

$STH = $DBH->prepare ("SELECT * FROM db_aufgabe2")
            or die "Konnte SQL-Statement nicht bereitstellen:$!";

$STH->execute()
            or die "Ausführen nicht möglich:$!";

print <<HERE_TEXT1;
Content-type: text/html

<html>
<head>
<title>Datensätze in Datenbank</title>
</head>
<body>
<center>
<h1>Datensätze:</h1>
<hr>
<table border>
<tr>
<td width="100"><b>Kalenderwoche</b></td>
<td width="100"><b>Einheiten</b></td>
</tr>

HERE_TEXT1

my @data;

while (@data = $STH->fetchrow_array()){
        my $kalenderwoche = $data[0];
        my $einheiten = $data[1];
print qq§<tr>\n<td><b>$kalenderwoche</b></td>\n<td>$einheiten</td>\n</tr>\n§;
}

print qq§</table>\n<p><a href="../aufgabe2_eintrag.html">Zurück zum Eingabeformular</a></p>\n<hr>\n</center>\n</body>\n</html>§;

$STH->finish();
$DBH->disconnect;}

###Start Subroutine Eintragen###

sub eintragen{

my ($kalenderwoche, $einheiten) = (param('kalenderwoche'),param('einheiten'));

$DBH=DBI->connect("DBI:CSV:db_aufgabe2=e:/apache/Apache2/cgi-bin")
          or die "Konnte keine Verbindung zur Datenbank herstellen:$!";

$STH=$DBH->do("INSERT INTO db_aufgabe2
VALUES('$kalenderwoche','$einheiten')")
          or die "Konnte SQL-Statement nicht bereitstellen:$!";

print<<HERE_TEXT2;
Content-type: text/html

<html>
<head>
<title>Antwort</title>
</head>
<body>
<h4>Datenbankeintrag</h4>
<hr>
<p><b>$kalenderwoche</b>, $einheiten</p>
<hr>
<p><a href="../aufgabe2_eintrag.html">Zurück zum Eingabeformular</a></p>
<hr>
</body>
</html>

HERE_TEXT2

$DBH->disconnect;}

Besten Dank für eure Hilfe.

Gruß Thomas

  1. hi Thomas

    Content-type: text/html

    ^^^^^^^
                                 |
                                 |---- hier fehlten noch \n\n

    ist aber nur eine behauptung von mir!!!

    ich habe das mal hier bei selfhtml gelesen weis aber zur zeit nicht wo.

    bis bis roman

    --
    P.S. manchmal wundere ich mich schon über die postings (fragen u. antworten) die man hier geboten bekommt(meine eigenen [leider] mit eingenommen)
    => ich denke mir meinen teil und ziehe das beste daraus :-)
    1. Hi!
      Danke für Deine Antwort, funktioniert aber leider mit "\n\n" auch nicht :-(
      Kann mir sonst vielleicht jemand weiterhelfen?

      Gruß Thomas

      1. hi Thomas

        print "Content-type: text/html\n\n";

        print <<HERE_TEXT1;
        <html>
        <head>

        probier das doch mal so.

        bis bis roman

        --
        P.S. manchmal wundere ich mich schon über die postings (fragen u. antworten) die man hier geboten bekommt(meine eigenen [leider] mit eingenommen)
        => ich denke mir meinen teil und ziehe das beste daraus :-)
      2. hallo Thomas,

        Danke für Deine Antwort, funktioniert aber leider mit "\n\n" auch nicht :-(

        Das sind ja auch nur zwei Zeilenumbrüche zur besseren optischen Darstellung des ausgegebenen HTML-Codes, das hat mit deinem Problem eh nix zu tun.

        Kann mir sonst vielleicht jemand weiterhelfen?

        Versuchen wirs mal:

        #!e:/perl/Perl/bin/perl -w

        Bist du sicher, daß dieser Pfad korrekt ist? Es ist zumindest ungewöhnlich, daß jemand "perl/PERL" als Installationsverzeichnis wählt.

        use strict;
        use CGI qw (:standard);
        use CGI::Carp qw (fatalsToBrowser);
        use DBI;

        Bist du sicher, daß du

        use CGI qw (:standard);

        wirklich brauchst, oder hätte nicht
          use CGI;
        ausgereicht?

        use CGI::Carp qw (fatalsToBrowser);

        Wäre das nicht auch in der Form
          use CGI::Carp 'fatalsToBrowser';
        denkbar?

        my $CGI;

        brauchst du nicht, weil du gleich darunter

        $CGI = new CGI();

        stehen hast. Besser wäre vielleicht:
         my $CGI = new CGI();

        Und zu überlegen wäre vielleicht auch, ob du nicht use vars () einsetzen solltest, um dir die ganzen "my" zu ersparen und die Übersicht zu behalten.

        Aber das sind alles nur Kleinigkeiten, die wenig Bedeutung haben. Problematisch wird es, wenn du

        if($CGI->param("anzeige")){
        anzeige($CGI, $DBH, $STH);
        }

        notierst. Zu diesem Zeitpunkt gibt es nämlich deine Subroutine "anzeige()" noch nicht. Schreibe also _erst_deine Subroutinen, und füge den Aufruf mit der if/else-Bedingung ganz unten an.

        Grüße aus Berlin

        Christoph S.

        1. hi

          Das sind ja auch nur zwei Zeilenumbrüche zur besseren optischen Darstellung des ausgegebenen HTML-Codes, das hat mit deinem Problem eh nix zu tun.

          auch hier mal ein link http://selfhtml.teamone.de/cgiperl/sprache/cginotwendig.htm

          dort steht so was wie dieses "nachfolgenden Daten. Da das CGI-Script sinnvollerweise HTML-Code an den Browser senden will, benutzt es den Mime-Type für HTML, nämlich text/html. Weiterhin muss ein HTTP-Header zwei abschließende Steuerzeichen für Zeilenumbruch enthalten. In Perl lässt sich ein solches Steuerzeichen durch die Zeichenfolge \n erzeugen. Durch die Anweisung:
          print "Content-type: text/html\n\n";"

          Versuchen wirs mal:

          ..
          ..
          und den rest schenke ich mir mal!!! und weises auf mein motto ||
                                                                        ||
                                                                        /

          bis bis roman

          --
          P.S. manchmal wundere ich mich schon über die postings (fragen u. antworten) die man hier geboten bekommt(meine eigenen [leider] mit eingenommen)
          => ich denke mir meinen teil und ziehe das beste daraus :-)
        2. hi!

          Bist du sicher, daß du

          use CGI qw (:standard);
          wirklich brauchst, oder hätte nicht
            use CGI;
          ausgereicht?

          Das ist kein Bug, sondern ein Feature. perldoc CGI.

          my $CGI;
          brauchst du nicht, weil du gleich darunter
          $CGI = new CGI();
          stehen hast. Besser wäre vielleicht:
          my $CGI = new CGI();

          Beides bewirkt das gleiche. Also ist nichts davon objektiv besser.

          Aber das sind alles nur Kleinigkeiten, die wenig Bedeutung haben.
          Problematisch wird es, wenn du versucht, Probleme zu erkennen, wo
          keine sind:

          if($CGI->param("anzeige")){
          anzeige($CGI, $DBH, $STH);
          }
          notierst. Zu diesem Zeitpunkt gibt es nämlich deine Subroutine
          "anzeige()" noch nicht. Schreibe also _erst_deine Subroutinen, und
          füge den Aufruf mit der if/else-Bedingung ganz unten an.

          Denn offensichtlich hast du mal wieder keine Ahnung, wovon du redest:

          A subroutine may be called using an explicit "&" prefix.
                 The "&" is optional in modern Perl, as are parentheses if
                 the subroutine has been predeclared.

          Die Klammern sind also optional, wenn die Funktion vorher deklariert
          wurde. Das bedeutet andersherum, dass man die Funktion auch später
          deklarieren kann, solange man Klammern setzt.

          bye, Frank!

          --
          Never argue with an idiot. He will lower you to his level and then
          beat you with experience.
          1. hallo Frank,

            Bist du sicher, daß du
            [...]
            Das ist kein Bug

            Habe ich ja auch nicht behauptet. Ich habe lediglich gefragt, ob da wirklich "Sicherheit" besteht, daß es in der angegebenen Form gebraucht wird.

            my $CGI;
            brauchst du nicht, weil du gleich darunter
            $CGI = new CGI();
            stehen hast. Besser wäre vielleicht:
            my $CGI = new CGI();
            Beides bewirkt das gleiche. Also ist nichts davon objektiv besser.

            Ich habe keinerlei "Objektivität" behauptet, sondern ein "vielleicht" geschrieben und einen Konjunktiv verwendet, was beides durchaus subjektiv ist. Ich selber halte es  -  ganz subjektiv  -  für besser, diese Angaben aus Gründen der Übersichtlichkeit so knapp wie möglich zu halten. Auf die "Validität" hat das keine Auswirkung, das ist richtig.

            A subroutine may be called using an explicit "&" prefix.

            Selbstverständlich, das kann so sein, aber ich habe nichts von "&" geschrieben.

            The "&" is optional in modern Perl, as are parentheses if
            the subroutine has been predeclared.
            Die Klammern sind also optional, wenn die Funktion vorher deklariert wurde.

            Das war exakt der Sinn meiner Aussage.

            Das bedeutet andersherum, dass man die Funktion auch später deklarieren kann, solange man Klammern setzt.

            _Vielleicht_ ist ja nicht ganz unwichtig, was in der Klammer steht.

            Und: siehst du eventuell in der von Thomas angegebenen Zeile

            print qq§<tr>\n<td><b> [...]

            noch irgendein Problem? Mir ist nicht bekannt, daß "§" irgendeine Bedeutung hätte, im Gegensatz zu "$", aber du darfst mich gern eines Besseren belehren.

            Denn offensichtlich hast du mal wieder keine Ahnung, wovon du redest

            Bist du sicher, daß dieser Vorwurf gerechtfertigt ist?

            Im übrigen ist es relativ selten, daß nur die Fehlermeldung "Premature end of script headers" im log oder im Browser erscheint. Meistens folgt danach die Angabe der Codezeile, in der der Fehler steckt. Und wenn man diese Zeilennummer kennt, kann man normalerweise schon etwas genauer nach dem Fehler suchen.

            Christoph S.

            --
            mailto:christoph.schnauss@berlin.de
            ss:| zu:) ls:& fo:) va:) sh:| rl:|
            1. nur ums mal kurz zu erwähnen (hab selber null ahnung davon):
              in einer newsgroup, die ich grad lese, gabs den selben fehler.
              da hatte der angemeldete user keine rechte, auf das verzeichnis zuzugreifen. (falls das ganze unter linux läuft).

              grüsse, raik

            2. hi!

              A subroutine may be called using an explicit "&" prefix.
              Selbstverständlich, das kann so sein, aber ich habe nichts von "&"
              geschrieben.

              Das war nur die Einleitung des zitierten Abschnitts und hat mit dem
              Problem nichts zu tun.

              The "&" is optional in modern Perl, as are parentheses if
              the subroutine has been predeclared.
              Die Klammern sind also optional, wenn die Funktion vorher
              deklariert wurde.
              Das war exakt der Sinn meiner Aussage.

              Der Sinn von "Zu diesem Zeitpunkt gibt es nämlich deine Subroutine
              anzeige() noch nicht. Schreibe also _erst_deine Subroutinen, und füge
              den Aufruf mit der if/else-Bedingung ganz unten an." soll sein, dass
              man beim Funktionsaufruf Klammern setzen muss, wenn die Funktion erst
              später deklariert wird? Das ist ja wohl ein schlechter Scherz.

              Ansonsten trifft es das Zitat von Torsten noch etwas genauer als
              meines.

              Das bedeutet andersherum, dass man die Funktion auch später
              deklarieren kann, solange man Klammern setzt.
              _Vielleicht_ ist ja nicht ganz unwichtig, was in der Klammer steht.

              Doch.

              Und: siehst du eventuell in der von Thomas angegebenen Zeile

              print qq§<tr>\n<td><b> [...]
              noch irgendein Problem? Mir ist nicht bekannt, daß "§" irgendeine
              Bedeutung hätte, im Gegensatz zu "$", aber du darfst mich gern
              eines Besseren belehren.

              Ab und zu wäre vielleicht ein Blick in die Dokumentation ganz
              hilfreich:

              While we usually think of quotes as literal values, in
                     Perl they function as operators, providing various kinds
                     of interpolating and pattern matching capabilities.  Perl
                     provides customary quote characters for these behaviors,
                     but also provides a way for you to choose your quote char-
                     acter for any of them.  In the following table, a "{}"
                     represents any pair of delimiters you choose.

              [...]

              Non-bracketing delimiters use the same character fore and
                     aft, [...]

              Denn offensichtlich hast du mal wieder keine Ahnung, wovon du
              redest
              Bist du sicher, daß dieser Vorwurf gerechtfertigt ist?

              Jepp.

              bye, Frank!

              --
              Never argue with an idiot. He will lower you to his level and then
              beat you with experience.
        3. Hi Christoph,

          Bist du sicher, daß du

          use CGI qw (:standard);
          wirklich brauchst, oder hätte nicht
            use CGI;
          ausgereicht?

          Umgekehrt wird ein Schuh draus, warum soll man das gesamte CGI-Modul einbinden, wenn die durch ":standard" repräsentierten Funktionen ausreichen. Siehe:
          http://www.perldoc.com/perl5.8.0/lib/CGI.html#PROGRAMMING-STYLE

          Und zu überlegen wäre vielleicht auch, ob du nicht use vars () einsetzen solltest, um dir die ganzen "my" zu ersparen und die Übersicht zu behalten.

          Hm, Perldoc bezeichnet das Modul "vars" als überflüssig:
          http://www.perldoc.com/perl5.8.0/lib/vars.html

          [...] Zu diesem Zeitpunkt gibt es nämlich deine Subroutine "anzeige()" noch nicht. Schreibe also _erst_deine Subroutinen, und füge den Aufruf mit der if/else-Bedingung ganz unten an.

          Nein, das stimmt so nicht, siehe:
          http://www.perldoc.com/perl5.8.0/pod/perlsub.html#DESCRIPTION
          "Like many languages, Perl provides for user-defined subroutines.
           These may be located anywhere in the main program, loaded in from
           other files via the do, require, or use keywords, or generated on
           the fly using eval or anonymous subroutines."

          Viele Grüße
          Torsten

  2. Hallo,

    if($CGI->param("anzeige")){
    anzeige($CGI, $DBH, $STH);
    }

    elsif($CGI->param("eintrag")){
    eintragen($CGI, $DBH, $STH);
    }

    Und es ist sicher, dass einer der beiden CGI-Parameter gesetzt wurde?

    Wenn nämlich keiner der beiden gesetzt wurde, dann gibt das Script schlicht und ergreifend gar nichts aus, was für das Perl-Script keinen Fehler bedeutet, für den Webserver aber schon.

    Grüße
      Klaus

  3. Hallo!
    Wenn ich mir über ein HTML-Formular die Einträge einer Datenbank mittels folgendem Perl-Skript anzeigen lassen möchte, bekomme ich immer die Fehlermeldung "Premature end of script headers". Wer kann mir sagen, woran dass liegen kann? In der Konsole lässt sich das Skript fehlerfrei compilieren, die Fehlermeldung erfolgt lediglich beim Aufruf über den Browser. Skript:

    naja, dein Skript wird quasi nur ausgeführt, wenn es einen Parameter gibt, d.h. an der Konsole kannst du nicht viel testen.

    use CGI qw (:standard);
    use CGI::Carp qw (fatalsToBrowser);
    use DBI;

    my $DBH;
    my $STH;
    my $CGI;
    my $antwort;

    $CGI = new CGI();

    Da du CGI.pm nutzt frag ich mich, warum du nur due Funktion param nutzt?

    ###Eintrag oder Anzeige###

    Hier ander stelle würd ich den header schicken.

    print $CGI->header();

    if($CGI->param("anzeige")){
    anzeige($CGI, $DBH, $STH);

    da CGI global definiert ist, ist der 1.Parameter nicht notwendig.

    }

    elsif($CGI->param("eintrag")){
    eintragen($CGI, $DBH, $STH);
    }

    sinnvoll wäre hier eine defaultroutine:

    besser so:
    if($CGI->param("eintrag")){

    eintragen($CGI, $DBH, $STH);

    }
    else{
    anzeige($CGI, $DBH, $STH);
    }

    ###Start Subroutine Anzeige###

    sub anzeige{

    Wo sind die Parameter?

    print <<HERE_TEXT1;
    Content-type: text/html

    <html>
    <head>
    <title>Datensätze in Datenbank</title>
    </head>
    <body>
    <center>
    <h1>Datensätze:</h1>
    <hr>
    <table border>
    <tr>
    <td width="100"><b>Kalenderwoche</b></td>
    <td width="100"><b>Einheiten</b></td>
    </tr>

    HERE_TEXT1

    print $CGI->start_html(-title => 'Datensätze in Datenbank');
    print $CGI->h1('Datensätze:');

    usw.

    CGI.pm biete viele Funktionen um HTML Tabellen und Formulare auszugeben, damit verschonst du deinen Perl Code mit dem ganzen HTML Tags.

    Gerade für Tabellen gibt es viele Möglichkeiten.

    my @rows;

    my @data;

    while (@data = $STH->fetchrow_array()){
            my $kalenderwoche = $data[0];
            my $einheiten = $data[1];
    print qq§<tr>\n<td><b>$kalenderwoche</b></td>\n<td>$einheiten</td>\n</tr>\n§;

    push @rows, $CGI->td([$data[0], $data[1]]);

    }

    print $CGI->table( $CGI->Tr( @rows) ) );

    Ansonsten empfehl ich dir, wenn du das Skript in der Konsole testest, entweder einen Wert für 'anzeige' oder 'eintrag' mal am prompt einzugeben, oder im Skript festzusetzten, da du sonst ja nicht siehst was falsch läuft:

    $CGI->param('anzeige', 1);

    Struppi.