Zeddix: Utf8 und Mysql

Hallo,

Im Vorraus:
Ich benutze Wamp (2.0i) als Tool zum Verwalten von:
MySQL 5.1.36
sowie
Apache 2.2.11
PHP 5.3.0

Vor kurzem bin ich auf das Problem mit Umlauten und der Kommunikation von MySQL und PHP gestoßen, daraufhin hab ich mich ein wenig schlaugemacht(so hoffe ich doch) und möchte auf von Latin auf UTF_8 umsteigen.
Ich habe für alle Datenbankeinträge UTF_8_bin als Kollation gewählt um mir erstmal alle Möglichkeiten(Groß und Kleinschreibung, ü/u) offen zu lassen.
Die Datenbank habe ich umgestellt, dann habe ich meinen Texteditor auf "UTF-8 ohne BOM" umgestellt.
Dann hab ich noch für den Client folgende Zeilen im PHP-Code und HTML-Code hinzugefügt:

PHP-Code
header("Content-type: text/html; charset=UTF-8");

HTML-Code
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

Dann habe ich noch gelesen, dass noch die Kommunikation zwischen PHP und MySQL auch auf UTF-8 umgestellt werden muss, also habe ich folgendes probiert:

mysql_query("SET NAMES 'utf8'");  
mysql_query("SET CHARACTER SET 'utf8'");

und
mysql_set_charset('utf8',$sqldb);

Dann hab ich gedacht "Toll jetzt mal schauen ob mein Scribt läuft!".
Naja wie zu erwarten macht er Probleme, gleich wenn ich eine Tabelle erstellen möchte:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '�ste VARCHAR(12) NOT NULL )'

Der Code der ausgeführt wird soll eigentlich heißen:

  
$grpadmin[0] = 'Administratoren';  
$grpmod[0] = 'Moderatoren';  
$grpreg[0] = 'Registrierte';  
$grpguest[0] = 'Gäste';  
  
$grptablecreate = '  
CREATE TABLE groups (  
	id INT AUTO_INCREMENT PRIMARY KEY,  
		name VARCHAR(80) NOT NULL,  
		'.$grpadmin[0].' VARCHAR(12) NOT NULL,  
		'.$grpmod[0].' VARCHAR(12) NOT NULL,  
		'.$grpreg[0].' VARCHAR(12) NOT NULL,  
		'.$grpguest[0].' VARCHAR(12) NOT NULL  
);

Eindeutig gibt es ein Problem mit dem Erstellen eine Spalte die einen Umlaut enthält.
Will ich aber zum Beispiel einen Eintrag mit einem Umlaut in die Tabelle schreiben so klappt das gut:
Der Eintrag heißt dann: "Gäste"
(Ich hoffe mal das ist Richtig :))

Was ich möchte ist einfach, dass ich mit Umlauten in UTF_8 in der MySQL-Tabelle Arbeiten kann.

Wäre super wenn mir das jemand nochmal erklären könnte wie das funktioniert.

