hawkmaster: Umstellung auf UTF8 gelungen?

0 63

Umstellung auf UTF8 gelungen?

hawkmaster
  • datenbank
  1. 0
    hotti
    1. 0
      hawkmaster
      1. 0
        Tom
        1. 0
          hawkmaster
          1. 0
            Tom
            1. 0
              hawkmaster
              1. 0
                Tom
                1. 0
                  hawkmaster
                  1. 0
                    dedlfix
                    1. 0
                      hawkmaster
                      1. 0
                        dedlfix
                        1. 0
                          hawkmaster
                          1. 0
                            dedlfix
                            1. 0

                              Aus ü wird ü ??

                              hawkmaster
                              1. 0
                                dedlfix
                                1. 0
                                  hawkmaster
                                  1. 0
                                    dedlfix
                                    1. 0
                                      hawkmaster
                                      1. 0
                                        dedlfix
                                        1. 0

                                          vielleicht auch nur ein Bug?

                                          hawkmaster
                                          1. 0
                                            Sven Rautenberg
                                            1. 0
                                              hawkmaster
                                              1. 0
                                                Sven Rautenberg
                                          2. 0
                                            dedlfix
                                      2. 0
                                        Tom
                                        1. 0
                                          hawkmaster
                                          1. 0
                                            Tom
                                        2. 0
                                          Sven Rautenberg
                                    2. 0
                                      Tom
                                      1. 0
                                        dedlfix
                                    3. 0
                                      hawkmaster
                                      1. 0
                                        Tom
                                        1. 0

                                          UTF8 erkennen, mb_internal_encoding() ?

                                          hawkmaster
                                          1. 1

                                            Zugriff über den Index-Operator auf einen UTF-8-String?

                                            Tom
                                            1. 0
                                              Sven Rautenberg
                                              1. 0
                                                hawkmaster
                                                1. 2
                                                  Sven Rautenberg
                                                  1. 0
                                                    Christian Kruse
                                              2. 0
                                                Tom
                                      2. 0
                                        Sven Rautenberg
                            2. 0
                              Tom
                              1. 0
                                dedlfix
                                1. 0

                                  TOM und ТОМ

                                  Tom
                                  • menschelei
                              2. 0
                                Der Martin
                                1. 0
                                  at
                  2. 0
                    Tom
                    1. 0
                      hawkmaster
          2. 0
            hotti
  2. 0
    Harlequin
    1. 0
      hawkmaster
      1. 0
        Harlequin
    2. 0
      Tom
      1. 0
        Harlequin
        1. 0
          Tom
  3. 0
    Tom
    1. 0
      hawkmaster
      1. 0
        Tom
        1. 0
          hawkmaster
          1. 0
            Tom
  4. 0

    str_pad() multibyte?

    hawkmaster
    1. 0
      Tom
    2. 0
      Sven Rautenberg

Hallo zusammen,

ich habe heute meine WebAnwendung mit PHP und die Datenbank MySQL von latin1 auf UTF8 umgestellt.
Folgendes wurde gemacht.

in der my.ini des MySQL Servers:
default-character-set = utf8
character-set-server = utf8
collation-server= utf8_general_ci
init_connect = SET NAMES utf8

In der httpd.conf des Apache:
AddDefaultCharset utf-8

In allen PHP Seiten:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

in der php.ini:
default_charset = "UTF-8"

Dann einen SQL Dump mit PHPMyAdmin der gesamten DB.
Mit Editor geöffnet und alle Stellen
DEFAULT CHARSET=latin1 mit DEFAULT CHARSET=utf8 ersetzt.
Import mit PhpMyAdmin in Einstellung utf8

Apache und MySQL neu gestartet.
Auf den ersten Blick scheinen alle Sonderzeichen und Umlaute korrekt dargestellt zu werden.
ABER:
eine Tabelle "webuser" hatte in der Spalte Pword verschlüsselte Passwörter abgelegt, die ganz "wilde" Sonderzeichen enthielten (z.b. Å¡EfJk­Ž4ý²)

Wenn sich nun ein User einloggen will, klappt dies nicht mehr. Offensichtlich stimmt das Passwort nicht mehr überein.
Es wäre nun nicht so schlimm, die User neu anzulegen weil es nur ganz wenig sind.
Mich würde aber interessieren warum dies mit der Umwandlung nicht geklappt hat?

