Susanne27: Sonderzeichen

Hi!
Wie ihr aus meiner folgenden Beschreibung wahrscheinlich gleich erkennen werdet bin ich ziemliche Anfängerin...

Ich habe ein (hoffentlich) kleines Problem mit Sonderzeichen und einem wirklich primitiven CGI Script.

Auf einer HTML Seite kann man ein ein Formularfeld ausfüllen. Diese Nachricht "wandert" dann via CGI Script auf eine andere HTML Seite ("neuigkeiten.html). Diese Seite wird dann in weiterer Folge via PHP Script <?php include("inhalt.htm"); ?> in ein DIV meiner eigentlichen Website geladen.

Alles funktioniert so weit ausgezeichnet.
Das einzige Problem:
Wenn man im Formularfeld Sonderzeichen wie ä ö ü bzw Absätze eingibt, werden diese natürlich nicht korrekt dargestellt.
Deshalb meine Frage:

Kann man den folgenden CGI Script so bearbeiten, dass Sonderzeichen auf der "neuigkeiten.html" Seite richtig dargestellt werden? Bzw. Absätze übernommen werden, damit man im Formular nicht jedes Mal <br> schreiben muss.

Hier der Script:

use CGI qw(:standard) ;

@datei = "$pfad/$data" ;

print header();

$kom = param("kommentar") ;

open(FILE,"@datei");
@lines = <FILE>;
close(FILE);

@monate = ('01','02','03','04','05','06','07','08','09','10','11','12');
      ($sec,$min,$hour,$mday,$mon,$year,$wday) = (localtime(time))[0,1,2,3,4,5,6];
      if ($mday < 10) { $mday = "0$mday"; }
      if ($year > 99) { $year = $year + 1900; }
      $date = "$mday.$monate[$mon].$year ";

Eintrag ins Gästebuch hinzufügen:

open (FILE,">@datei");
foreach $line (@lines) {
      if ($line =~ /<!--name-->/) {
      print FILE "<!--name-->\n" ;
      print FILE qq~
        Eintrag am $date<br><br>

<b>$kom</b><br><br>

<hr noshade size=2><br>
~
      }
      else {
      print FILE $line ;
      }
      }
close (FILE);

&ende ;

sub ende {
print <<ENDE ;
        <div align="center"><br><br><br><br><br><br><br>
        Danke für Ihren Eintrag!
        <br><br>
        <a href="http://irgendeineseite.de">Zurück zum Gästebuch</a>
        <br><br><br><br><br><font size="-1">
        </font></div>
ENDE
}
sub fehler { print "<b>Fehler: Kein Name <br>Bitte geben Sie Ihren Namen an! <br><br><a href="javascript:history.back(-1)">zurück</a>";
last;
}
sub fehler1 { print "<b>Fehler: Keine Nachricht <br>Bitte füllen Sie das Formular neu aus! <br><br><a href="javascript:history.back(-1)">zurück</a>";
last;
}

  1. Kann man den folgenden CGI Script so bearbeiten, dass Sonderzeichen auf der "neuigkeiten.html" Seite richtig dargestellt werden? Bzw. Absätze übernommen werden, damit man im Formular nicht jedes Mal <br> schreiben muss.

    Erst mal.
    Speichere deine Scripte im gleichen Zeichensatz ob.
    Vorzugsweise UTF-8 ohne BOM

    Wenn du im Perlscript direkt Variablen definierst wie
    my $example='äöü';

    dann braucht perl zudem für UTF-8

    use :utf8;

    Dein Perlscript sollte einen httpheader mit der richtigen charset angabe ausgeben.

    print "Content-Type:text/html; charset=UTF-8\n\n";

    use CGI qw(:standard) ;

    use strict;
    use warnings;
    use :utf8; # wegen direktem textinput "Gästenbuch";

    @datei = "$pfad/$data" ;

    Kein Array! sondern ein String

    my $datei = $pfad .'/'.$data;

    print header();

    charset Angeben!

    $kom = param("kommentar") ;

    my...
    Kopieren an diesem Punkt aber überflüssig!

    open(FILE,"@datei");

    open(INFILE '<', $datei) or die ('Fehler File '. $datei. $! );

    @lines = <FILE>;

    my @lines = <INFILE>;

    close(FILE);

    close(INFILE);

    ...

    @monate = ('01','02','03','04','05','06','07','08','09','10','11','12');
          ($sec,$min,$hour,$mday,$mon,$year,$wday) = (localtime(time))[0,1,2,3,4,5,6];
          if ($mday < 10) { $mday = "0$mday"; }
          if ($year > 99) { $year = $year + 1900; }
          $date = "$mday.$monate[$mon].$year ";

    hier wäre es besser mit sprintf() zu arbeiten.

    my (undef,undef,undef,$mday,$mon,$year,undef) = localtime(time)
    my $date = sprintf("%02.%02d.%04d",
                        $mday,  $mon+1, $year+1900 );

    Eintrag ins Gästebuch hinzufügen:

    open (FILE,">@datei");

    open(OUTFILE '>', $datei) or die ('Fehler Schreiben von File '. $datei. $! );

    foreach $line (@lines) {

    foreach my $line (@lines) {

    if ($line =~ /<!--name-->/) {
            print FILE "<!--name-->\n" ;

    print OUTFILE...

    print FILE qq~
            Eintrag am $date<br><br>

    <b>$kom</b><br><br>

    Einspruch. Dein $kom enthält eventuell HTML
    also
             <b>~ . sanitize_html($kom) . qq~</b><br><br>

    Zudem kann $kom an dieser Stelle leer sein...

    <hr noshade size=2><br>
    ~
          }
          else {
            print FILE $line ;

    print OUTFILE $line ;

    }
       }
    close (FILE);

    close (OUTFILE);

    verwende die Drei-Argumente-Form von open.
    Verwende für Filehandles entweder
    my $infh, my $outfh
    oder INFILE, OUTFILE.
    Grund: Lesbarkeit. gleich benannte Filehandes im gleichen Blockscope von Typ FILE sind Fehleranfällig.

    sub sanitize_html{
      my $t = shift || '';
      $t=~ s/</&lt;/g;
      $t=~ s/>/&gt;/g;
      $t=~ s/&/&amp;/g;
      $t=~ s/"/&quot/g;
      return $t;
    }

    &ende ;

    veraltet. Verwende:
    ende();

    sub ende {
    print <<ENDE ;
            <div align="center"><br><br><br><br><br><br><br>
            Danke für Ihren Eintrag!
            <br><br>
            <a href="http://irgendeineseite.de">Zurück zum Gästebuch</a>
            <br><br><br><br><br><font size="-1">
            </font></div>
    ENDE
    }
    sub fehler { print "<b>Fehler: Kein Name <br>Bitte geben Sie Ihren Namen an! <br><br><a href="javascript:history.back(-1)">zurück</a>";
    last;
    }
    sub fehler1 { print "<b>Fehler: Keine Nachricht <br>Bitte füllen Sie das Formular neu aus! <br><br><a href="javascript:history.back(-1)">zurück</a>";
    last;
    }

    mfg Beat

    --
    ><o(((°>           ><o(((°>
       <°)))o><                     ><o(((°>o
    Der Valigator leibt diese Fische
    1. hi,

      oder INFILE, OUTFILE.
      Grund: Lesbarkeit. gleich benannte Filehandes im gleichen Blockscope von Typ FILE sind Fehleranfällig.

      Hmm. Wenn ~FILE ohnehin der Kontext ist, kann das auch entfallen, also <IN>, <OUT> ;-)

      Hotti

    2. use :utf8;

      Vorsicht, Fehler. Dieses Statement tut nichts.

        
      
      > perl -e'use Devel::Peek; Dump "öäüß"' 2>&1 | ack PV.=  
      
        PV = 0x8ca540 "\303\266\303\244\303\274\303\237"\0  
      
      > perl -e'use :utf8; use Devel::Peek; Dump "öäüß"' 2>&1 | ack PV.=  
      
        PV = 0x8ca6d0 "\303\266\303\244\303\274\303\237"\0  
      
      > perl -e'use utf8; use Devel::Peek; Dump "öäüß"' 2>&1 | ack PV.=  
      
        PV = 0x8c9790 "\303\266\303\244\303\274\303\237"\0 [UTF8 "\x{f6}\x{e4}\x{fc}\x{df}"]  
      
      
      1. use :utf8;
        Vorsicht, Fehler. Dieses Statement tut nichts.

        Doch es (wenn der Doppelpunkt weggemacht wird) sagt dem Interpreter, das der Perlcode in utf8 vorliegt. Was in diesem Fall ziemlich unnütz ist.

        Struppi.

        1. Struppi, ich bezog mich genau auf diese seltsame (falsche) Schreibweise. Aus dem Beispiel wird implizit klar, dass der Doppelpunkt weggelassen werden muss.

  2. Wow! Vielen Dank Beat!!!

    Dann werd' ich mal am Script rumbasteln...

    Danke und Lg,
    Susanne

  3. moin,

    Wie ihr aus meiner folgenden Beschreibung wahrscheinlich gleich erkennen werdet bin ich ziemliche Anfängerin...

    Es gibt für alles ein "Erstesmal". Jeder Webserver generiert einen HTTP-Header mit einem DefaultCharset. Genau hier musst Du eingreifen, denn das ist nicht immer das was Du willst. Wenn alle Seiten dieselbe Kodierung (1) utf-8 haben sollen, schreib in die .htaccess:

    AddDefaultCharset UTF-8

    Falls das (1) nicht der Fall ist, lege das im jeweiligen Script PHP oder Perl mit der header() Funktion fest. Dazu ist eine globale Variable ganz hilfreich, ich mache das einfach so:

    Perl => $ENV{'charset'} = 'utf-8';
    PHP  => $_SERVER{'charset'} = 'utf-8';

    also in das globale Array der Serverumgebung, dafür gibts bei mit für Perl/PHP jeweils eine Basis-Library, wo das reinkommt (2). Desweiteren muss charset auch im Kopf einer jeden HTML-Datei deklariert sein:

    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

    und das muss mit dem charset im HTTP-Header überinstimmen. Dafür sorgt sowohl die header() Funktion (HTTP) als auch eine eigene Funktion, die den HTML-Header erzeugt.

    (1)(2) definiere für jede Seite eine Tabelle, wo deren Eigenschaften festgelegt sind, eine der Eigenschaften ist die Zeichenkodierung.

    Bei PHP musst Du aufpassen, dass der Parser nicht eigenständig einen header feuert, das macht der nämlich, wenn außerhalb <?php ?> was steht, und das kann schon ein Leerzeichen oder eine Leerzeile bewirken, auch in den Dateien, die mit include() eingebunden werden.

    Hotti