Danke Zeddix

  1. Wäre super wenn mir das jemand nochmal erklären könnte wie das funktioniert.

    Was mir persönlich fehlt - wie (in welchem Format) sind deine Scripte gespeichert?

    1. Was mir persönlich fehlt - wie (in welchem Format) sind deine Scripte gespeichert?

      Ich hoffe ich verstehe die Frage richtig :).
      Also ich hab die Datein als Text-Datein mit der Endung .php gespeichert.
      Das Format ist "UTF8 ohne BOM".

  2. Hi!

    Ich habe für alle Datenbankeinträge UTF_8_bin als Kollation gewählt um mir erstmal alle Möglichkeiten(Groß und Kleinschreibung, ü/u) offen zu lassen.

    Da der Fehler gern im Detail steckt bitte ich dich, bei den Begrifflichkeiten möglichst genau zu sein. "Datenbankeinträge" sind im Allgemeinen Daten. Wenn du Datenbank, Tabelle, Felder meinst, dann benenn sie bitte auch so, damit man weiß, wovon du sprichst. Die Feldeinstellung ist letztlich wichtig, wobei der zweite Teil (genannt Kollation. hier: bin) nicht für die Ablage sondern für das spätere Verarbeiten interessiert.

    mysql_query("SET NAMES 'utf8'");

    mysql_query("SET CHARACTER SET 'utf8'");

      
    Beide Statements ändern die selben Konfigurationswerte. Sie überschreiben sich also gegenseitig, wenn du beide absendest. Üblicherweise will man aber die Auswirkungen von SET CHARACTER SET nicht haben.  
      
    
    > `mysql_set_charset('utf8',$sqldb);`{:.language-php}  
      
    Und da du diese Funktion verwenden kannst, brauchst du gar keins von den beiden obigen Statements abzusenden. Solange du diese Funktion verwenden kannst, solltest du ihr den Vorzug vor dem SET NAMES-Statement geben. Außerdem musst du sie nach jedem mysql\_connect() ausführen, da sie nur für die aktuelle Verbindung arbeitet.  
      
    
    > You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '�ste VARCHAR(12) NOT NULL )'  
      
    Das sieht danach aus, als ob du doch kein UTF-8 sendest sondern Latin1/ISO-8859-1/Windows-1252.  
      
    
    > Der Code der ausgeführt wird soll eigentlich heißen:  
    >   
    > ~~~php
      
    
    > $grpadmin[0] = 'Administratoren';  
    > $grpmod[0] = 'Moderatoren';  
    > $grpreg[0] = 'Registrierte';  
    > $grpguest[0] = 'Gäste';  
    >   
    > $grptablecreate = '  
    > CREATE TABLE groups (  
    > 	id INT AUTO_INCREMENT PRIMARY KEY,  
    > 		name VARCHAR(80) NOT NULL,  
    > 		'.$grpadmin[0].' VARCHAR(12) NOT NULL,  
    > 		'.$grpmod[0].' VARCHAR(12) NOT NULL,  
    > 		'.$grpreg[0].' VARCHAR(12) NOT NULL,  
    > 		'.$grpguest[0].' VARCHAR(12) NOT NULL  
    > );
    
    

    Schau dir lieber den fertigen String an und schick ihn mal durch urlencode(). Bekommst du für das ä zwei %xx-Sequenzen oder nur eine?

    Will ich aber zum Beispiel einen Eintrag mit einem Umlaut in die Tabelle schreiben so klappt das gut:
    Der Eintrag heißt dann: "Gäste"
    (Ich hoffe mal das ist Richtig :))

    Das kommt ganz darauf an, wo und wie du das betrachtest. Wenn das so im phpMyAdmin angezeigt wird, dann hast du was falsch gemacht. Du hast dabei UTF-8 gesendet, das DBMS hat aber Latin1 gelesen und nach UTF-8 umkodiert. Oder aber im DBMS ist alles richtig und du schaust dir die UTF-8-Ausgabe als ISO-8859-1 interpretiert an.

    Was ich möchte ist einfach, dass ich mit Umlauten in UTF_8 in der MySQL-Tabelle Arbeiten kann.
    Wäre super wenn mir das jemand nochmal erklären könnte wie das funktioniert.

    Wenn man es richtig macht, funktioniert das problemlos. Du musst nur dafür sorgen, dass
    a) jedes System intern mit der gewählten Kodierung umgehen kann und
    b) beim Datenaustausch dem Zielsystem die verwendete Kodierung mitgeteilt wird und die Daten auch tatsächlich in dieser Kodierung vorliegen.

    Die Kodierung von Daten lässt sich am besten im Hex-Modus betrachten. bin2hex() ist eine unter PHP verwendbare Funktion und urlencode() lässt sich auch gut dafür missbrauchen.

    Lo!

    1. Danke dir, hab den Fehler gefunden und jetzt klappt es (immoment) alles Prima :). Das Problem war, das ich in Latin1 gesendet habe, da ich immoment noch einen (vermutlich eher ungesunden) Mix aus MySQLi- und MySQL-Syntax benutze. Dann hatte ich die Einstellung nur für die normale MySQL Verbindung getätig und nicht für die MySQLi Verbindung. Darauf muss man erstmal kommen. Natürlich wurde auch der Feld-Eintrag dann in myPHPAdmin falsch angezeigt, nun steht da ordentlich Gäste :).

      Deine Erklärungen waren echt super, jetzt hab ich das System richtig verstanden. Nun sollte ich auch in Zukunft die Probleme einfacher lösen können, da es die Fehlersuche erheblich einfacher macht! Danke dir xD.

      Gruß Zeddix