vielen Dank und viele Grüße
hawk

  1. hi,

    entscheidend bei Stringvergleichen in MySQL ist die Collation. In dieser Hinsicht muss es eine Übereinstimmung geben zwischen der Zeichenkodierung von Benutzereingaben und der entsprechenden Spalte.

    Beispiel:
    Benutzereingabe: "ü"
    charset(Browser): = utf-8
    Abfrage auf Tabelle mit "User like '%ü%'" gibt "Münz" aus, sofern der drinsteht und die Spalte User die collation utf-8 hat.

    Hotte

    1. Hi Hotte,
      danke für deine Hilfe,

      entscheidend bei Stringvergleichen in MySQL ist die Collation. In dieser Hinsicht muss es eine Übereinstimmung geben zwischen der Zeichenkodierung von Benutzereingaben und der entsprechenden Spalte.

      Also wenn ich mich einloggen will steht die Browsercodierung auf utf8
      Und in der BD ist die Collation utf8_general_ci.

      Ich habe jetzt ein zusätzliches Problem.
      Wenn ein neuer User angelegt wird, wird das Passwort mit der Funktion
      AES_ENCRYPT(:pwd,@pswd_key)
      abgelegt.

      Doch dies klappt jetzt nach der Umstellung auf UTF8 leider auch nicht mehr. Speichere ich z.b. das Passwort "hallo" bleibt die Spalte leer, speichere ich das Passwort "Testuser" steht nur eine 9 drin.

      Verstehe ich wirklich nicht. Mit latin1 hatte alles wunderbar funktioniert.

      vielen Dank und viele Grüße
      hawk

      1. Hello,

        Ich habe jetzt ein zusätzliches Problem.

        Und was passiert von der Eingabe im Browser bis zur Verwandlung in ein verschlüsseltes Passwort mit dem Datenwert?

        Außerdem sollten Passwörter mMn in der Tabelle im Collation-Type binary gespeichert werden und keinesfalls CaseInsensitive.

        Liebe Grüße aus dem schönen Oberharz

        Tom vom Berg

        --
        Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
        1. Hallo Tom,

          ich habe jetzt nochmals in der MySQL doku nachgeschaut wgen AES_Encrypt:

          AES_ENCRYPT() encrypts a string and returns a binary string.

          Note

          The encryption and compression functions return binary strings. For many of these functions, the result might contain arbitrary byte values. If you want to store these results, use a column with a VARBINARY or BLOB binary string data type.

          Das wird vermutlich das Problem sein.

          Es wäre vermutlich das beste wenn ich die Passwortspalte als BLOB definiere?

          vielen Dank und viele Grüße
          hawk

          1. Hello,

            Es wäre vermutlich das beste wenn ich die Passwortspalte als BLOB definiere?

            Wie lang sollen denn die Passwörter werden?
            BLOB ist da wohl eher überskaliert ;-)

            Wenn Du den Spaltentyp umgestellt hast, ist ein Problem beseitigt.

            Liebe Grüße aus dem schönen Oberharz

            Tom vom Berg

            --
            Nur selber lernen macht schlau
            http://bergpost.annerschbarrich.de
            1. Hallo Tom,

              Wie lang sollen denn die Passwörter werden?
              BLOB ist da wohl eher überskaliert ;-)

              hm, ich weiss ja nicht was die User für Passwörter verwenden. Es wird eine kleine Intranet Anwendung. Ich könnte natürlich die Passwörter auf max. 10 Zeichen begrenzen.

              Welchen Datentyp würdest du dann empfehlen?

              Wenn Du den Spaltentyp umgestellt hast, ist ein Problem beseitigt.

              Was meinst du damit?
              Das es noch andere Probleme geben kann?

              vielen Dank und viele Grüße
              hawk

              1. Hello,

                Wie lang sollen denn die Passwörter werden?
                BLOB ist da wohl eher überskaliert ;-)

                hm, ich weiss ja nicht was die User für Passwörter verwenden. Es wird eine kleine Intranet Anwendung. Ich könnte natürlich die Passwörter auf max. 10 Zeichen begrenzen.

                Welchen Datentyp würdest du dann empfehlen?

                Wenn Du den Spaltentyp umgestellt hast, ist ein Problem beseitigt.

                Deutsch:  http://dev.mysql.com/doc/refman/5.1/de/binary-varbinary.html
                Englisch: http://dev.mysql.com/doc/refman/5.1/en/binary-varbinary.html

                http://dev.mysql.com/doc/refman/5.1/en/string-type-overview.html

                sagt aus, dass char 256 Zeichen lang werden darf (0 .. 255)
                und das binaray ein Spezialtyp davon ist.

                Also solltest Du doch mit dem Typ BINARY gut auskommen.

                Allerdings solltest Du Dir vielleicht nochmal durchlesen, was da in der Beschreibung über "leading and trailing spaces" oder so ähnlich steht.

                Liebe Grüße aus dem schönen Oberharz

                Tom vom Berg

                --
                Nur selber lernen macht schlau
                http://bergpost.annerschbarrich.de
                1. Hallo Tom,

                  jetzt habe ich nochmals weiter geforscht.
                  Stelle ich die Spalte PWD auf "varbinary" und Collation "binary" um und lege dann einen neuen User an, klappt hinterher das Login auch nicht.

                  Mache ich hingegen die Spalte als "varchar" mit Collation "latin1_generali_ci" klappt es wieder mit dem Passwort.

                  Also ich verstehe das jetzt nicht mehr so ganz..
                  Dann ist eigentlich eher die Kollation als der Typ wichtig?

                  vielen Dank und viele Grüße
                  hawk

                  1. Hi!

                    Stelle ich die Spalte PWD auf "varbinary" und Collation "binary" um und lege dann einen neuen User an, klappt hinterher das Login auch nicht.
                    Mache ich hingegen die Spalte als "varchar" mit Collation "latin1_generali_ci" klappt es wieder mit dem Passwort.

                    Zeig doch bitte mal mit dem geringsmöglichen Code, was du genau machst, damit man das mal 1:1 nachvollziehen kann.

                    Lo!

                    1. Hallo dedlfix,
                      danke für deine Hilfe
                      (du hast ja eine neue Begrüßung und Verabschiedung :-)) )

                      OK folgender Code:
                      In $_POST['pass'] steht das Passwort das der User eingibt. (Seite ist in UTF8)

                      Das Prepared Statement:
                      $dbInsertUserNew = $DBO->prepare("INSERT INTO webuser (usr,pwd,AddressField1,LanguagesID) VALUES (:user,AES_ENCRYPT(:pwd,@pswd_key),:address1,:languagesid)");

                      Bei einem Submit in der Seite "newuser.php":
                      $dbInsertUserNew->bindParam(':user', $_POST['login']);
                      $dbInsertUserNew->bindParam(':pwd', $_POST['pass']);
                      ..
                      $dbInsertUserNew->execute();

                      Nun steht das Passwort verschlüsselt in der DB Tabelle.
                      Bei einem anschließenden Login mit den neuen Userdaten mache ich für das Passwort wieder einen Select mit
                      $dboSelectUser = $DBO->prepare("SELECT count(*) as usercount, usr, UserID FROM webuser WHERE usr = :usr AND pwd = AES_ENCRYPT(:pwd,@pswd_key) ..

                      Wie gesagt. Angeblich soll man ja mit AES_ENCRYPT den Typ VARBINARY or BLOB nehmen.
                      Aber das klappt bei mir nicht.

                      vielen Dank und viele Grüße
                      hawk

                      1. Hi!

                        Wie gesagt. Angeblich soll man ja mit AES_ENCRYPT den Typ VARBINARY or BLOB nehmen.

                        Ich habe mit dem phpMyAdmin und dem AES_ENCRYPT etwas experimentiert. Auf der Startseite ist als "connection collation" utf8_... gewählt, Zeichen werden also UTF8-kodiert, die Kollation spielt erstmal keine Rolle.

                        SELECT  
                        AES_ENCRYPT('föo','bar'),  
                        AES_ENCRYPT(CONVERT('föo' USING latin1),'bar')
                        

                        Das ergibt unterschiedliche Werte. AES_ENCRYPT() arbeitet also byteorientiert. Unicode-Codepoint-orientiert zu arbeiten ergibt keinen richtigen Sinn, denn diese Codepoints sind abstrakte Zahlen, die keine konkreten, für den Rechner nutzbaren Werte darstellen. Sie müssten dazu in eine konkrete Form gebracht werden, wie beispielsweise UTF-16 oder UTF-8. In diese Form müssten dann aber alle anders kodierten Werte gebracht werden, um vergleichbare Ergebnisse zu erzielen, wenn man mit den Zeichen an sich und nicht ihrer konkreten, irgendwie kodierten Form arbeiten wollte.

                        Wie auch immer, die Bytewerte interessieren. Und wenn du bei anscheinend gleichen Rechenschritten unterschiedliche Ergebnisse bekommst, so liegt dir Vermutung nahe, dass du mit unterschiedlichen Kodierungen arbeitest.

                        Überprüfen könntest du das, indem du mal das SELECT wegkommentierst und stattdessen ein INSERT ausführst (mit gleichem Passwort aber mit anderem Benutzernamen, denn da wird sicher ein unique key draufliegen). Die Werte für beide Benutzer kannst du anschließend zum Beispiel im PMA vergleichen. Sie sollten übereinstimmen, was sie aber vermutlich nicht tun werden.

                        Als nächstes könntest du das AES_ENCRYPT() an beiden Stellen (beim normalen INSERT und beim testweisen) entfernen und mal Klartext-Passwörter speichern. Dann solltest du deutlicher sehen, was aus den Werten wird, wenn du dir das Ergebnis im PMA anschaust.

                        Auf alle Fälle solltest du VARBINARY als Feldtyp verwenden und eine ausreichende Feldgröße wählen. Die Doku zu AES_ENCRYPT spricht von
                          16 × (trunc(string_length / 16) + 1)
                        wobei du beachten musst, dass 1 Zeichen UTF-8-kodiert bis zu 4 Byte lang werden kann.

                        Lo!

                        1. Hallo dedlfix,

                          herzlichen Dank für deine Hilfe,

                          Ich lasse es nun mal auf varbinary und mache einige tests.

                          Mir ist eben noch etwas aufgefallen.
                          Ich hatte bei meinen Tests einmal einen Loginnamen (wegen den Umlauten):
                          Hansjörg
                          und dann einen
                          Hänsjörg

                          verwendet.
                          Beim Versuch "Hänsjörg" zu speichern, kam eine Fehlermeldung das dieser Loginname schon vorhanden ist. (Spalte "loginname" ist Unique)

                          Die Collation der Spalte ist nach der Umstellung auf UTF8 nun utf8_general_ci

                          Laut Manual (ja ich habe mich gebessert :-)) )

                          http://dev.mysql.com/doc/refman/5.1/en/charset-unicode-sets.html

                          wird bei dieser Collation das A mit Ä gleichgesetzt.
                          Auch bei den Beispielen;

                          http://dev.mysql.com/doc/refman/5.1/en/charset-collation-effect.html

                          sieht man diesen effekt. Wohl auch für das deutsche ß = s

                          Jetzt frage ich mich: Welche Collation wäre dann angebracht damit wirklich zwischen a und ä unterschieden wird?
                          Eigentlich müßte man doch vermutlich auf "latin1_german2_ci" einstellen.

                          Wie wirkt sich das aber aus wenn das System z.b. mit französischen Namen und Sonderzeichen arbeiten muss?

                          Puhh, das mit den zeichensätzen und Collationen ist garnicht so einfach.
                          vielen Dank und viele Grüße
                          hawk

                          1. Hi!

                            Jetzt frage ich mich: Welche Collation wäre dann angebracht damit wirklich zwischen a und ä unterschieden wird?
                            Eigentlich müßte man doch vermutlich auf "latin1_german2_ci" einstellen.

                            Nein, du willst UTF8 haben, also ist alles was nicht mit utf8_ anfängt unbrauchbar. Es gibt kein spezielles german für utf8, weil dessen Regeln in utf8_general und utf8_unicode enthalten sind. Wenn du keine sprachspezifischen Vergleichsregeln haben möchtest, nimm *_bin, also utf8_bin. Damit weiß das MySQL, dass die Daten als UTF8 zu interpretieren sind, aber beim Vergleichen keine speziellen Regeln zu verwenden sind. Dann ist aber auch a <> A und nicht nur a <> ä.

                            Wie wirkt sich das aber aus wenn das System z.b. mit französischen Namen und Sonderzeichen arbeiten muss?

                            utf8_bin wäre sprachunspezifisch, ansonsten sind die französischen Regeln mit in utf8_general/utf8_unicode enthalten.

                            Lo!

                            1. Hallo dedlfix,

                              ich versuche es nun mal mit utf8_bin.
                              Vielen Dank für die Erklärung.

                              Tut mir leid, aber ich habe nun schon die ersten Probleme nach der Umstellung.
                              Eigentlich ist es blos ein "copy" Befehl also nicht mal eine besondere String Funktion.
                              Und zwar steht in einer Tabelle ein Verzeichnispfad drin. z.b.
                              C:\Programme\WebAnwendung\München

                              Ich habe eine Funktion die mir den Verzeichnispfad holt.
                              $get_dir = get_DirectoriesPath($dir_ID);
                              copy("$userupload/$new_prn_name", "$get_dir/$new_prn_name")

                              In der Funktion "get_DirectoriesPath" ist eigentlich nur ein ganz normaler Select drin der mit den Pfad zurückgibt.

                              zum debuggen habe ich mal den Pfad in eine textdatei geschrieben. Und siehe da. Hier steht dann
                              C:\Programme\WebAnwendung\München

                              also wurde aus ü ein ü was im Hexeditor ein C3BC ist.

                              Ich verstehe leider nicht so recht die Zusammenhänge bzw. warum das jetzt passiert?
                              Alle Seiten und Scripte laufen doch auch UTF8

                              Hast du eine Idee?

                              vielen Dank und viele Grüße
                              hawk

                              1. Hi!

                                Tut mir leid, aber ich habe nun schon die ersten Probleme nach der Umstellung.

                                Das muss dir nicht leid tun. Probleme deuten darauf hin, dass nicht alle beteiligten Systeme so mitarbeiten, wie sie sollen.

                                Eigentlich ist es blos ein "copy" Befehl also nicht mal eine besondere String Funktion.
                                Und zwar steht in einer Tabelle ein Verzeichnispfad drin. z.b.
                                C:\Programme\WebAnwendung\München

                                Da hast du ein Dateisystem, und darauf hast du wenig Einfluss. Am schmerzärmsten wäre, dort auf Nicht-ASCII-Zeichen zu verzichten. Ansonsten sind erst einige Untersuchungen fällig, um herauszubekommen, was bei der Interaktion zwischen dir und dem Dateisystem für Ergebnisse herauskommen. Fragen die geklärt werden müssen, wäre beispielsweise:

                                • Von PHP aus Datei mit Umlaut im Namen anlegen - Was kommt im Dateisystem an? (dir/ls/Explorer/...)
                                • Im Dateisystem Datei mit Umlaut im Namen anlegen - Was sieht PHP? (glob/scandir/opendir/...)

                                zum debuggen habe ich mal den Pfad in eine textdatei geschrieben. Und siehe da. Hier steht dann
                                C:\Programme\WebAnwendung\München

                                Das heißt, du hast UTF-8-kodierte Daten, schaust sie dir aber als ISO-8859-1 interpretiert an. Wenn du deinen Texteditor anweist, die Datei als UTF-8 zu lesen, siehst du wieder das ü. Das ist also alles richtig so.

                                Lo!

                                1. Hallo dedlfix,

                                  also irgendwie werde ich nicht schlau aus dem ganzen.
                                  Folgendes habe ich getestet:

                                  1. aus PHP heraus eine Datei "täßt.txt" angelegt. Diese ist im Dateisystem dann auch als "täßt.txt" sichbar bzw. wird genauso angelegt.
                                  Ich kann diese dann auch wieder beschreiben mit dem gleichen Namen.

                                    
                                  $test_file = "täßt.txt";  
                                  $fp = fopen($test_file, "w");  
                                  fwrite($fp, $test_dir);  
                                  fclose($fp);  
                                  
                                  

                                  2. Eine PHP Seite mit einem Textfeld. Hier wird der Name Rüdesheim eingegeben. Ein Submit legt das verzeichnis auf Dateiebene an.

                                    
                                  $new_path = $old_path . "\\" . $_POST['txt_newsubdir'];  
                                  if(!is_dir($new_path) ){  
                                  mkdir($new_path);  
                                  }  
                                  
                                  

                                  Nun gibt es im Verzeichnis das Verzeichnis aber nicht mit ü sondern;
                                  Rüdesheim
                                  Ein "copy" Versuch wie im Ausgangsproblem geschildert bringt dann auch keinen Fehler mehr.

                                  3. In der Tabelle "directories" sind die Verzeichnispfade ja mit Umlauten drin. z.b.
                                  C:\Programme\WebAnwendung\München

                                  sowohl in PhpMyAdmin als auch QueryBrowser, oder andere SQL Browser zeigen die Umlaute als Ü, ä oder ö an.
                                  Auch ein Dump bzw. Export in eine sql Datei und anschauen mit Texteditor zeigt mir die Umlaute als Ü Ö Ä an.
                                  Liegt nun das Ü in der Datenbank als Ü vor oder als Hex C3BC oder als ü vor und die Betrachter zeigen es nur als Ü an?

                                  So, jetzt weiss ich ehrlich gesagt nicht so recht was ich ändern muss / soll.
                                  Müssen alle Umlaute wie Ä, Ü und Ö z.b. als a&uml; also umgewandelt in der DB gespeichert werden?
                                  Das wäre ja dann ein großer Aufwand wenn man alle Tabellen und Spalten ändern müßte.

                                  Es macht ja auch wenig Sinn wenn ein Verzeichnis als "Rüdesheim" angelegt wird.

                                  Vielleicht kannst du mir ein paar Tipps geben.

                                  vielen Dank und viele Grüße
                                  hawk

                                  1. Hi!

                                    1. aus PHP heraus eine Datei "täßt.txt" angelegt. Diese ist im Dateisystem dann auch als "täßt.txt" sichbar bzw. wird genauso angelegt.

                                    In welcher Kodierung ist das PHP-Script gespeichert?

                                    1. Eine PHP Seite mit einem Textfeld. Hier wird der Name Rüdesheim eingegeben. Ein Submit legt das verzeichnis auf Dateiebene an.
                                      Nun gibt es im Verzeichnis das Verzeichnis aber nicht mit ü sondern;
                                      Rüdesheim

                                    Das deutet darauf hin, dass das PHP-Script als ISO-8859-1 (oder Windows-1252) kodiert ist. Die Daten vom Browser kommen UTF-8-kodiert und werden vom PHP-Script nur durchgereicht. Als Schlussfolgerung will also auch das Dateisystem in ISO-8859-1/Windows-1252 angesprochen werden.

                                    Das heißt also, dass du von und zum Dateisystem UTF-8-kodieren und -dekodieren musst, wenn du da ordentliche Umlaute sehen möchtest. Das ist theoretisch verlustbehaftet, zumindest in Richtung ISO-8859-1. Doch praktisch wird das nicht weiter stören, weil du vermutlich nur Zeichen aus ISO-8859-1 verwenden wirst.

                                    sowohl in PhpMyAdmin als auch QueryBrowser, oder andere SQL Browser zeigen die Umlaute als Ü, ä oder ö an.
                                    Auch ein Dump bzw. Export in eine sql Datei und anschauen mit Texteditor zeigt mir die Umlaute als Ü Ö Ä an.
                                    Liegt nun das Ü in der Datenbank als Ü vor oder als Hex C3BC oder als ü vor und die Betrachter zeigen es nur als Ü an?

                                    Wie etwas in der Datenbank liegt ist aus der Sicht von Anwendungen irrelevant. Das ist eine Blackbox, die allein über die SQL-Statements angesprochen wird. Wichtig ist nur, welche Kodierung beim Kommunizieren gesprochen wird.

                                    Der PMA und die anderen werden sich die Kodierung passend ausgehandelt haben und geben das ihrerseits passend (kodiert und deklariert) ans Ausgabemedium weiter. Bei den Export-Tools kannst du angeben, welche Kodierung zu verwenden ist. Das sollte man auch explizit tun, sonst bekommt man die Daten in irgendeiner Default-Kodierung. Gegebenenfalls kodiert MySQL zwischen der Feldkodierung und der Export-Kodierung (manchmal prinzipbedingt verlustbehaftet) um.

                                    So, jetzt weiss ich ehrlich gesagt nicht so recht was ich ändern muss / soll.
                                    Müssen alle Umlaute wie Ä, Ü und Ö z.b. als a&uml; also umgewandelt in der DB gespeichert werden?

                                    Nein, keinesfalls. Von und zum DBMS hast du ja kein Problem, da sprichst du ordentliches UTF-8. Dein Problemfeld ist momentan nur die Kommunikation mit dem Dateisystem.

                                    Lo!

                                    1. Hi dedlfix,
                                      vielen Dank für deine Geduld.
                                      (Ich schreibe gerne auch mal ein kleines Tutorial bzw. Info was alles zu beachten ist bei der Umstellung von latin1 bzw. ISo zu utf8)

                                      In welcher Kodierung ist das PHP-Script gespeichert?

                                      Sollte alles utf8 sein. Siehe weiter unten.

                                      Das deutet darauf hin, dass das PHP-Script als ISO-8859-1 (oder Windows-1252) kodiert ist. Die Daten vom Browser kommen UTF-8-kodiert und werden vom PHP-Script nur durchgereicht. Als Schlussfolgerung will also auch das Dateisystem in ISO-8859-1/Windows-1252 angesprochen werden.

                                      Folgende Umstellung habe ich gemacht:

                                      in der my.ini des MySQL Servers:
                                      default-character-set = utf8
                                      character-set-server = utf8
                                      collation-server= utf8_general_ci
                                      init_connect = SET NAMES utf8

                                      In der httpd.conf des Apache:
                                      AddDefaultCharset utf-8

                                      In allen PHP Seiten:
                                      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

                                      in der php.ini:
                                      default_charset = "UTF-8"

                                      Damit müssten doch alle PHP Dateien und die Connection mit UTF8 laufen oder?

                                      Das heißt also, dass du von und zum Dateisystem UTF-8-kodieren und -dekodieren musst, wenn du da ordentliche Umlaute sehen möchtest.

                                      du meinst ich müsste dann bei allen Aktionen die das Dateisystem betreffen mit "utf8_encode" und "utf8_decode" arbeiten?

                                      Nein, keinesfalls. Von und zum DBMS hast du ja kein Problem, da sprichst du ordentliches UTF-8. Dein Problemfeld ist momentan nur die Kommunikation mit dem Dateisystem.

                                      Dann bin ich ja etwas beruhigt. :-)

                                      vielen Dank und viele Grüße
                                      hawk

                                      1. Hi!

                                        In welcher Kodierung ist das PHP-Script gespeichert?
                                        Sollte alles utf8 sein. Siehe weiter unten.

                                        In der httpd.conf des Apache:
                                        AddDefaultCharset utf-8

                                        Das ist das, was der Apache dem Browser erzählt, was der bekommt.

                                        In allen PHP Seiten:
                                        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

                                        Das im Prinzip auch.

                                        in der php.ini:
                                        default_charset = "UTF-8"

                                        Das brauchst du nicht, weil du schon über den Apachen mit AddDefaultCharset eine charset-Angabe im Content-Type-Header unterbringst. PHP macht damit das gleiche. Aber wie auch immer ...

                                        Damit müssten doch alle PHP Dateien und die Connection mit UTF8 laufen oder?

                                        ... alle Optionen beschreiben nur gegenüber dem Browser was er bekommt. Ich meinte, deine PHP-Dateien als solche, in die du mit einem Editor deinen PHP-Code schreibst. Die, scheint mir, speicherst du nicht ISO-8859-1-kodiert ab. Dateisystemoperationen nur mit PHP-COde gelingen damit problemlos, weil das Dateisystem auch nur ISO spricht. Aber UTF-8-kodierte, anderswoher kommende, durchgereichte Daten machen ein Problem.

                                        Das heißt also, dass du von und zum Dateisystem UTF-8-kodieren und -dekodieren musst, wenn du da ordentliche Umlaute sehen möchtest.
                                        du meinst ich müsste dann bei allen Aktionen die das Dateisystem betreffen mit "utf8_encode" und "utf8_decode" arbeiten?

                                        Ja, oder alternativ das Dateisystem umstellen ... doch das wird ein zu tiefer Eingriff ins Gesamtsystem sein.

                                        Lo!

                                        1. Hi dedlfix,

                                          ich bin gerade dauernd in Manuals und Webseiten unterwegs die ähnliche Probleme hatten nach der Umstellung.

                                          Hier ist mir zufällig ein Bug Report von PHP aufgefallen.

                                          http://bugs.php.net/bug.php?id=46990

                                          Könnte das auch mit meinem Problem zusammenhängen?

                                          vielen Dank und viele Grüße
                                          hawk

                                          1. Moin!

                                            ich bin gerade dauernd in Manuals und Webseiten unterwegs die ähnliche Probleme hatten nach der Umstellung.

                                            Hier ist mir zufällig ein Bug Report von PHP aufgefallen.

                                            http://bugs.php.net/bug.php?id=46990

                                            Könnte das auch mit meinem Problem zusammenhängen?

                                            Ja, das ist exakt dein Problem.

                                            PHP hat keinen Mechanismus, einem String in einer Variable auch noch ein Encoding zuzuordnen. Und es hat außerdem keinen Mechanismus, dem Dateinamen bei der Funktion fopen() über einen gesonderten Parameter ein Encoding zuzuordnen.

                                            Die Bytes, die im String als Dateiname drinstehen, werden einfach 1:1 durchgereicht ans Dateisystem, und das muss dann sehen, wie es damit fertig wird.

                                            Windows-Dateisysteme nutzen UCS-2 als Speicherformat für Dateinamen, aber es gibt einen Kompatibilitätslayer, der die Dateinamen in Windows-1252 überführt. PHP nutzt beim Dateizugriff diesen Layer. Es ist also derzeit unmöglich, mit PHP auf Windows korrekte Unicode-Dateinamen zu verwenden. Wie im Bugreport ausgeführt, wird das erst mit PHP 6 funktionieren.

                                            Klar, man könnte die relevanten Funktionen (also z.B. fopen()) auch alle um einen Encoding-Parameter erweitern - das wäre aber vermutlich viel aufwendiger und würde vielleicht auch künftigen Erweiterungen widersprechen, insbesondere steht es im Widerspruch zum beabsichtigten Unicode-Support in PHP 6, der solche Spielchen komplett überflüssig machen wird.

                                            Solange ausschließlich PHP den Dateizugriff realisiert, ist es hinsichtlich der Dateinamen übrigens egal, ob das Dateisystem UTF-8 kann, oder nur die String-Bytes unverändert speichert und wieder ausliest. Spannend wird es erst dann, wenn auch andere Zugriffe auf den Dateinamen erfolgen, z.B. vom Explorer, der Kommandozeile, oder dem Webserver. Dabei kann dann alles mögliche schiefgehen - deshalb sind Dateinamen mit etwas anderem als ASCII grundsätzlich eher böse.

                                            - Sven Rautenberg

                                            1. Hallo Sven,

                                              vielen Dank auch für deine tolle Erklärung.

                                              Also ich sehe schon. Ganz so trivial ist so eine UTF8 Umstellung nicht.

                                              Was würdest du denn aus deiner Erfahrung her, empfehlen?
                                              Sollte man Datei- und Verzeichnisnamen eher ohne Umlaute speichern oder ist das nicht mehr zeitgemäß?

                                              vielen Dank und viele Grüße
                                              hawk

                                              1. Moin!

                                                Also ich sehe schon. Ganz so trivial ist so eine UTF8 Umstellung nicht.

                                                Was würdest du denn aus deiner Erfahrung her, empfehlen?
                                                Sollte man Datei- und Verzeichnisnamen eher ohne Umlaute speichern oder ist das nicht mehr zeitgemäß?

                                                Die Behandlung von Dateinamen muss sowieso potentiell schädliche und verbotene Zeichen aus dem Namen entfernen. In diesem Schritt kann dann auch direkt die Umwandlung von allzu kreativen Unicode-Zeichen in etwas kompatibleres erfolgen.

                                                Das hat aber erstmal gar nichts mit UTF-8 zu tun, sondern muss unabhängig von der Kodierung erfolgen. Unicode bringt nur zusätzlich eine deutlich größere Anzahl an möglichen Zeichen mit.

                                                - Sven Rautenberg

                                          2. Hi!

                                            http://bugs.php.net/bug.php?id=46990
                                            Könnte das auch mit meinem Problem zusammenhängen?

                                            Ja, Sven hat's ja schon erklärt. PHP kleiner als 6 denkt immer noch ISO-8859-1/Windows-1252. Deshalb kann und wird es auch nur in dieser Kodierung mit anderen Systemen sprechen. Ausnahmen sind die Systeme, bei denen es einfach nur ohne "nachzudenken" die Daten durchreicht. Beim Dateisystem (zumindest unter Windows) muss es aber umrechnen. Und das geht in die Hose, wenn es andere Daten als ISO bekommt. Du wirst also nicht umhinkommen, für das Dateisystem ISO zu liefern, bis PHP 6 erschienen ist. (Datei_inhalte_ sind davon nicht betroffen!)

                                            Lo!

                                      2. Hello,

                                        (Ich schreibe gerne auch mal ein kleines Tutorial bzw. Info was alles zu beachten ist bei der Umstellung von latin1 bzw. ISo zu utf8)

                                        Noch bist Du ja erste am Anfang und beim Sichten der notwendigen Arbeitsschritte.
                                        Bekommst Du die noch alle zusammen?
                                        Ich habe nämlich den Verdacht, dass Deine Idee mit dem "kleinen Tutorial" recht gut in die Zeit passt. Ich steuere auf jeden Fall schon mal die Liste mit der Gegenüberstellung der byteorientierten Funktionen und den multibyteorientierten dazu. Daran sitze ich aber bestimmt auch noch ein Weilchen. Bisher haabe ich Auswirkungen gefunden bei

                                        • Stringfunktionen

                                        • PCRE-Funktionen

                                        • EREG-Funktionen

                                        • Bei Array-Funktionen gibt es mMn Auswirkungen auf die Sortierung
                                            da bin ich mir aber mit mir selbst noch nicht einig :-)

                                        Liebe Grüße aus dem schönen Oberharz

                                        Tom vom Berg

                                        --
                                        Nur selber lernen macht schlau
                                        http://bergpost.annerschbarrich.de
                                        1. Hallo Tom,

                                          Noch bist Du ja erste am Anfang und beim Sichten der notwendigen Arbeitsschritte.
                                          Bekommst Du die noch alle zusammen?

                                          Ja da hast du Recht. So langsam wird es schwierig.
                                          Ich habe mir schon im Vorfeld alles mögliche notiert und die ganzen Schritte für MySQL Server, PHP, Apache usw. mal notiert.
                                          Aber natürlich kommen immer wieder neue Dinge hinzu. So habe ich z.b. deinen Hinweis wegen den String Funktionen bzw. mb_string funktionen gerne aufgenommen und hatte ich vorher nicht bedacht.

                                          Von daher wäre es vielleicht schon gut wenn man hier vielleicht so ein kleines Tutorial erstellen könnte.

                                          vielen Dank und viele Grüße
                                          hawk

                                          1. Hello,

                                            Aber natürlich kommen immer wieder neue Dinge hinzu. So habe ich z.b. deinen Hinweis wegen den String Funktionen bzw. mb_string funktionen gerne aufgenommen und hatte ich vorher nicht bedacht.

                                            Von daher wäre es vielleicht schon gut wenn man hier vielleicht so ein kleines Tutorial erstellen könnte.

                                            Ich sehe da eine schöne Arbeitswelle auf uns zukommen. ;-)

                                            So nach und nach werden immer mehr Webserver von den Providern von ISO-8859-1 einfach beim Upgrade auf UTF-8 umgestellt. Es fängt also damit an, dass man den ganzen auf die Schnelle gestrickten Applikationen erstmal wieder erzählen muss, dass sie doch noch ISO sprechen sollen. Man kann das natürlich auch den Webservern erstellen, nur auf diese Einstellungen haben die Nutzer oft keinen Einfluss, weil AllowOverride FileInfo nicht eingeschaltet ist. Und Schwupps, fängst Du in den Apllikationen an zu stricken... Das ist dann teurer, als sich einen vernünftigen Provider zu suchen.

                                            Liebe Grüße aus dem schönen Oberharz

                                            Tom vom Berg

                                            --
                                            Nur selber lernen macht schlau
                                            http://bergpost.annerschbarrich.de
                                        2. Moin!

                                          • Stringfunktionen
                                          • PCRE-Funktionen
                                          • EREG-Funktionen

                                          EREG ist in PHP 5.3 offiziell deprecated und wird entfernt werden. Das betrifft allen ereg*-Zeugs, und auch split(). Nur so zur Info.

                                          - Sven Rautenberg

                                    2. Hello,

                                      Das deutet darauf hin, dass das PHP-Script als ISO-8859-1 (oder Windows-1252) kodiert ist. Die Daten vom Browser kommen UTF-8-kodiert und werden vom PHP-Script nur durchgereicht. Als Schlussfolgerung will also auch das Dateisystem in ISO-8859-1/Windows-1252 angesprochen werden.

                                      Ist es nicht eher so, dass das Dateisystem selber nur byteorientiert arbeitet?
                                      Wie aber die geholten "Byte-Strings" dann in der Shell dargestellt werden, ist die spannende Frage oder wie die Shell in ihr eingegebene Werte an ddas Filesystem weitergibt.

                                      Für durchgereichte Werte gilt wohl, dass die transparent, ohne jede Veränderung durchgereicht werden.

                                      Wenn also mittels "UTF-8-Shell" eine Datei erzeugt wird, passiert doch  das...

                                      Münchenstraße                                    Original in der UTF-8-Shell
                                        Münchenstraße                                  die macht daraus, wenn man es in ISO darstellt
                                                                                                                 die Bytewerte, die im
                                        4d | c3 bc | 6e | 63 | 68 | 65 | 6e | 73 | 74 | 72 | 61 | c3 9f | 65     Interrupt des
                                                                                                                 filesystems landen

                                      http://selfhtml.bitworks.de/utf8.php

                                      Dem Filesystem ist es also nahezu egal, welche Bytewerte es in seine Puffer geschrieben bekommt.

                                      Liebe Grüße aus dem schönen Oberharz

                                      Tom vom Berg

                                      --
                                      Nur selber lernen macht schlau
                                      http://bergpost.annerschbarrich.de
                                      1. Hi!

                                        Ist es nicht eher so, dass das Dateisystem selber nur byteorientiert arbeitet?

                                        Wie auch immer. Das Dateisystem ist jedenfalls eine Blackbox, bei der mich nicht interessiert, was sie intern macht. Hauptsache die Datei bleiben heil.

                                        Wie aber die geholten "Byte-Strings" dann in der Shell dargestellt werden, ist die spannende Frage oder wie die Shell in ihr eingegebene Werte an ddas Filesystem weitergibt.

                                        Das wird es sein. Die Shell interpretiert. Aber ebenso müssen alle anderen richtig interpretieren. Das System und alle Programme, die darauf laufen sollen, stellt man nicht einfach so mit Links um.

                                        Für durchgereichte Werte gilt wohl, dass die transparent, ohne jede Veränderung durchgereicht werden.

                                        Lo!

                                    3. Hallo nochmals,

                                      ich hoffe ich strapaziere diesen Thread nicht zu sehr.
                                      Ich will jedoch noch einiges testen um zu sehen wo es überall Probleme geben kann oder wo nach der Umstellung Probleme auftreten.

                                      »»... Dein Problemfeld ist momentan nur die Kommunikation mit dem Dateisystem.

                                      Wir hatten ja gestern festgestellt, dass alles was mit UTF8 Strings und dem Dateisystem zu tun hat, codiert werden muss.
                                      In der Tat hatte mehere Situationen, sei es bei der Prüfung mit
                                      "if(is_file($file)...
                                      oder
                                      mkdir
                                      oder copy usw. Probleme mit UTF8 Daten und dem Windows Dateisystem

                                      Wenn ich konsequent mit "utf8_decode" arbeite klappt es.
                                      z.b.
                                      $test_dir = utf8_decode($test_dir);

                                      Meine Überlegung ist nun:
                                      Wenn ich nun die ganze Webanwendung und die Datenbank auf UTF8 lasse und alle Dateisystemfunktionen anpasse ist alles ok.
                                      Wenn nun aber irgend jemand später mal sagt. "Wir machen wieder alles auf latin1" oder ISO-8859-1" würde man ja die "utf8_decode" Funktionen nicht brauchen.

                                      Wäre es nun gut, vorher zu prüfen ob ein String in UTF8 vorliegt (geht das überhaupt?) oder ob es codierte Zeichen enthält? Wenn ja, dann "utf8_decode" einsetzen.
                                      Oder wäre es egal, wenn "utf8_decode" eingesetzt wird auch wenn alles auf latin1 bzw. ISO-8859-1 ist?

                                      vielen Dank und viele Grüße
                                      hawk

                                      1. Hello,

                                        Wäre es nun gut, vorher zu prüfen ob ein String in UTF8 vorliegt (geht das überhaupt?) oder ob es codierte Zeichen enthält? Wenn ja, dann "utf8_decode" einsetzen.

                                        Das haben Cybaer und ich hier schon mehrfach diskutiert.
                                        http://forum.de.selfhtml.org/archiv/2006/3/t124786/#m804376

                                        Es ist im Prinzip nicht möglich zu erkennen, ob ein ISO-String oder ein UTF-8-String vorliegt, wenn man dem ISO-String keine Randbedingungen auferlegt. Wenn man den ISO-String auf "druckbare Zeichen" einschränkt, dann kann man zumindest ahnen, in welchen Fällen es sich nicht mehr um einen gültigen (nach diesen Regeln) ISO-String handelt. Dann kann man als nächstes prüfen, ob der String denn wenigstens dieselben Regeln als UTF-8-String erfüllen würde. Vorher könnte man mittels der  Funktionen von Cybaer noch testen, ob denn überhaupt ein gültiger UTF-8 String vorliegt.

                                        Je mehr randbedingungen bekannt sind (Sprache, nur druckbare Zeichen, ...), desto eher kannst Du eine sinnvolle Aussage treffen.

                                        Oder wäre es egal, wenn "utf8_decode" eingesetzt wird auch wenn alles auf latin1 bzw. ISO-8859-1 ist?

                                        ausprobieren! Du wirst sehen, dass es nur für Code(s|points) unterhalb 128 egal ist, weil dort die Definitonstabellen deckungsgleich sind.

                                        http://selfhtml.bitworks.de/utf8.php

                                        Liebe Grüße aus dem schönen Oberharz

                                        Tom vom Berg

                                        --
                                        Nur selber lernen macht schlau
                                        http://bergpost.annerschbarrich.de
                                        1. Hallo Tom,

                                          tja, das ist eigentlich schon ein interessantes Thema.
                                          Es ist nämlich auch so, das fast in allen Anleitungen und Tutorials die ich gefunden habe, immer nur die Umstellung von PHP (also Header UTF8), dann noch SET NAMES .., des MySQL Servers und vielleicht noch des Apache erwähnt werden.

                                          Die ganze Problematik wie ich sie nun erlebt habe, also mit Datei- und Verzeichniszugriffen wird fast nie erwähnt.
                                          Auch sehr wenig Hinweise gibt es, das es mit den "alten" String Funktionen Probleme geben kann.

                                          Ich denke wenn man weiss das das ganze System, also die Webanwendung mit Apache und PHP und auch MySQL auf UTF8 laufen und auch so bleiben, könnte man ja schon alles ändern und anpassen.
                                          Die Frage stellt sich mir: Könnte man es auch so hinbekommen, dass alles sowohl mit ISO bzw. latin1 läuft als auch UTF8?

                                          z.b. habe ich z.b. einige str_len Funktionen die die Länge eines Wortes das aus der DB kommt, ermittelt.

                                            
                                          //$len_filename = strlen($row['FileName']);//vorher  
                                          $len_filename = mb_strlen($row['FileName'], 'utf8');  
                                          
                                          

                                          Das habe ich jetzt geändert auf mb_strlen weil die Zeichenanzahl nicht mehr stimmte, wenn Umlaute drin waren.
                                          Jetzt weiss ich das die DB in UTF8 läuft. Was aber wenn jemand alles wieder auf ISO umstellt?
                                          Wie würdest du denn vorgehen?

                                          PS: echo "der zeichensatz ist " . mb_internal_encoding();
                                          bringt bei mir die Ausgabe:
                                          der zeichensatz ist ISO-8859-1
                                          aus was bezieht sich aber die Funktion? Auf den Zeichensatz des Betriebssystems? Alle meine Scripte laufen ja auf UTF8.
                                          Ich habe im Manual nichts dazu gefunden?

                                          ausprobieren! Du wirst sehen, dass es nur für Code(s|points) unterhalb 128 egal ist, weil dort die Definitonstabellen deckungsgleich sind.

                                          http://selfhtml.bitworks.de/utf8.php

                                          Ich werde es  mal ausprobieren und vielleicht mal alles wieder auf ISo umstellen, die UTF_decode und ms_string Funktionen drinlassen.

                                          vielen Dank und viele Grüße
                                          hawk

                                          1. Hello,

                                            es gibt noch viel mehr Fallen.

                                            als ich sagte, dass wir mit (der aumstellung auf) UTF-8 noch viel Freude[tm] haben werden, bin ich nur ausgelacht worden.

                                            als Beispiel nur einer von den kritischen Posts:
                                            http://forum.de.selfhtml.org/archiv/2007/12/t163961/#m1068067

                                            Ist denn inzwischen eine Lösung für den Index-Operator gefunden worden?

                                            Ein Zugriff per

                                            $zeichen = $string[$i];

                                            ist für multibyte-codierte Strings ja irgendwie nicht möglich?

                                            Liebe Grüße aus dem schönen Oberharz

                                            Tom vom Berg

                                            --
                                            Nur selber lernen macht schlau
                                            http://bergpost.annerschbarrich.de
                                            1. Moin!

                                              als ich sagte, dass wir mit (der aumstellung auf) UTF-8 noch viel Freude[tm] haben werden, bin ich nur ausgelacht worden.

                                              Eigentlich nicht.

                                              Ist denn inzwischen eine Lösung für den Index-Operator gefunden worden?

                                              Ein Zugriff per

                                              $zeichen = $string[$i];

                                              ist für multibyte-codierte Strings ja irgendwie nicht möglich?

                                              Doch, klar. Das liefert dir das BYTE an Position $i des Strings.

                                              Wenn du ZEICHEN haben willst, nimm mb_substr().

                                              - Sven Rautenberg

                                              1. Hallo Sven,

                                                Wenn du ZEICHEN haben willst, nimm mb_substr().

                                                und was macht man bei Funktionen für die es keine entsprechende multibyte Funktion gibt?
                                                Siehe mein Posting hier um 13.50 str_pad() multibyte?

                                                ich habe einige Beiträge von dir gelesen in denen es um UTF8 ging.
                                                Ich möchte dich als Experten mal gerne fragen, wie du bei einer Umstellung umgehen würdest oder umgegangen bist?
                                                Du schreibst das Forum und Blog sind UTF8.

                                                Ich bin jetzt ganz am Anfang meiner Umstellung. Im Grunde müsste man doch konsequent jede Zeile Code bzw. jede String Funktion und jede Funktion die mit dem Dateisystem zu tun hat, prüfen und gegebenfall ändern.

                                                Bin für jeden Tipp dankbar.

                                                vielen Dank und viele Grüße
                                                hawk

                                                1. Moin!

                                                  Wenn du ZEICHEN haben willst, nimm mb_substr().

                                                  und was macht man bei Funktionen für die es keine entsprechende multibyte Funktion gibt?
                                                  Siehe mein Posting hier um 13.50 str_pad() multibyte?

                                                  Da hast du eine Antwort. :)

                                                  ich habe einige Beiträge von dir gelesen in denen es um UTF8 ging.
                                                  Ich möchte dich als Experten mal gerne fragen, wie du bei einer Umstellung umgehen würdest oder umgegangen bist?

                                                  UTF-8 ist nach meiner Ansicht pflegeleichter, als es hier manchmal dargestellt wird. Das liegt zum einen daran, dass es tatsächlich vollständig bytekompatibel zu beispielsweise ISO-8859-1 ist, also keine merkwürdigen Bytes enthält, die vollkommen aus dem definierten Bereich von ISO-8859-1 herausfallen. Jedes System, was mit ISO-8859-1 grundsätzlich umgehen kann, kann auch mit UTF-8 umgehen.

                                                  Der Teufel steckt natürlich dann doch im Detail. Denn "umgehen" betrifft, wenn wir vom "Backend" sprechen, also alles, was nicht im Browser passiert, nur komplette Strings.

                                                  Ok, manche Dinge kriegt man auch ohne spezielle UTF-8-Berücksichtigung noch hin. Sortieren von Strings beispielsweise funktioniert mit ISO als auch UTF-8 prima, wenn dabei nur Bytes verglichen werden. Wenn man UTF-8 sortiert, wird eben anhand der Unicode-Codepoints aufsteigend sortiert, und der ganze Krams mit "äquivalente Zeichen", wie sie in den Sortierregeln von Sprachen vorkommen, bleiben komplett außen vor.

                                                  Außerdem profitiert man sicherlich davon, wenn eine zentrale Schaltstelle existiert, die als einzige mit den Speichersubsystemen spricht (also z.B. Datenbank oder Dateisystem). Denn da UTF-8-Strings vom Byteinhalt her auch gültiges ISO-8859-1 sind (wenngleich das nicht schön aussieht), funktionieren alle Subsysteme, die in der Lage sind, einen String entgegenzunehmen und unverändert wieder zurückzugeben.

                                                  Sprich: Es ist überhaupt kein Problem, wenn deine Dateifunktionen UTF-8-Strings als Dateinahmen verwenden, solange als einziges wieder nur dein PHP-Skript auf diese Dateinamen zugreifen will.

                                                  Problematisch wird's dann, wenn man gern möchte, dass das Subsystem von mehreren Stellen aus angezapft wird. Im Falle des Dateisystems will man also auch gerne den Explorer oder die Shell mit identischen Dateinamen beglücken. Im Falle einer Datenbank will man auch mit dem Admin-Tool korrekte Umlaute sehen, nicht nur mit dem Skript.

                                                  Und zu guter letzt: Irgendwann muss man mit den Strings auch mal mehr tun, als sie nur unverändert durchzureichen. :)

                                                  Du schreibst das Forum und Blog sind UTF8.

                                                  Richtig, aber beide Systeme nutzen bei den allermeisten Dingen kein PHP, sondern C.

                                                  Ich bin jetzt ganz am Anfang meiner Umstellung. Im Grunde müsste man doch konsequent jede Zeile Code bzw. jede String Funktion und jede Funktion die mit dem Dateisystem zu tun hat, prüfen und gegebenfall ändern.

                                                  Eine Umstellung von altem Code ist immer eine etwas schmerzhafte Angelegenheit. Es ist viel angenehmer, neuen Code direkt auf UTF-8 ausgerichtet zu schreiben - dummerweise ist das auch viel aufwendiger.

                                                  Du brauchst, wenn du mit Dateisystemen operierst, ja ohnehin eine Filterfunktion, um Zeichen zu behandeln, die sich für die Verwendung in Dateinamen nicht eignen. Und genau diese Funktion wird umgestellt von "kriegt ISO-8859-1 und macht einen Dateinamen draus" auf "kriegt UTF-8 ...". Das ist ein relativ kleiner Schritt.

                                                  PHP bietet übrigens an, die normalen Stringfunktionen (aber leider nicht alle, nur die, für die es mb_*-Ersatz gibt) direkt zu überladen, d.h. sie verhalten sich dann multibyte-kompatibel. Siehe http://de3.php.net/manual/en/mbstring.overload.php. Der einzige zusätzliche Schritt wäre dann, mb_internal_encoding('UTF-8'); aufzurufen, damit man das Encoding des verwendeten Strings nicht jedesmal manuell angeben muss.

                                                  Das Überladen der ereg-Funktionen ist übrigens nicht notwendig. Erstens ist ereg böse, zweitens seit 5.3.0 deprecated (fliegt also raus), und drittens sollte man ja sowieso preg-Funktionen verwenden, die schon lange auch einen Unicode-Modifier anbieten. Und außerdem auch einen passenden Such-Pattern für bestimmte Unicode-Zeichen-Eigenschaften: \p bzw. \P - damit kann man dann beispielsweise nach "Buchstaben" suchen, ohne alle Unicode-Buchstaben in einer Zeichenklasse auflisten zu müssen.

                                                  Ja, Unicode bzw. UTF-8 fällt nicht so ohne weiteres aus der Tüte, man muss an gewissen Stellen schon etwas mehr nachdenken und aufpassen. Andererseits erleichtert es grundsätzlich die Arbeit in so einem Maße, dass ich persönlich nicht drauf verzichten möchte. Deshalb halte ich es auch für extrem unrealistisch, dass irgendein UTF-8-fähiges System tatsächlich irgendwann nochmal zurück auf ISO-8859-1 getrimmt wird. Allein schon des fehlenden Eurozeichens wegen.

                                                  - Sven Rautenberg

                                                  1. 你好 Sven,

                                                    UTF-8 ist nach meiner Ansicht pflegeleichter, als es hier manchmal dargestellt wird. Das liegt zum einen daran, dass es tatsächlich vollständig bytekompatibel zu beispielsweise ISO-8859-1 ist, also keine merkwürdigen Bytes enthält, die vollkommen aus dem definierten Bereich von ISO-8859-1 herausfallen. Jedes System, was mit ISO-8859-1 grundsätzlich umgehen kann, kann auch mit UTF-8 umgehen.

                                                    Was daran liegt, dass es keine Bytes gibt, die nicht in ISO-8859-1 liegen. Hehe. Bei ISO-8859-1 ist jedes Byte belegt, von 0x00 bis 0xFF. De Facto gibt es also kein Zeichensatz, der nicht "ISO-8859-1-kompatibel" in dem von dir definierten Sinn ist.

                                                    Vermutlich spielst du auf ISO 8859-1 an, wo die Räume 0x00-0x1F und 0x80-0x9F nicht belegt sind.

                                                    Ja, der Bindesrich macht einen Unterschied. Benutzt wird jedoch üblicherweise ISO-8859-1 (man beachte den Bindestrich).

                                                    再见,
                                                     克里斯蒂安

                                              2. Hello,

                                                als ich sagte, dass wir mit (der aumstellung auf) UTF-8 noch viel Freude[tm] haben werden, bin ich nur ausgelacht worden.

                                                Eigentlich nicht.

                                                Ist denn inzwischen eine Lösung für den Index-Operator gefunden worden?

                                                Ein Zugriff per

                                                $zeichen = $string[$i];

                                                ist für multibyte-codierte Strings ja irgendwie nicht möglich?

                                                Doch, klar. Das liefert dir das BYTE an Position $i des Strings.

                                                Wenn du ZEICHEN haben willst, nimm mb_substr().

                                                qed!

                                                Keine befriedigende Lösung!

                                                Also müssen diese ganzen Stellen in Scripten bei Umstellung auch umgeschrieben werden!

                                                Sattdessen könnten die PHPler das Verhalten der (emulierten) Überladungen der Operatoren auch abhängig machen von einem generellen Schalter, der angibt, ob die folgende Funktion nun singlebyte oder multibyte agieren soll.

                                                Das hätte vermutlich auch das Umschreiben vieler vieler Scripte erspart.
                                                Aber es hätte den PHP-Entwicklern etwas mehr Arbeit abverlangt.

                                                Liebe Grüße aus dem schönen Oberharz

                                                Tom vom Berg

                                                --
                                                Nur selber lernen macht schlau
                                                http://bergpost.annerschbarrich.de
                                      2. Moin!

                                        In der Tat hatte mehere Situationen, sei es bei der Prüfung mit
                                        "if(is_file($file)...
                                        oder
                                        mkdir
                                        oder copy usw. Probleme mit UTF8 Daten und dem Windows Dateisystem

                                        Wenn ich konsequent mit "utf8_decode" arbeite klappt es.
                                        z.b.
                                        $test_dir = utf8_decode($test_dir);

                                        Das ist aber insgesamt keine sehr gute Idee.

                                        Woher kommen denn die Zeichen, die du da als Dateiname verwenden willst? Du darfst ja nicht einfach alle beliebigen Zeichen im Dateisystem verwenden, weil manche von denen ja ihre eigene Sonderbedeutung im Betriebssystem haben. Du musst also einen benutzerdefinierbaren Dateinamen immer auf das Vorhandensein böser Zeichen prüfen.

                                        utf8_decode() liefert dir für alle Zeichen, die in ISO-8859-1 definiert sind, eine vernünftige Dekodierung. Da Unicode aber weit mehr Zeichen erlaubt, kriegst du für alle anderen Zeichen nur ein Fragezeichen als Rückgabewert. Das Fragezeichen hat aber im Betriebssystem u.U. Sonderbedeutung - und auch andere Zeichen, die ganz harmlos in ASCII vorkommen, will man vermutlich nicht in Dateinamen haben.

                                        Du solltest dir also eine Funktion bauen, die dir einwandfreie ASCII-Dateinamen baut. Bestandteil dieser Funktion könnte $bettername = [link:http://docs.php.net/manual/en/function.iconv.php@title=iconv]('utf-8','ASCII//TRANSLIT', $evilname); sein. Das //TRANSLIT sorgt für eine Übersetzung von z.B. Umlauten und Euro-Zeichen in eine verfügbare Langform: Ä = AE, € = EUR, ß = ss.

                                        Danach sollte man alle Zeichen wegfiltern, die außerhalb des sichtbaren Bereichs sind, und sich auch hinsichtlich der Sonderzeichen einschränken.

                                        Meine Überlegung ist nun:
                                        Wenn ich nun die ganze Webanwendung und die Datenbank auf UTF8 lasse und alle Dateisystemfunktionen anpasse ist alles ok.
                                        Wenn nun aber irgend jemand später mal sagt. "Wir machen wieder alles auf latin1" oder ISO-8859-1" würde man ja die "utf8_decode" Funktionen nicht brauchen.

                                        Sowas wird nie einer sagen. :)

                                        Naja, klar dass du in diesem Fall die Funktion zum Bereinigen des Dateinamens anpassen musst, aber da du die ja einmal zentral definiert hast und überall zum Generieren eines gereinigten Dateinamens verwendest, passt du in diesem Fall einfach nur die Angabe des Input-Encodings von UTF-8 auf das neue Encoding an.

                                        Wäre es nun gut, vorher zu prüfen ob ein String in UTF8 vorliegt (geht das überhaupt?) oder ob es codierte Zeichen enthält? Wenn ja, dann "utf8_decode" einsetzen.

                                        Man kann das nicht prüfen, man muss es wissen. Woher man das weiß - weil man es so definiert hat, oder weil es bei den Daten dabeistand, die man empfangen hat,

                                        Oder wäre es egal, wenn "utf8_decode" eingesetzt wird auch wenn alles auf latin1 bzw. ISO-8859-1 ist?

                                        Nein, das zerstört dir den String.

                                        - Sven Rautenberg

                            2. Hello,

                              dieser Thread steigt auf meiner privaten Archivskala gerade über die Warnschwelle. Bitte jetzt nicht aufhören :-)

                              Nein, du willst UTF8 haben, also ist alles was nicht mit utf8_ anfängt unbrauchbar. Es gibt kein spezielles german für utf8, weil dessen Regeln in utf8_general und utf8_unicode enthalten sind. Wenn du keine sprachspezifischen Vergleichsregeln haben möchtest, nimm *_bin, also utf8_bin. Damit weiß das MySQL, dass die Daten als UTF8 zu interpretieren sind, aber beim Vergleichen keine speziellen Regeln zu verwenden sind. Dann ist aber auch a <> A und nicht nur a <> ä.

                              Das will man bei Passworten oder Schlüsselwert-Spalten ja eigentlich auch so haben. Keinerlei Kurzschlüsse in den Vergleichsregeln bitte. Vollen Wertebereich aufrecht erhalten und Doppelungen durch "a = ä" oder "a = A" von vorneherein ausschließen.

                              Liebe Grüße aus dem schönen Oberharz

                              Tom vom Berg

                              --
                              Nur selber lernen macht schlau
                              http://bergpost.annerschbarrich.de
                              1. Hi!

                                Nein, du willst UTF8 haben, also ist alles was nicht mit utf8_ anfängt unbrauchbar. Es gibt kein spezielles german für utf8, weil dessen Regeln in utf8_general und utf8_unicode enthalten sind. Wenn du keine sprachspezifischen Vergleichsregeln haben möchtest, nimm *_bin, also utf8_bin. Damit weiß das MySQL, dass die Daten als UTF8 zu interpretieren sind, aber beim Vergleichen keine speziellen Regeln zu verwenden sind. Dann ist aber auch a <> A und nicht nur a <> ä.

                                Das will man bei Passworten oder Schlüsselwert-Spalten ja eigentlich auch so haben. Keinerlei Kurzschlüsse in den Vergleichsregeln bitte. Vollen Wertebereich aufrecht erhalten und Doppelungen durch "a = ä" oder "a = A" von vorneherein ausschließen.

                                Jein. Passwörter auf alle Fälle, aber nicht bei allen Schlüsselwert-Spalten. Nicht immer will man, dass ein Mensch Schwierigkeiten hat beim Auseinanderhalten der Identitäten Tom, Tóm, Tòm und wie sie alle heißen mögen. Noch schwerer wird es bei TOM und ТОМ, da helfen auch keine Kollationsregeln mehr. Ein Computer hätte damit kein Problem, da der erste lateinische und der zweite kyrillische Buchstaben verwendet.

                                Lo!

                                1. Hello,

                                  Jein. Passwörter auf alle Fälle, aber nicht bei allen Schlüsselwert-Spalten. Nicht immer will man, dass ein Mensch Schwierigkeiten hat beim Auseinanderhalten der Identitäten Tom, Tóm, Tòm und wie sie alle heißen mögen. Noch schwerer wird es bei TOM und ТОМ, da helfen auch keine Kollationsregeln mehr. Ein Computer hätte damit kein Problem, da der erste lateinische und der zweite kyrillische Buchstaben verwendet.

                                  *grins*

                                  War das jetz eine Anspielung?  russisch ТОМ heißt übersetzt auf Deutsch VOLUME, sagt Goolge.

                                  Passt bei meinem Übergewicht dann ja fast wieder.

                                  Liebe Grüße aus dem schönen Oberharz

                                  Tom vom Berg

                                  --
                                  Nur selber lernen macht schlau
                                  http://bergpost.annerschbarrich.de
                              2. Hallo,

                                Das will man bei Passworten oder Schlüsselwert-Spalten ja eigentlich auch so haben. Keinerlei Kurzschlüsse in den Vergleichsregeln bitte. Vollen Wertebereich aufrecht erhalten und Doppelungen durch "a = ä" oder "a = A" von vorneherein ausschließen.

                                ja, was die Unterscheidung verschiedener Werte angeht, stimme ich da 100% zu. Ich wäre allerdings froh, wenn ich meiner Windows-Umgebung (Explorer, Office-Programme) eine "natürliche" Sortierung beibringen könnte, bei der

                                A == a == ä == á == â

                                gilt[1] - so wie ich es beim Sortierung "von Hand" auch machen würde. Und eine Sortierung, die auch die ganzen Sonderzeichen ordentlich mitsortiert. Gerade der Windows-Explorer hat da eine seltsame, für mich nicht nachvollziehbare Sortierstrategie:

                                Blank (0x20) < '.' (0x2E) < '_' (0x5F) < '~' (0x7E) < '+' (0x2B) < Buchstaben

                                Ein '-' (0x2D) in Dateinamen wird bei der Sortierung anscheinend komplett ignoriert, und auch sonst stutze ich immer mal wieder über die eigenwillige Sortierung. Word und Excel sortieren bei Tabelleninhalten wieder ein wenig anders, ordnen die Sonderzeichen (sogar die innerhalb des ASCII-Bereichs) aber auch sehr merkwürdig.
                                Wäre schön, wenn man die Sortierfolge umstellen könnte. Aber ich habe noch keine Möglichkeit gefunden.

                                So long,
                                 Martin

                                [1] Zwar gilt für den Explorer 'A' == 'a', aber sämtliche diakritischen, auf 'a' oder 'A' basierenden Zeichen sortiert er hinter 'z' ein.

                                --
                                Es sagte...
                                ein korpulenter Lehrer zu einem Schüler, der ihn ein Fass genannt hatte: "Nein. Ein Fass ist von Reifen umgeben, ich dagegen von Unreifen."
                                1. Hallo.

                                  Zwar gilt für den Explorer 'A' == 'a', aber sämtliche diakritischen, auf 'a' oder 'A' basierenden Zeichen sortiert er hinter 'z' ein.

                                  Vielleicht hast du ja die schwedische Version.
                                  MfG, at

                  2. Hello,

                    Also ich verstehe das jetzt nicht mehr so ganz..
                    Dann ist eigentlich eher die Kollation als der Typ wichtig?

                    Da lesen wir mal zusammen das MySQL-Manual. Ich habe mir das schließlich auch nicht selbst ausgedacht ;-)

                    Specifying the CHARACTER SET binary attribute for a character data type causes the column to be created as the corresponding binary data type: CHAR becomes BINARY, VARCHAR becomes VARBINARY, and TEXT becomes BLOB. For the ENUM and SET data types, this does not occur; they are created as declared. Suppose that you specify a table using this definition:

                    CREATE TABLE t
                    (
                      c1 VARCHAR(10) CHARACTER SET binary,
                      c2 TEXT CHARACTER SET binary,
                      c3 ENUM('a','b','c') CHARACTER SET binary
                    );

                    The resulting table has this definition:

                    CREATE TABLE t
                    (
                      c1 VARBINARY(10),
                      c2 BLOB,
                      c3 ENUM('a','b','c') CHARACTER SET binary
                    );

                    The ASCII attribute is shorthand for CHARACTER SET latin1.

                    The UNICODE attribute is shorthand for CHARACTER SET ucs2.

                    The BINARY attribute is shorthand for specifying the binary collation of the column character set. In this case, sorting and comparison are based on numeric character values.

                    Du brauchst also nur den Spaltentyp "BINARY(x)" oder "VARBINARY(x)" angeben.
                    Die Binary-Typen haben eine "natürliche" Collation, also eine, die auf den Bytewerten (dem Bitmuster) der eingetragenen Werte beruht.

                    Liebe Grüße aus dem schönen Oberharz

                    Tom vom Berg

                    --
                    Nur selber lernen macht schlau
                    http://bergpost.annerschbarrich.de
                    1. Hallo Tom,
                      ja das mit den Handbüchern ist immer so ne Sache.
                      Ich habe mir ja wirklich schon angewöhnt vorher zu schauen.
                      Aber offensichtlich habe ich an den flaschen Seiten geschaut.
                      Ich suchte zb. bei
                      http://dev.mysql.com/doc/refman/5.1/en/encryption-functions.html

                      und da steht:

                      The encryption and compression functions return binary strings. For many of these functions, the result might contain arbitrary byte values. If you want to store these results, use a column with a VARBINARY or BLOB binary string data type

                      Dann habe ich noch bei Charactrer Set im Manual nachgeschaut.
                      http://dev.mysql.com/doc/refman/5.1/en/charset-column.html

                      Aber du hast Recht.
                      Wenn ich die Spalte PWD auf varbinary stelle scheint es nun zu klappen.

                      Was ist dann wohl beim Typ BLOB anders das es nicht funktioniert?

                      vielen Dank und viele Grüße
                      hawk

          2. hi,

            Es wäre vermutlich das beste wenn ich die Passwortspalte als BLOB definiere?

            base64 wäre auch eine Möglichkeit aus bin-Zeichen ASCII zu machen und ist umkehrbar. Speicherung und Stringvergleich erfolgt dann auf ASCII-Ebene.

            Hotti

            --
            Wenn der Kommentar nicht zum Code passt, kann auch der Code falsch sein.
  2. Yerf!

    ABER:
    eine Tabelle "webuser" hatte in der Spalte Pword verschlüsselte Passwörter abgelegt, die ganz "wilde" Sonderzeichen enthielten (z.b. Å¡EfJk­Ž4ý²)

    Wenn sich nun ein User einloggen will, klappt dies nicht mehr. Offensichtlich stimmt das Passwort nicht mehr überein.
    Es wäre nun nicht so schlimm, die User neu anzulegen weil es nur ganz wenig sind.
    Mich würde aber interessieren warum dies mit der Umwandlung nicht geklappt hat?

    Meine Vermutung: die Passwort-Verschlüsselung erzeugt irgendeine Form von 8Bit-Datenstrom, der nicht wirklich als Text ausgelegt werden sollte, aber in der DB als Varchar (oder ähnliches) abgelegt wurde.

    D.h. die Verschlüsselung erzeugt immer noch die gleichen Daten wie vorher, aber durch die Umstellung der Datenbank wurden die gespeicherten Passwörter fälschlicherweise einer Iso -> Utf8 Wandlung unterzogen.

    Gruß,

    Harlequin

    --
    RIP --- XHTML 2
    nur die Besten sterben jung
    1. Hallo Harlequin

      vielen Dank auch an dich.
      Ich habe eben Hotte geantwortet.

      Das mit den alten Passwörtern könnte ich noch verkraften.
      Jedoch werden auch neue User bzw. deren Passwörter nicht richtig gespeciehrt.
      Ich speichere das Passwort mit der funktion
      AES_ENCRYPT(:pwd,@pswd_key)

      Die variable @pswd_key
      mache ich gleich nach dem Connect.
      query("SELECT @pswd_key:='test'")

      Komisch ist das nun die neuen Passwörter nicht richtig abgelegt werden.
      z.b. Passwort "hallo" wird als leere Spalte gespeichert. Passwort "testuser" als 9.

      Hast du eine Idee woran das liegen kann?

      vielen Dank und viele Grüße
      hawk

      1. Yerf!

        Ich speichere das Passwort mit der funktion
        AES_ENCRYPT(:pwd,@pswd_key)

        Hm, weis jetzt nicht, was diese Funktion als Ergebnis hat, aber vermutlich wie ich schon angedeutet hab werden es Binärdaten sein.

        Komisch ist das nun die neuen Passwörter nicht richtig abgelegt werden.
        z.b. Passwort "hallo" wird als leere Spalte gespeichert. Passwort "testuser" als 9.

        Hast du eine Idee woran das liegen kann?

        Vermutlich sind in den Daten Werte enthalten, die bei UTF8 ungültig sind (bei der ISO-Codierung kommt so etwas nicht vor).

        Wenn meine Vermutung richtig ist sollte man den Datentyp der Spalte auf einen für Binärdaten ändern.

        Gruß,

        Harlequin

        --
        RIP --- XHTML 2
        nur die Besten sterben jung
    2. Hello,

      D.h. die Verschlüsselung erzeugt immer noch die gleichen Daten wie vorher, aber durch die Umstellung der Datenbank wurden die gespeicherten Passwörter fälschlicherweise einer Iso -> Utf8 Wandlung unterzogen.

      Meine Meinung ist eher: die Prüfsummenbildung mit md5() (nehme ich einfach mal an) erzeugt nun eine andere Prüfsumme, weil ja keine singelbytebasierten Strings mehr geliefert werden, sondern multibytebasierte. Wenn in den Passwörtern also Zeichen enthalten sind, deren Codepoints zwei oder mehr Bytes benötigen, dann kann nicht mehr dieselbe Prüfsumme herauskommen, wie vorher.

      Da die Prüfsumme mit md5() selber nur Hexadezimal-Characters erzeugt, die mit ihren Codepoints in den ersten 128 Bytes des Coderaums liegen, kann hier eigentlich keine Veränderung stattfinden

      Das, wie gesagt, unter der Annahme, dass es sich um in der Datenbank abgelegte Passwörter der Applikation handelt, die mit md5() zu einer Prüfsumme verwandelt wurden.

      BTW: Ich habe die letzten Tage etwa 150 solcher Passwörter in Klartext zurückverwandelt. Keine Rechnung/Computing dauerte länger, als 3 Sekunden und alle haben gestimmt.

      md5() ist keine Verschlüsselung

      Liebe Grüße aus dem schönen Oberharz

      Tom vom Berg

      --
      Nur selber lernen macht schlau
      http://bergpost.annerschbarrich.de
      1. Yerf!

        Meine Meinung ist eher: die Prüfsummenbildung mit md5() (nehme ich einfach mal an) erzeugt nun eine andere Prüfsumme, weil ja keine singelbytebasierten Strings mehr geliefert werden, sondern multibytebasierte. Wenn in den Passwörtern also Zeichen enthalten sind, deren Codepoints zwei oder mehr Bytes benötigen, dann kann nicht mehr dieselbe Prüfsumme herauskommen, wie vorher.

        Das ist natürlich auch ein Punkt der zu beachten ist, aber das Problem äußert sich doch noch etwas anders.

        Da die Prüfsumme mit md5() selber nur Hexadezimal-Characters erzeugt, die mit ihren Codepoints in den ersten 128 Bytes des Coderaums liegen, kann hier eigentlich keine Veränderung stattfinden

        Das gepostete Beispiel für einen Passwort-Hash sah aber nicht nach Hex-Code aus, sondern nacht einen durch UTF8-Wandlung verunstalteten ISO-String. Von daher befürchte ich eher, dass binäre Hashcodes als String in der DB standen.

        md5() ist keine Verschlüsselung

        a) sowieso nicht, sondern eine hash-Funktion

        b) es ist auch nicht neu, dass es unsicher ist

        Gruß,

        Harlequin

        --
        RIP --- XHTML 2
        nur die Besten sterben jung
        1. Hello,

          md5() ist keine Verschlüsselung

          a) sowieso nicht, sondern eine hash-Funktion
          b) es ist auch nicht neu, dass es unsicher ist

          Ich reite darauf nur herum, weil auch von "Wissenden" immer wieder geschrieben wird, "mit md5() verschlüsselt". Ich schließe mich da nicht aus, will mich aber bessern ;-)

          Liebe Grüße aus dem schönen Oberharz

          Tom vom Berg

          --
          Nur selber lernen macht schlau
          http://bergpost.annerschbarrich.de
  3. Hello,

    eine Tabelle "webuser" hatte in der Spalte Pword verschlüsselte Passwörter abgelegt, die ganz "wilde" Sonderzeichen enthielten (z.b. Å¡EfJk­Ž4ý²)

    ich vermute, dass es mit Umstellung von Zeichensätzen und Codierungen usw. noch nicht getan ist.

    Das Passwort wurde vermutlich mit md5() in eine Prüfsumme verwandelt.
    Als Grundlage hast Du einen Single-Byte-Code verwendet.
    Nun sind die Sonderzeichen im String aber plötzlich durch Multibyte-Codes darzustellen.
    Das muss mMn eine andere Prüfsumme ergeben, da ja andere Bytes in der Zeichenkette stehen und md5() für mich keine erkennbare Möglichkeit zur Berücksichtigung von Multibytecode hat
    http://de2.php.net/manual/en/function.md5.php

    Das gleiche Problem hast Du jetzt vermutlich in jeder Programmstelle, die Stringfunktionen verwendet. Die müssen jetzt alle umgeschrieben werden auf die mb_*-Stringfunktionen
    http://de2.php.net/manual/en/ref.mbstring.php

    Ich würde mir da als erstes eine Liste aller umzuschreibenden Stringfunktionen machen und dann mit einen Editor die Dateien nach deren Vorkommen durchsuchen lassen.

    Vielleicht könnte man sogar ein Konvertierungsscript dafür schreiben...
    Sollte man mal darüber nachdenken, oder die große Grabbelkiste durchsuchen.

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
    Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de
    1. Hallo Tom,
      vielen Dank auch an dich.
      Ohje ohje worauf habe ich mich da nur eingelassen.

      Das gleiche Problem hast Du jetzt vermutlich in jeder Programmstelle, die Stringfunktionen verwendet. Die müssen jetzt alle umgeschrieben werden auf die mb_*-Stringfunktionen
      http://de2.php.net/manual/en/ref.mbstring.php

      Ich würde mir da als erstes eine Liste aller umzuschreibenden Stringfunktionen machen und dann mit einen Editor die Dateien nach deren Vorkommen durchsuchen lassen.

      wie ich bereits an Harlequin und Hotte geschrieben habe, schreibe ich die Passwörter mit
      pwd = AES_ENCRYPT(:pwd,@pswd_key)

      Ich verstehe nicht ganz was du meinst mit "Programmstellen und Stingfunktionen"?
      Kannst du mir ein Beispiel nennen?

      vielen Dank und viele Grüße
      hawk

      1. Hello,

        Ich verstehe nicht ganz was du meinst mit "Programmstellen und Stingfunktionen"?
        Kannst du mir ein Beispiel nennen?

        Stringfunktionen für Single-Byte-Codierungen findest Du unter
        http://de2.php.net/manual/en/ref.strings.php

        Stringfunktionen für Multi-Byte-Codierungen findest Du unter
        http://de2.php.net/manual/en/ref.mbstring.php

        Wenn Du beide gegenüberstellst, siehst Du, dass Du durch die Umstellung auf utf-8 manche Single-Byte-Funktionen gegen die entsprechenden Multi-Byte-Funktionen ersetzen musst.

        Liebe Grüße aus dem schönen Oberharz

        Tom vom Berg

        --
        Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
        1. Hallo Tom,

          danke für die Infolinks.
          Ich hatte mich ehrlich gesagt vorher nie mit den mbstring Funktionen befasst.
          Nur nochmals zum Verständnis.
          Ich verwende natürlich an vielen Stellen auf den PHP Seiten Funktionen wie;
          substr , strlen, implode, explode usw.

          Ich muss vermutlich aber nur die String funktionen testen und überprüfen an deren Stelle anschließend ein Datenbank Eintrag oder Select erfolgt oder?
          Also nicht JEDE String Funktion ansich.

          vielen Dank und viele Grüße
          hawk

          1. Hello,

            Ich verwende natürlich an vielen Stellen auf den PHP Seiten Funktionen wie;
            substr , strlen, implode, explode usw.

            Ich muss vermutlich aber nur die String funktionen testen und überprüfen an deren Stelle anschließend ein Datenbank Eintrag oder Select erfolgt oder?
            Also nicht JEDE String Funktion ansich.

            Du wirst jedes Statement überarbeiten müssen, dass eine "affected string function" enthält, also jedes Statement, dass eine Stringfunktion enthält, für dies es eine mb_*-Stringfunktion gibt, es sei denn, dass die Zeichen der Eingangsgrößen garantiert immer aus der Menge der ersten 128 Codepoints stammen.

            Liebe Grüße aus dem schönen Oberharz

            Tom vom Berg

            --
            Nur selber lernen macht schlau
            http://bergpost.annerschbarrich.de
  4. Hallo zusammen,

    bei meinen Test nach der Umstellung bin ich auf ein erneutest Problem gestossen und zwar mit "str_pad"
    Ich nutze dies an mehreren Stellen um einen String zu füllen.

      
    $new_filename = str_pad($row['FileName'],$pad0, "#");  
    
    

    wenn nun "$row['FileName']" als UTF8 mit Umlauten vorliegt, stimmt die Menge an aufzufüllenden Zeichen nicht mehr.

    Leider gibt es keine passende mb_ string Funktion dazu.

    Was könnte man tun?
    Eine eigene Funktion dazu schreiben?

    oder gleich warten bis PHP6 rauskommt :-)

    vielen Dank und viele Grüße
    hawk

    1. Hello,

      Was könnte man tun?

      Die Branche wechseln.

      Liebe Grüße aus dem schönen Oberharz

      Tom vom Berg

      --
      Nur selber lernen macht schlau
      http://bergpost.annerschbarrich.de
    2. Moin!

      bei meinen Test nach der Umstellung bin ich auf ein erneutest Problem gestossen und zwar mit "str_pad"
      Ich nutze dies an mehreren Stellen um einen String zu füllen.

      $new_filename = str_pad($row['FileName'],$pad0, "#");

      
      > wenn nun "$row['FileName']" als UTF8 mit Umlauten vorliegt, stimmt die Menge an aufzufüllenden Zeichen nicht mehr.  
        
      Du arbeitest hier mit Dateinamen? Dann filtere die doch erstmal zu einer sicheren ASCII-Darstellung, bevor du auffüllst.  
        
      Ansonsten:  
        
      
      > Eine eigene Funktion dazu schreiben?  
        
      Ja. Kombiniere str\_repeat (dem ist egal, ob der zu kopierende String UTF-8 ist) und mb\_substr.  
        
       - Sven Rautenberg