paul: problem mit textcodierung!

hallo,

ich habe ein texteingabefeld. der inhalt wird an eine mysql-datenbank geschickt. nun passieren sonderbare dinge:

szenario 1: ich habe im webformular als textcodierung "utf-8" eingestellt und schicke das ganze an die datenbank. wenn ich das ergebnis auf einer html-seite anzeigen lasse, die ebenfalls utf-8 kodiert ist, steht z.b. statt einem Ä dann ein A mit einer Wellenlinie drüber (ich kann es hier nicht einfügen, weil das forum das zeichen nicht zulässt...)
das Ä wird nur richtig dargestellt, wenn ich bei der eingabe auf ISO Latin1 schalte, und bei der Ausgabe auf utf-8. das ist doch eigenartig, oder,? hat das mit mySql zu tun?

an und für sich könnt ich ja dann die entsprechende codierung angeben, damits funktioniert, aber erstens möchte ich wissen, was da eigentlich abläuft, und zweitens habe ich ein "update"-formular, das die vorhandenen daten anzeigt und auch in die db einträgt. klarerweise hab ich dann den konflikt, welche zeichencodierung ich auswählen soll...

danke für eure hilfe!

  1. Hi!

    ich habe ein texteingabefeld. der inhalt wird an eine mysql-datenbank geschickt. nun passieren sonderbare dinge:

    Zwei Grundregeln sind da zu beachten. Jedes am Verarbeitungsprozess beteiligte System muss für sich mit der gewählten Kodierung umgehen können oder die Daten unverändert durchreichen können. Zwischen zwei Systemen muss die zu verwendende Kodierung bekannt sein oder ausgehandelt/angegeben werden.

    Diese Fragen solltest du für dich beantworten: Welches sind die beteiligten Systeme? Wo sind die Schnittstellen? Was wird für eine Kodierung wird da jeweils verwendet und wie wird diese bekanntgegeben?

    das Ä wird nur richtig dargestellt, wenn ich bei der eingabe auf ISO Latin1 schalte, und bei der Ausgabe auf utf-8. das ist doch eigenartig, oder,? hat das mit mySql zu tun?

    Dann hast du eine oder mehrere dieser erwähnten Schnittstellen nicht ausreichnd mit Information versorgt oder behandelst die Daten innerhalb der Systeme nicht richtig. Finde das heraus. Bei Fragen dazu: Stell sie bitte.

    Lo!

    1. Danke, ich möchte natürlich eine einheitl. Codierung verwenden. Das problem scheint die mySql-db zu sein,und ich hab keine ahnung,wie ich dort die codierung beeinflussen kann?? Kan ich das in phpmyAdmin irgendwo tun?(hab vers. 2.5.6 am server laufen)

      Zwei Grundregeln sind da zu beachten. Jedes am Verarbeitungsprozess beteiligte System muss für sich mit der gewählten Kodierung umgehen können oder die Daten unverändert durchreichen können. Zwischen zwei Systemen muss die zu verwendende Kodierung bekannt sein oder ausgehandelt/angegeben werden.

      Diese Fragen solltest du für dich beantworten: Welches sind die beteiligten Systeme? Wo sind die Schnittstellen? Was wird für eine Kodierung wird da jeweils verwendet und wie wird diese bekanntgegeben?

      das Ä wird nur richtig dargestellt, wenn ich bei der eingabe auf ISO Latin1 schalte, und bei der Ausgabe auf utf-8. das ist doch eigenartig, oder,? hat das mit mySql zu tun?

      Dann hast du eine oder mehrere dieser erwähnten Schnittstellen nicht ausreichnd mit Information versorgt oder behandelst die Daten innerhalb der Systeme nicht richtig. Finde das heraus. Bei Fragen dazu: Stell sie bitte.

      Lo!

      1. Hi,

        bite sinnvoll zitieren, nicht alles, und kein TOFU produzieren - danke!

        Danke, ich möchte natürlich eine einheitl. Codierung verwenden. Das problem scheint die mySql-db zu sein,und ich hab keine ahnung,wie ich dort die codierung beeinflussen kann??

        Google: mysql kodierung aushandeln -> erster Treffer: </archiv/2008/11/t178773/>

        MfG ChrisB

        --
        Light travels faster than sound - that's why most people appear bright until you hear them speak.
    2. hi,

      Dann hast du eine oder mehrere dieser erwähnten Schnittstellen nicht ausreichnd mit Information versorgt oder behandelst die Daten innerhalb der Systeme nicht richtig. Finde das heraus. Bei Fragen dazu: Stell sie bitte.

      ich habe nun meines wissens nach überall utf-8 eingestellt, auch in den entsprechenden db-feldern in der datenbank. jetzt kommt es zu folgenden ungereimtheiten: im safari/mac sind die umlaute der get-parameter durch diverse kryptische zeichen vertreten, auch im dokument selbst werden sie so dargestellt.
      im firefox/mac sind sowohl in der url-zeile, als auch im dokument die umlaute zu sehen. kann es sein, dass der safari die umlaute anders codiert, obwohl immer utf-8 angegeben ist?

      p

      1. Hi!

        ich habe nun meines wissens nach überall utf-8 eingestellt, auch in den entsprechenden db-feldern in der datenbank.

        Bitte beschreibe das was du gemacht hast genauer, so dass man aus den Details eventuelle Fehler erkennen kann.

        Die Einstellungen der Felder ist der erste Schritt. Der sorgt dafür, dass MySQL intern in der Lage ist, das volle Spektrum der UTF-8-Möglichkeiten zu speichern. Wie schaut es mit der Schnittstelle zu anderen Systemen aus? Hast du die Kommunikation auch definiert auf UTF-8 gestellt?

        Ein Hilfsmittel, um die Korrektheit der Daten zu überprüfen ist der phpMyAdmin. Der kann ordnungsgemäß mit den Kodeirungen umgehen. Wenn der alles richtig anzeigt, kann man davon ausgehen, dass die Daten ordnungsgemäß abgelegt wurden. Wenn nicht, hat MySQL aufgrund der vermutlich nicht ausgehandelten Verbindungskodierung die Daten anders interpretiert als du es dir gedacht hast.

        jetzt kommt es zu folgenden ungereimtheiten: im safari/mac sind die umlaute der get-parameter durch diverse kryptische zeichen vertreten, auch im dokument selbst werden sie so dargestellt.

        Das ist eine Browser-Geschichte. Hast du diesem gesagt, welche Kodierung du verwendest? Verwendest du diese Kodierung tatsächlich?

        Die charset-Angabe im HTTP-Header Content-Type ist die maßgebliche Stelle. Fehlt dort ein Eintrag, darf der Browser diese Information aus dem gleichnamigen Meta-Element nehmen. Prüfen welche Kodierung vorliegt, kann man, indem man dem Browser (meist) im Menü Ansicht die Zeichenkodierung händisch einstellt. Werden dann alle Zeichen richtig dargestellt, kann man davon ausgehen, dass die Daten in dieser Kodierung vorliegen.

        Wie die GET-Parameter im Browser aussehen, ist erstmal zweitrangig. Er wird normalerweise die Kodierung der Seite verwenden, in der das abzusendende Formular liegt. (Das accept-charset-Attribut arbeitet browserübergreifend nicht hinreichend zufriedenstellend.)

        Was sieht das empfangende Programm? Wenn du die ankommenden Daten mal durch url_encode() geschickt anzeigen lässt, siehst du unter anderem auch für die Umlaute die Bytewerte. Als Faustregel: UTF-8-Umlaute verwenden zwei %XX-Werte, ISO-8859-1-Umlaute nur einen.

        Den url_encode()-Trick kannst du auch auf die zum Browser zu senden Daten anwenden oder aber auch schon an der Stelle, an der sie aus dem DBMS kommen, um Rückschlüsse auf die vorliegende Kodierung zu ziehen.

        im firefox/mac sind sowohl in der url-zeile, als auch im dokument die umlaute zu sehen. kann es sein, dass der safari die umlaute anders codiert, obwohl immer utf-8 angegeben ist?

        Er rät vielleicht anders als die anderen. Wenn alle Angaben richtig gesetzt wurden, macht eigentlich kein Browser was verkehrt.

        Lo!

        1. whow, danke für die ausführliche antwort;-)

          Die Einstellungen der Felder ist der erste Schritt. Der sorgt dafür, dass MySQL intern in der Lage ist, das volle Spektrum der UTF-8-Möglichkeiten zu speichern. Wie schaut es mit der Schnittstelle zu anderen Systemen aus? Hast du die Kommunikation auch definiert auf UTF-8 gestellt?

          Ich habe jetzt eine neuere version von phpMyAdmin. hier habe ich bei den db-feldern überall "utf8_unicode_ci" angegeben, ebenso für die gesamte tabelle. wo kann ich die kommunikation einstellen??

          Die charset-Angabe im HTTP-Header Content-Type ist die maßgebliche Stelle. Fehlt dort ein Eintrag, darf der Browser diese Information aus dem gleichnamigen Meta-Element nehmen. Prüfen welche Kodierung vorliegt, kann man, indem man dem Browser (meist) im Menü Ansicht die Zeichenkodierung händisch einstellt. Werden dann alle Zeichen richtig dargestellt, kann man davon ausgehen, dass die Daten in dieser Kodierung vorliegen.

          ich habe auf jeder seite, die im spiel war, den zeichensatz im browser manuell auf utf-8 gestellt. auch in den html-seiten ist utf-8 angegeben...

          Den url_encode()-Trick kannst du auch auf die zum Browser zu senden Daten anwenden oder aber auch schon an der Stelle, an der sie aus dem DBMS kommen, um Rückschlüsse auf die vorliegende Kodierung zu ziehen.

          ok, werd ich mir mal vorknöpfen.

          Er rät vielleicht anders als die anderen. Wenn alle Angaben richtig gesetzt wurden, macht eigentlich kein Browser was verkehrt.

          verstehe...

          prinzipiell für mein verständnis: habe ich vielecht irgendwo eine utf-angabe zu setzen, an die ich nicht gedacht habe? mein setting: php-dokumente mit enthaltenen (html-)foormularen, die daten an eine mySql-db schicken und wieder abholen. wie gesagt, die html-docs und auch die db sollten jetzt utf8 sein. muß ich für php irgendwo vielleicht extra noch die codierung angeben?

          p

          Lo!

          1. Hi!

            whow, danke für die ausführliche antwort;-)

            Zu dem Thema gibt es übrigens schon eine ganze Menge derartiger Antworten im Archiv.

            Ich habe jetzt eine neuere version von phpMyAdmin. hier habe ich bei den db-feldern überall "utf8_unicode_ci" angegeben, ebenso für die gesamte tabelle.

            Die Werte für Tabelle und Datenbank sind nur Default-Werte für neu angelegte Elemente (Tabelle->Felder und Datenbank->Tabellen)

            wo kann ich die kommunikation einstellen??

            Wenn man es sich recht überlegt, sollten einem zwei Stellen einfallen. Zum einen sind bei einer Kommunikation zwei Geräte beteiligt, also sind zwischen diesen beiden die Parameter dieser Kommunikation auszuhandeln. Zum anderen gibt es einen Default-Wert, der Server-weit eingestellt wird.

            Auf den Server-Default-Wert sollte man sich nach Möglichkeit nicht verlassen. Nach erfolgreichem Verbindungsaufbau sollte deshalb die Kodierung mit mysql(i)_set_charset() (PHP vorausgesetzt) vereinbart werden. Wenn diese Funktion nicht zur Verfügung steht, kann man ein SET NAMES-Statement absetzen. Das ist zwar weniger gut als die Funktion, aber für die hierzulande üblichen Kodierungen der ISO-8859-Familie und UTF-8 ausreichend.

            Die charset-Angabe im HTTP-Header Content-Type ist die maßgebliche Stelle. Fehlt dort ein Eintrag, darf der Browser diese Information aus dem gleichnamigen Meta-Element nehmen. Prüfen welche Kodierung vorliegt, kann man, indem man dem Browser (meist) im Menü Ansicht die Zeichenkodierung händisch einstellt. Werden dann alle Zeichen richtig dargestellt, kann man davon ausgehen, dass die Daten in dieser Kodierung vorliegen.

            ich habe auf jeder seite, die im spiel war, den zeichensatz im browser manuell auf utf-8 gestellt. auch in den html-seiten ist utf-8 angegeben...

            Wenn er nicht bereits auf UTF8 steht, dann hast du noch eine Baustelle. Was der Server in seinen HTTP-Headern sendet, findest du beispielsweise mit der Livehttpheaders-Extension für den Firefox raus (betrachte den Response-Teil). Selbst setzen kannst du das unter PHP mit der Funktion header().

            prinzipiell für mein verständnis: habe ich vielecht irgendwo eine utf-angabe zu setzen, an die ich nicht gedacht habe? mein setting: php-dokumente mit enthaltenen (html-)foormularen, die daten an eine mySql-db schicken und wieder abholen. wie gesagt, die html-docs und auch die db sollten jetzt utf8 sein. muß ich für php irgendwo vielleicht extra noch die codierung angeben?

            Betrachte jeden Request und jede Verbindung einzeln. Ein Browser tut das auch. Er nimmt sich generell die für das aktuelle Dokument angegebenen Angaben. Wenn dein Webserver (z.B. Apache) nicht generell eine charset-Angabe mitsendet, solltest du möglichst einen eigenen HTTP-Header _mit_ dieser Angabe senden. Zusätzlich schadet das Meta-Element nicht (besonders wenn das Dokument lokal gespeichert wird wäre die wichtig). Zum DBMS hin, füge zu jedem mysql_connect() ein mysql_set_charset() (oder SET NAMES) hinzu.

            Lo!

            1. hi,

              Zu dem Thema gibt es übrigens schon eine ganze Menge derartiger Antworten im Archiv.

              ja, ich hab auch einiges dazu gelesen, trotzdem ist das nochmalige neuformulieren deinerseits sehr hilfreich...

              Die Werte für Tabelle und Datenbank sind nur Default-Werte für neu angelegte Elemente (Tabelle->Felder und Datenbank->Tabellen)

              alles klar...

              Wenn er nicht bereits auf UTF8 steht, dann hast du noch eine Baustelle. Was der Server in seinen HTTP-Headern sendet, findest du beispielsweise mit der Livehttpheaders-Extension für den Firefox raus (betrachte den Response-Teil). Selbst setzen kannst du das unter PHP mit der Funktion header().

              nö,nö, im header steht eh auch utf-8, ich habe mir die header auch ausgeben lassen, und da stimmts auch. ich schätze, es hat entweder mit der übertragung in die datenbank oder mit der db selbst zu tun.

              ich habe auch zwei schwachstellen gefunden:

              wen ich mir in der db mit "SHOW VARIABLES LIKE 'char%'" die werte ausgeben lasse, sieht das folgendermassen aus:

              character_set_client   utf8
              character_set_connection  utf8
              character_set_database   latin1
              character_set_filesystem  binary
              character_set_results   utf8
              character_set_server   latin1
              character_set_system   utf8

              die von mir eingerichtete tabelle steht auf utf-8, die datenbank selbst aber auf "latin1_swedish_ci". was für auswirkungen hat es, wenn die db als ganzes  latin1_swedish_ci ist, die tabelle aber utf-8? ist nicht die tabelle "wichtiger?"

              ich habe also eine db und einen db-server in der falschen codierung. in phpMyAdmin läßt sich das aber nicht ändern. ist das eine sache für den server-admin, oder kann ich das doch selbst beeinflussen? muß ich das dann in jeder datei tun, oder kann ich das global umstellen? sorry für die laienfragen, aber ich habe mich mit diesem thema bis jetzt nicht beschäftigt, da ich offensichtlich mit den eingestellten default-werten an allen ecken und enden glück hatte;-)

              wie schätzt du das ein, meinst du, dass wir da den fehler in der db entdeckt haben?

              Lo!

              1. Hi!

                die von mir eingerichtete tabelle steht auf utf-8, die datenbank selbst aber auf "latin1_swedish_ci". was für auswirkungen hat es, wenn die db als ganzes  latin1_swedish_ci ist, die tabelle aber utf-8? ist nicht die tabelle "wichtiger?"

                Nein, nur die Einstellung jedes einzelnen Feldes zählt. Der Datenbankwert hat außer seiner Defaultwerteigenschaft nur noch dann eine Bedeutung, wenn man statt SET NAMES ein SET CHARACTER SET verwendet. Aber letzteres benötigt man normalerweise nicht, und sollte es auch nicht verwenden, wenn man seine Auswirkungen nicht kennt.

                Du kannst aber diesen Wert umstellen, wenn du willst. Beispielsweise über den phpMyAdmin die Datenbank anwählen und dort im Reiter Operationen.

                ich habe also eine db und einen db-server in der falschen codierung. in phpMyAdmin läßt sich das aber nicht ändern. ist das eine sache für den server-admin, oder kann ich das doch selbst beeinflussen? muß ich das dann in jeder datei tun, oder kann ich das global umstellen?

                Diese Defaultwerte brauchen dich nicht zu kümmern, wenn du explizit nach dem Verbindungsaufbau die für diese Verbindung zu verwendende Kodierung aushandelst. Zusammen mit den Feldkodierungseinstellungen sind das eigentlich die zwei für den Endanwender zu beachtenden Dinge.

                wie schätzt du das ein, meinst du, dass wir da den fehler in der db entdeckt haben?

                Kann gut sein. Stell einfach nur die Feldkodierung und die Verbindungskodierung ein, und alles sollte gut werden. Jedenfalls was die Datenbankkommunikation und Speicherung anbelangt und wenn du ihr nach der Verbindungskodierungaushandlung auch tatsächlich UTF-8-kodierte Daten sendest.

                Lo!

                1. ich bins nochmal,

                  also, so wies aussieht, hab ich überall utf-8. ich glaube mittlerweile, es hat garnichts mit der db zu tun, sondern damit, wie die php-datei meine daten weitergibt. ein beispiel:
                  hiergibt es ein testformular, das den eintrag weitergibt, und
                  diese datei wertet das ganze aus. alles auf utf-8 eingestellt, und wenn du mal einen umlaut eingibst, hast du bei der auswertung schon den salat;-)

                  jetzt ist mir folgendes aufgefallen:
                  ich habe einen teil des php-scripts vor dem header in der php-datei stehen, und zwar genau den teil, der die get-parameter für die url erzeugt. liegt da der hund begraben? ich muß den php-block aber da stehen haben, sonst bekomme ich einen "headers already sent"-error...

                  hier mal der quellcode der datei test1.php:

                    
                  <?php  
                  if(isset ($_POST['submit'])and ($_POST['submit'] =='Versenden')){# wenn Formular abgeschickt wurde:  
                  header("Location: weiterleitung.php?vorname=".$_POST['vorname']."");}	  
                  ?>  
                  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">  
                  <html>  
                  <head>  
                  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
                  <title>Formular</title>  
                  </head>  
                    
                  <body>  
                  <form method="POST" action="<?php echo $_SERVER['PHP_SELF']?>" name="kontakt">  
                  <p>Vorname:</p>  
                  <p><input name="vorname" type="text" class="input" id="vorname" title="Hier den Vornamen eingeben!" value="<?php if(isset ($_POST['vorname'])){echo $_POST['vorname'];}?>" size="12" ></p>  
                    
                  <p><input name="submit" type="submit" title="Kontakt Eintragen" value="Versenden"></p>  
                    
                  </form>  
                  </body>  
                  </html>  
                  
                  
                  1. Hi,

                    hiergibt es ein testformular, das den eintrag weitergibt, und
                    diese datei wertet das ganze aus. alles auf utf-8 eingestellt, und wenn du mal einen umlaut eingibst, hast du bei der auswertung schon den salat;-)

                    Also http://viennaclassicalplayers.com/VCP2.0/weiterleitung.php?vorname=aäuüoö gibt mir aäuüoö so wieder aus, wie ich's eingegeben habe.

                    ich habe einen teil des php-scripts vor dem header in der php-datei stehen, und zwar genau den teil, der die get-parameter für die url erzeugt. liegt da der hund begraben?

                    if(isset ($_POST['submit'])and ($_POST['submit'] =='Versenden')){# wenn Formular abgeschickt wurde:
                    header("Location: weiterleitung.php?vorname=".$_POST['vorname']."");}

                    Du übergibst hier Daten in den Kontext URL, nimmst aber keine diesem Kontext gerechte Kodierung der Daten vor - und damit überlässt du sie dem Browser.
                    In den meisten Browsern kann man einstellen, ob URL(-Bestandteile), so sie denn vom Browser selbst kodiert werden müssen, in UTF-8 kodiert werden sollen oder nicht - und wenn du das nicht eingestellt hast, dann verwendet dein Browser wohl irgendeine andere Kodierung, und damit kommt natürlich dann Murks heraus, wenn du diese nicht in UTF-8 übermittelten Daten dann wieder als UTF-8 kodierte zu interpretieren versuchst.

                    MfG ChrisB

                    --
                    Light travels faster than sound - that's why most people appear bright until you hear them speak.
                  2. Hi!

                    also, so wies aussieht, hab ich überall utf-8. ich glaube mittlerweile, es hat garnichts mit der db zu tun, sondern damit, wie die php-datei meine daten weitergibt. ein beispiel:
                    hiergibt es ein testformular, das den eintrag weitergibt, und
                    diese datei wertet das ganze aus. alles auf utf-8 eingestellt, und wenn du mal einen umlaut eingibst, hast du bei der auswertung schon den salat;-)

                    Nö, hab ich nicht. Aber der Reihenfolge nach:
                    Ich sehe, dass die Seite test1.php keine charset-Angabe im HTTP-Header Content-Type mitsendet, aber es gibt als Ersatz ein Meta-Element dafür. Ich tippe ein:

                    <"ä

                    und bekomme angezeigt

                    Vorname: <\"ä

                    und der Firefox 3.0 zeigt als URL

                    .../weiterleitung.php?vorname=<"ä

                    Dabei sehe ich kein Problem, was das UTF-8 anbelangt, dafür aber vier andere.
                    Der Livehttpheaders-Mitschnitt zeigt als POST-Daten

                    vorname=%3C%22%C3%A4&submit=Versenden

                    Mein Browser nimmt für das ä die zwei UTF-8-Byte und zusammen mit den anderen Zeichen URL-kodiert er die Eingabe. Als Antwort erhalte ich (gekürzt)

                    HTTP/1.x 302 OK
                      Content-Type: text/html
                      Location: weiterleitung.php?vorname=<"ä
                      X-Powered-By: PHP/4.4.4, ASP.NET

                    Es gibt also einen Redirect (Status 302), die PHP-Version ist uralt und der Content-Type enthält keine charset-Angabe. Mein Browser darf in dem Fall raten und er rät richtig. (Zum \ vor dem " sag ich später noch was.)

                    Mein Browser fragt also nach

                    GET /VCP2.0/weiterleitung.php?vorname=%3C%22%C3%A4 HTTP/1.1

                    und bekommt die oben erwähnte Ausgabe.

                    Für die Weiterleitung ist diese Zeile zuständig:

                    header("Location: weiterleitung.php?vorname=".$_POST['vorname']."");}

                    Das Anfügen eines Leerstrings an einen String ist eine sinnlose Handlung. Es ändert an dem String nichts und hat auch keine Nebenwirkungen (à la Integer verknüpft mit Leerstring ergibt einen Typecast des Integers nach String), die man vielleicht ausnutzen könnte.

                    Nicht beachtet hast du, dass ein Location-Header gemäß Vorschrift eine vollständige URL benötigt. In den meisten Fällen machen die Browser trotzdem das von dir Vorgesehene. Wichtiger ist, dass du da einen URL-Kontext hast, und die Daten URL-kodiert einfügen musst. Ansonsten kann man dir beliebig den Querystring manipulieren.

                    Obendrein fummelt das PHP-Feature Magic Quotes in den Daten rum, ohne dass das da sinnvoll wäre. Zu den Magic Quotes kannst du den Abschnitt PHP-Besonderheit Magic Quotes lesen. Auch der Rest (der Vorabversion) des Artikels Kontextwechsel erkennen und behandeln wird einge Sachen enthalten, die du vielleicht bisher noch nicht berücksichtigst. Die Magic Quotes jedenfalls sorgen bei der ersten Runde dafür, dass aus dem " ein " wird. Beim Redirect wird aus dem \ ein \ und das " wiederum zum ", zusammen ergibt das: \"
                    Magic Quotes solltest du deaktiveren und die Kontextwechsel zur Datenbank hin und in alle anderen Richtungen selbst und passend behandeln.

                    Wenn ich mir den Quelltext ansehe, sehe ich

                    <p>Vorname: <\"ä</p>

                    Wenn ein < kein Tag-Öffner ist, wie muss das dann in HTML notiert werden? Du hast da den nächsten nicht beachteten Kontextwechsel. In dem zitierten Code von test1.php sind weitere Stellen:

                    <form method="POST" action="<?php echo $_SERVER['PHP_SELF']?>" name="kontakt">

                    Das unbehandelte Einfügen von $_SERVER['PHP_SELF'] eignet sich zum Manipulieren des form-Elements. Da muss mindestens ein htmlspecialchars() drumrum.

                    Das gleiche Problem befindet sich hier (gekürzt):

                    <input name="vorname" type="text" value="<?php echo $_POST['vorname'];?>"></p>

                    Zum Umlautproblem: PHP reicht die Daten nur durch, ohne daran was zu ändern. Die einzige Stelle, die da was ändert, muss dein Browser sein, der anders rät als meiner. Ob du ihm das Raten mit einem selbst gesetzten Content-Type-Header inklusive charset-Angabe abgewöhnen kannst, vermag ich nicht mit Bestimmtheit zu sagen. Jedoch empfehle ich dir, zunächst den Ablauf selbst einmal nachzuvollziehen, so wie ich das gemacht habe. Nimm dir dazu die Livehttpheaders-Extension und den FF oder ein ähnlich arbeitendes Tool für deinen Browser. Kontrollausgaben können ebenfalls hilfreich sein. Wenn du das nachvollzogen hast, und eventuell Unterschiede zu dem von mir beobachteten Verhalten sieht, füg die Headerzeile ein und schau erneut, sowohl die Auswirkungen als auch die interne Arbeitsweise. Wenn du das Problem nicht lösen kannst, so solltest du nun ein paar neue Beobachtungen gemacht haben, aus denen man vielleicht weitere Schlüsse ziehen kann.

                    Zum Abschluss noch:

                    ich muß den php-block aber da [vor dem <!DOCTYPE usw.] stehen haben, sonst bekomme ich einen "headers already sent"-error...

                    Beschäftige dich mal mit dem Thema EVA-Prinzip und der Aufteilung des Codes in Dateneingabe, -verarbeitung und -ausgabe. Dann sollte es dich auch nicht mehr wundern, wenn PHP-Blöcke vor dem HTML rumstehen.

                    Lo!

                    1. hi,

                      Nö, hab ich nicht. Aber der Reihenfolge nach:
                      Ich sehe, dass die Seite test1.php keine charset-Angabe im HTTP-Header Content-Type mitsendet, aber es gibt als Ersatz ein Meta-Element dafür.

                      wie lege ich in der datei im header das charset fest? ich habe überall nur hinweise auf die meta-angabe gefunden, und diverse web-editoren machen das meines wissens nach auch so. ist das also wirklich notwendig? weim w3c hab ich auch nur die meta-variante gefunden. ein link wäre hier sehr hilfreich;-)

                      ich habe jetzt in der url-weiterleitung urlencode() eingefügt. jetzt zeigt auch der safari die umlaute richtig an... passt das so, was die url-weitergabe betrifft??

                      Das Anfügen eines Leerstrings an einen String ist eine sinnlose Handlung. Es ändert an dem String nichts und hat auch keine Nebenwirkungen (à la Integer verknüpft mit Leerstring ergibt einen Typecast des Integers nach String), die man vielleicht ausnutzen könnte.

                      hab ich entfernt. es kam zustande, weil ich die datei, die eigentlich ein sehr umfangreiches formular behandelt, auf ein minimum zusammengekürzt habe, da hab ich das übersehen...

                      Nicht beachtet hast du, dass ein Location-Header gemäß Vorschrift eine vollständige URL benötigt. In den meisten Fällen machen die Browser trotzdem das von dir Vorgesehene. Wichtiger ist, dass du da einen URL-Kontext hast, und die Daten URL-kodiert einfügen musst. Ansonsten kann man dir beliebig den Querystring manipulieren.

                      ok, die URL sollte follständig sein, aber abgesehen davon passt das jetzt?

                      Obendrein fummelt das PHP-Feature Magic Quotes in den Daten rum, ohne dass das da sinnvoll wäre. Zu den Magic Quotes kannst du den Abschnitt PHP-Besonderheit Magic Quotes lesen. Auch der Rest (der Vorabversion) des Artikels Kontextwechsel erkennen und behandeln wird einge Sachen enthalten, die du vielleicht bisher noch nicht berücksichtigst. Die Magic Quotes jedenfalls sorgen bei der ersten Runde dafür, dass aus dem " ein " wird. Beim Redirect wird aus dem \ ein \ und das " wiederum zum ", zusammen ergibt das: \"
                      Magic Quotes solltest du deaktiveren und die Kontextwechsel zur Datenbank hin und in alle anderen Richtungen selbst und passend behandeln.

                      ok, das ist wohl ein eigenes kapitel, das jetzt nicht unbedingt mit dem umlaut-problem zusammenhängt, oder? ich habe nämlich ein sehr umfangreiches projekt daran hängen, das eigentlich bis auf die umlaute sehr gut funktioniert, und ich möchte da jetzt kein risiko eingehen, bzw. hab ich auch nicht die zeit, zig dateien umzuschreiben. ich heb mir das lieber fürs nächste projekt auf. oder glaubst du, spielt das doch eine rolle bei der umlaut-problematik?

                      Jedoch empfehle ich dir, zunächst den Ablauf selbst einmal nachzuvollziehen, so wie ich das gemacht habe. Nimm dir dazu die Livehttpheaders-Extension und den FF oder ein ähnlich arbeitendes Tool für deinen Browser.

                      hast du einen tipp für mich, ich habe firefox 3.0.6 installiert, und da geht die extension nicht. ausserdem hab ich safari 3.2.1 zur verfügung (ich bin nicht auf meinem heim-pc...)

                      Wenn du das Problem nicht lösen kannst, so solltest du nun ein paar neue Beobachtungen gemacht haben, aus denen man vielleicht weitere Schlüsse ziehen kann.

                      wie gesagt, safari gibt die umlaute jetzt richtig aus, nachdem ich urlencode() eingefügt habe...

                      Zum Abschluss noch:

                      Beschäftige dich mal mit dem Thema EVA-Prinzip und der Aufteilung des Codes in Dateneingabe, -verarbeitung und -ausgabe. Dann sollte es dich auch nicht mehr wundern, wenn PHP-Blöcke vor dem HTML rumstehen.

                      hat mich bis jetzt auch nicht gewundert- ich hab es schon oft wo gesehen und selbst verwendet...

                      danke für deine hilfe, ich bin jetzt richtig abhängig von dir;-)

                      p

                      1. Hi,

                        Ich sehe, dass die Seite test1.php keine charset-Angabe im HTTP-Header Content-Type mitsendet, aber es gibt als Ersatz ein Meta-Element dafür.

                        wie lege ich in der datei im header das charset fest?

                        Allgemein in der Serverkonfiguration (.htaccess, AddCharset), in der PHP-Kofiguration (default_charset), oder mit der Funktion header, mit der du selber eine Angabe a la "Content-Type: text/html, charset=utf-8" als Header senden lässt.

                        Obendrein fummelt das PHP-Feature Magic Quotes in den Daten rum, ohne dass das da sinnvoll wäre. [...]

                        ok, das ist wohl ein eigenes kapitel, das jetzt nicht unbedingt mit dem umlaut-problem zusammenhängt, oder? ich habe nämlich ein sehr umfangreiches projekt daran hängen, das eigentlich bis auf die umlaute sehr gut funktioniert, und ich möchte da jetzt kein risiko eingehen, bzw. hab ich auch nicht die zeit, zig dateien umzuschreiben. ich heb mir das lieber fürs nächste projekt auf. oder glaubst du, spielt das doch eine rolle bei der umlaut-problematik?

                        Nein, für die Umlaut-Problematik nicht.

                        Aber wenn du das nicht abfängst, und bei sämtlichen Nutzereingaben, die bspw. ein " enthalten, dann " herauskommt - dann ist die Applikation an sich kaputt, weil sie Daten verfälscht.
                        (Sollte das nicht der Fall sein, und auch noch eine Datenbank im Spiel sein - dann wird durch dieses Feature automatisch abgefangen, dass auch dort die Berücksichtigung des Kontextwechsels versäumt wurde.)

                        Nimm dir dazu die Livehttpheaders-Extension und den FF oder ein ähnlich arbeitendes Tool für deinen Browser.

                        hast du einen tipp für mich, ich habe firefox 3.0.6 installiert, und da geht die extension nicht.

                        FireBug kann dir u.a. auch den HTTP-Verkehr zwischen Browser und Server anzeigen.

                        MfG ChrisB

                        --
                        Light travels faster than sound - that's why most people appear bright until you hear them speak.
                      2. Hi!

                        wie lege ich in der datei im header das charset fest? ich habe überall nur hinweise auf die meta-angabe gefunden, und diverse web-editoren machen das meines wissens nach auch so. ist das also wirklich notwendig? weim w3c hab ich auch nur die meta-variante gefunden. ein link wäre hier sehr hilfreich;-)

                        Wenn du HTML als Inhalt hast, dann kann der Browser ja die Meta-Angabe lesen. Bei der 302er Weiterleitung hast du keinen Inhalt und kein Meta-Element. Da bleibt nur der Header. Allerdings habe ich da noch keine Erfahrung gesammelt / Messreihe gestartet, wie sich diese Angabe auf die Interpretation der Weiterleitungs-URL auswirkt.

                        ich habe jetzt in der url-weiterleitung urlencode() eingefügt. jetzt zeigt auch der safari die umlaute richtig an... passt das so, was die url-weitergabe betrifft??

                        urlencode() geht von ISO-8859-1 aus, wobei ankommendes UTF-8 byteweise als einzelne Zeichen gelesen und behandelt werden. Ob es so passt? ... Wie sieht das Ergebnis aus? Sind es zwei kodierte Bytes pro Umlaut oder nur eins?

                        ok, das ist wohl ein eigenes kapitel, das jetzt nicht unbedingt mit dem umlaut-problem zusammenhängt, oder? ich habe nämlich ein sehr umfangreiches projekt daran hängen, das eigentlich bis auf die umlaute sehr gut funktioniert, und ich möchte da jetzt kein risiko eingehen, bzw. hab ich auch nicht die zeit, zig dateien umzuschreiben. ich heb mir das lieber fürs nächste projekt auf. oder glaubst du, spielt das doch eine rolle bei der umlaut-problematik?

                        Wenn du das nicht korrigierst, hast du das Risiko der Datenverfälschung bereits eingebaut. Eventuell hast du auch noch ein weiteres Sicherheitsproblem, je nachdem, wo die Daten herkommen. Magic Quotes wirken nur $_GET, $_POST und $_COOKIE. Wenn du anderswo Daten herbekommst und dem DBMS übergibst, hast du keine Vorkehrung gegen SQL-Injection getroffen. Auf alle Fälle hast du XSS-Injection-Lücken (unbehandeltes Einfügen in den HTML-Kontext), zumindest in den gezeigten Codeausschnitten. Und nein, die Umlaute-Problematik betrifft das Thema nicht, die Auswirkungen können aber gravierender sein als ein paar kaputte Umlaute.

                        hast du einen tipp für mich, ich habe firefox 3.0.6 installiert, und da geht die extension nicht. ausserdem hab ich safari 3.2.1 zur verfügung (ich bin nicht auf meinem heim-pc...)

                        Diese Extension (Version 0.15) soll von Firefox 0.8 bis 3.5 gehen. In der 3.0-Reihe ist außerdem 3.0.13 aktuell. Für den Safari müsstest du mal suchen gehen, ob es da was gibt. Auf alle Fälle gibt es Webangebote, die eine angegebene URL besuchen und die Header anzeigen. (Und Ethernet-Sniffer, was aber mit Kanonen auf Spatzen geschossen ist.)

                        Wenn du das Problem nicht lösen kannst, so solltest du nun ein paar neue Beobachtungen gemacht haben, aus denen man vielleicht weitere Schlüsse ziehen kann.
                        wie gesagt, safari gibt die umlaute jetzt richtig aus, nachdem ich urlencode() eingefügt habe...

                        Das was du als richtig ansiehst, könnte nur so scheinen. Wie sieht es also genau aus? (Hab ich ja oben schon gefragt.)

                        Lo!