Ankündigung

Einklappen
Keine Ankündigung bisher.

Bestimmt zum 1000sten Mal: Php/MySql/Umlaute :(

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Bestimmt zum 1000sten Mal: Php/MySql/Umlaute :(

    Moin,

    bitte nicht hauen, auch wenn ich bestimmt die 1000ste Anfrage wegen des leidigen Umlaut Problems zwischen Php und MySSQL stelle.

    Nach 2 Tagen Internet-Recherche und nur immer wieder Verschlimmbesserungen meiner Datenbank (die nämlich inzwischen nur noch ein Mischmasch zwischen richtig und als gespeicherten Umlauten darstellt) erhoffe ich mir Hilfe aus dem Forum.

    Aber zur Sache, was ist los, bzw. was habe ich alles versucht:

    1. Der Datenbank-Server
    Server Version: 5.5.52-0+deb7u1-log - (Debian)
    Server Zeichensatz: UTF-8 Unicode ( utf8 )

    2. Die Datenbank
    Zeichensatz/Kollation der MySQL-Verbindung: utf8_general_ci

    3. Die Tabellen in der Datenbank
    artikelnummern1 10 MyISAM utf8_general_ci 2.2 KiB -
    artikelnummern2 8 MyISAM utf8_general_ci 2.4 KiB 100B
    artikelnummern3 0 MyISAM utf8_general_ci 1 KiB -
    ...
    7 Tabellen Gesamt 2,748 MyISAM utf8_general_ci 280.7 KiB 220 B

    Nach dem Import eines CSV-Files sah auch alles prima aus. Mit phpMyAdmin in die Tabellen geschaut und alle Umlaute waren da!
    Die Ausgabe über PHP hat aber nicht funktioniert. Die Umlaute wurde natürlich als Sonderzeichen ausgegeben.

    So, jetzt PHP

    1. Hier setze ich erst mal den PHP-Header - als 2. Zeile, direkt nach Session-Start;
    <?php
    session_start();
    header("Content-Type: text/html; charset=utf-8");
    ?>

    2. VOR dem ersten Query zünde ich ein wahres Feuerwerk von MySQL-EInstellungen (Eine Sammlung von allem was ich in letzter Zeit gefunden habe, nach dem Motto viel hilft viel.):
    mysql_query("SET NAMES 'utf8' COLLATE 'utf8_general_ci'") or die(mysql_error());
    $strQuery = "SET character_set_results = 'utf8',
    character_set_client = 'utf8',
    character_set_connection = 'utf8',
    character_set_database = 'utf8',
    character_set_server = 'utf8'";
    mysql_query($strQuery);
    $names = mysql_query('set names utf8');


    Und tatsächlich: Jetzt werden die Daten nach dem Auslesen richtig angezeigt!

    ABER: Schaut man sich über PHP neu angelegte Daten in der DB an, dann sind hier wieder Sonderzeichen statt Umlauten gespeichert worden. Auch die PHP-Ausgabe ist dann wieder falsch.

    Abfragen in denen Umlaute vorkommen hauen natürlich auch nicht hin. "Müller" z.Bsp. wird nie gefunden.

    Achja noch was:

    Auszug aus phpinfo():
    default_charset UTF-8 UTF-8

    und natürlich werden alle Dateien mit UTF-8 und ohne BOM abgespeichert (Dreamweaver-Standard-Einstelllung).

    Die Umwandlung mit utf8_encode() funktioniert übrigens auch- allerdings auch mit dem hässlichen Effekt dass nur Müll-Sonderzeichen in die DB zurück geschrieben werden

    Hat jemand Tipps was ich noch versuchen kann?

    Danke schon mal und viele Grüße
    Carsten

  • #2
    Dann wollen wir mal versuchen dein DB-Chaos in Ordnung zu bringen.
    Lies dir erst mal alles durch und versuche zu verstehen was ich hier schreibe, danach folgst du den Schritten.

    Schritt 1
    Du musst die Zeichenkodierung zur DB festlegen, das kann man mit set_charset machen, wie hier verdeutlicht wird

    PHP-Code:
    $mysqli = new mysqli("localhost""my_user""my_password""test");

    /* check connection */
    if (mysqli_connect_errno()) {
        exit(
    "Connect failed: %s\n"mysqli_connect_error());
    }

    /* change character set to utf8 */
    $mysqli->set_charset("utf8");
    ... 
    mehr braucht es dazu erst mal nicht.

    Schritt 2
    Um deine DB konsistent in UTF-8 zu wandeln, machst du ein SQL-Export.
    Beispiel:
    (Deine Daten sehen natürlich anders aus.)
    Code:
    CREATE TABLE IF NOT EXISTS `customer` (
      `id` int(11) NOT NULL,
      `firstname` varchar(50) NOT NULL,
      `lastname` varchar(50) NOT NULL,
      `company` varchar(50) NOT NULL,
      PRIMARY KEY (`id`),
      KEY `id` (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    Wichtig ist hier eigentlich nur die letzte Zeile, da sollte als Engine InnoDB stehen und UTF-8 als Default Charset, wenn nicht, änderst du das.
    Danach importierst du das mit den Änderungen in eine neue DB inklusive deiner Daten.

    Jetzt hast du eine Datenbank mit der richtigen Zeichenkodierung.
    Die Kollation kannst du in den Feldern in denen Namen vorkommen auf utf8_german2_ci stellen, das geht mit PHPmyAdmin oder du änderst das im SQL-Dump vor Erzeugen der neuen DB nach folgendem Muster
    Code:
    --
    -- Table structure for table `customer`
    --
    
    CREATE TABLE IF NOT EXISTS `customer` (
      `id` int(11) NOT NULL,
      `firstname` varchar(50) CHARACTER SET utf8 COLLATE utf8_german2_ci NOT NULL,
      `lastname` varchar(50) CHARACTER SET utf8 COLLATE utf8_german2_ci NOT NULL,
      `company` varchar(50) NOT NULL,
      PRIMARY KEY (`id`),
      KEY `id` (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    --
    -- Dumping data for table `customer`
    --
    
    INSERT INTO `customer` (`id`, `firstname`, `lastname`, `company`) VALUES
    (1, 'Thilo', 'Müller', 'Megasuperduper GmbH');
    Danach hast du schon mal eine Datenbank mit richtiger Zeichenkodierung und auch richtiger Kollation, also Sortierreihenfolge bei Namen. Die Kollation bitte nicht bei Zahlen oder Datumswerten ändern da das zu massiven Problemen bei Mysql führen kann, dort sollte utf8_general_ci eingestellt sein..
    Kollation bei Wikopedia erklärt.

    Schritt 3
    Wenn jetzt alle PHP-Scripte als UTF-8 abgespeichert sind bist du fast am Ziel.

    Schritt 4
    Du prüfst jetzt ob dein Server auch UTF-8 ausliefert.
    Dazu im Browser Firefox auf deiner Seite die rechte Maustaste drücken und View Page Info oder Seiteninformationen auswählen. Bei Text Encoding(Zeichenkodierung) muss UTF-8 stehen.
    Wenn das der Fall ist bist du am Ziel und hast alles auf UTF-8 umgestellt.

    Da du jetzt 2 Datenbanken hast, kannst du die erste Löschen, nicht das du aus Versehen weiterhin mit der kaputten Version arbeitest.

    Sollte etwas nicht so funktionieren meldest du dich her wieder.

    Kommentar


    • #3
      Moin Prostetix,

      vielen, vielen Dank für deine sehr ausführliche Antwort- vor allem zu so später Stunde!

      Ich versuche mich mal Schritt für Schritt an deiner Anleitung langzuhangeln, scheitere aber schon ganz am Anfang:

      Meine DB ist nicht auf einem eigenen Server, sondern wird bei 1&1 gehostet. Ich kann also keine eigenen DBs anlegen, sondern das geschieht über ein Admin-Tool.
      Eine neue DB wird mit dem Zeichensatz UTF8_general_ci und dem Typ MyISAM angelegt. Das ist nicht einstellbar.

      Ich habe jetzt also eine neue DB angelegt, alle Tabellen erstellt und DEREN Typ dann auf InnoDB umgestellt. Ich hoffe dieser Workaround funktioniert.
      Nächster Stolperstein: Es gibt bei 1&1 keinen Zeichensatz UTF8_german2_ci. Ich musste es also bei UTF8_general_ci belassen.

      Als nächstes der Export / Import:
      Wir kommen von einer DB und Tabellen mit dem Zeichensatz latin1_german2_ci

      Ich habe also alles exportiert (per phpMyAdmin- ich hoffe das ist Ok, weil dein Beispiel für einen Export so wie ich das sehe PHP Tabellen anlegt und nicht exportiert ) und im Dump dann alle Vorkommen von latin1_german2_ci durch UTF8_general_ci ersetzt.

      Wenn ich mir die neue DB jetzt anschaue habe ich also einen Zeichensatz bei der DB UTF8_general_ci, Typ MyISAM und alle Tabellen sind vom Zeichensatz UTF8_general_ci und Typ InnoDB.
      Nach dem Import werden in der DB alle Umlaute mit Fragezeichen dargestellt.

      Firefox bestätigt übrigens dass die Textkodierung UTF-8 ist.

      Und nu?

      Kommentar


      • #4
        Bitte nicht Zeichensatz mit Zeichenkodierung gleichsetzen, das sind 2 unterschiedliche Paar Schuhe. Zeichensatz ist eine Menge an darstellbaren Zeichen..Da kann das "Ä" enthalten sein genauso wie ein "⇡". Kodierung ist wie das Zeichen intern abgespeichert wird, ob also 8 Bit für ein Zeichen zur Verfügung steht oder 16 Bit oder gar 32 Bit. Da man mit mehr Bits mehr Zeichen ablegen kann ist der mögliche darstellbare Zeichenumfang ungleich grösser.

        Nach dem Import werden in der DB alle Umlaute mit Fragezeichen dargestellt.
        Meinst du auf deiner Webseite oder in PHPMyAdmin?

        Kommentar


        • #5
          nicht Zeichensatz mit Zeichenkodierung gleichsetzen
          Ah, ok

          In phpMyAdmin werden die Umlaute nur mit Fragezeichen dargestellt.

          Kommentar


          • #6
            http://www.php-rocks.de/thema/98-die...schw-rung.html
            Competence-Center -> Enjoy the Informatrix
            PHProcks!Einsteiger freundliche TutorialsPreComposed Packages

            Kommentar


            • #7
              In der Tabelle stehen die falschen Zeichen drin, ich fürchte fast, das musst du nun per Hand korrigieren.

              Du kannst in PHP auf den SQL Tab gehen und mal folgendes Versuchen, unteren Code rein kopieren den Namen der Tabelle ändern von t1 auf deine Tabelle und ausführen.
              Code:
              ALTER TABLE t1 CHARACTER SET = utf8;
              Wenn es das nicht bringt, dann eben wie oben beschrieben per Hand jeden Datensatz einzeln korrigieren, es sei denn jemand anderes hat dafür eine Lösung im Petto.

              Kommentar


              • #8
                nicht vergessen - auch PHPmyadmin hat eine eigene Einstellung .. ich hab hier schon Leute gesehen, die in ihren Scripten und Datenbank ALLES richtig gemacht haben - und dann hinterher genörgelt haben, weil es im phpmyadmin "merkwürdig" aussah ... wo dann eindeutig phpmyadmin veraltet oder falsch eingerichtet war ...
                "Irren ist männlich", sprach der Igel und stieg von der Drahtbürste [IMG]http://www.php.de/core/images/smilies/icon_lol.gif[/IMG]

                Kommentar


                • #9
                  Ev. deswegen auch mal statt phpmyadmin einen SQL-Client wie zB HeidiSQL (mein Favorit), SQLWorkbench, etc.. verwenden. PMA nutze ich nur mehr wenn es nicht anders geht.
                  The string "()()" is not palindrom but the String "())(" is.

                  Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
                  PHP.de Wissenssammlung | Kein Support per PN

                  Kommentar

                  Lädt...
                  X