dedlfix: Codierung (Charset UTF-8)

Beitrag lesen

echo $begrüßung;

Ich hab da nochmal was vorbereitet. Teil 1 des Versuchs schreibt ein ä in ein Latin1-Feld und fragt dieses unter den Verbindungskodierungen Latin1 und UTF-8 ab. Dann wird die Feldkodierung auf UTF-8 umgestellt und wieder mit beiden Verbindungskodierungen abgefragt. Dieser Versuch zeigt aber nur, dass MySQL auf der Verbindung die jeweils richtige Bytefolge schickt. Das Feld stellt eine Black-Box dar. Was darin passiert ist in diesem Teil nicht offensichtlich. Es kann nur vermutet werden, dass MySQL zwischen Feldkodierung und Verbindungskodierung bei Bedarf umkodiert.
Teil 2 versucht den Deckel der Black-Box zu lüften. Er schreibt ein ä und das Nicht-Latin1-Zeichen Ω (Ohm-Zeichen; Unicode-2126) in die Tabelle und stellt dann die Feldkodierung auf Latin1 um. Das Ω geht dabei flöten, weil es nicht in Latin1 kodiert werden kann. Das ä lässt sich weiterhin unter beiden Verbindungskodierungen abfragen.

(Der Code ist kein Beispiel für gutes mysqli-Handling unter PHP, denn ich hab sämtliche Fehlerprüfungen weggelassen. Bitte vor Ausführung sicherstellen, dass keine Tabelle names "test" existiert.)

<pre>  
<?php  
  
class test_mysqli extends mysqli {  
  // Zusammenfassung von Query, Fetch und Ausgabe als Hex-Werte  
  function abfrage() {  
    $result = $this->query('SELECT feld FROM test');  
    $row = $result->fetch_assoc();  
    print bin2hex($row['feld']) . "\n";  
  }  
}  
  
// Vorbereitung; Anlegen der Tabelle mit einem Latin1-Feld  
$mysqli = new test_mysqli('localhost', 'test', 'test', 'test');  
$mysqli->set_charset('latin1'); // entspricht SET NAMES  
$mysqli->query('CREATE TABLE test (feld VARCHAR(10) CHARACTER SET latin1)');  
$mysqli->query("INSERT INTO test SET feld='\xE4'"); // ein ä  
  
// Abfragen; Verbindungskodierung ist immer noch latin1  
$mysqli->abfrage(); // Ausgabe: e4  
  
// Abfragen; Verbindungskodierung auf utf8 umgestellt  
$mysqli->set_charset('utf8');  
$mysqli->abfrage(); // Ausgabe: c3a4  
  
// Ändern der Feldkodierung auf utf8  
$mysqli->query('ALTER TABLE test CHANGE feld feld VARCHAR(10) CHARACTER SET utf8');  
  
// Abfragen mit Verbindungskodierung latin1  
$mysqli->set_charset('latin1');  
$mysqli->abfrage(); // Ausgabe: e4  
  
// Abfragen mit Verbindungskodierung utf8  
$mysqli->set_charset('utf8');  
$mysqli->abfrage(); // Ausgabe: c3a4  
  
// Gegenversuch mit Zeichen, das nicht in Latin1 enthalten ist  
print "\n";  
$mysqli->query('TRUNCATE test');  
$mysqli->query("INSERT INTO test SET feld='\xc3\xa4\xe2\x84\xa6'"); // ä + Ω (Ohm-Zeichen; Unicode-2126)  
$mysqli->abfrage('SELECT feld FROM test'); // Ausgabe: c3a4e284a6  
  
// Abfragen mit Verbindungskodierung latin1  
$mysqli->set_charset('latin1');  
$mysqli->abfrage(); // Ausgabe: e43f - ein ä und ein Fragezeichen  
  
// nochmal Abfragen mit Verbindungskodierung utf8  
$mysqli->set_charset('utf8');  
$mysqli->abfrage(); // Ausgabe: c3a4e284a6 - ist also noch vorhanden  
  
// Ändern der Feldkodierung auf latin1  
$mysqli->query('ALTER TABLE test CHANGE feld feld VARCHAR(10) CHARACTER SET latin1');  
  
// Abfragen; Verbindungskodierung ist immer noch utf8  
$mysqli->abfrage(); // Ausgabe: c3a43f - ä lebt noch, Ω ist tot  
  
// Abfragen mit Verbindungskodierung latin1  
$mysqli->set_charset('latin1');  
$mysqli->abfrage(); // Ausgabe: e43f - ein ä und ein Fragezeichen  
  
  
// Aufräumen  
$mysqli->query('DROP TABLE test');

echo "$verabschiedung $name";