Hi!
[...] wenn ich meiner mySQL - query ein "SET NAMES utf8" vorausschicke. tue ich das nicht, werden die älteren, nicht korrigierten einträge richtig dargestellt, die neuen utf8-codierten einträge aber mit einem fragezeichen-platzhalter. das bedeutet doch, dass die abfrage selbst nicht in utf-8 übermittelt wird, oder? (wie gesagt, wenn ich SET NAMES utf8 vorausschicke, werden die neuen einträge richtig dargestellt...)
Es bedeutet genau das, was SET NAMES bewirkt. MySQL geht nach einem SET NAMES - oder besser mysql(i)_set_charset() - davon aus, dass die Daten auf der aktuellen Verbindung in der angegebenen Kodierung kommen und auch die Ergebnisse in dieser Kodierung geliefert werden sollen. Ohne SET NAMES geht MySQL davon aus, dass die System-Default-Kodierung für die Kommunikation mit dem Client verwendet werden soll.
Das Problem mit deinen alten Datensätzen ist dies: Du hast zwar MySQL durch die Konfiguration der einzelnen Felder gesagt, dass es die Daten darin UTF-8-kodiert ablegen soll. Die Verbindung stand aber auf Latin1. MySQL hat daraufhin von Latin1 nach UTF-8 umkodiert. Allerdings hat es dabei in den von dir in UTF-8-kodiert gelieferten Daten die aus mehreren Byte bestehenden Sequenzen einiger Zeichen (Umlaute vorzugsweise) als jeweils ein Zeichen aufgefasst und auch nochmal nach UTF-8 umkodiert. Du siehst, wie MySQL die Daten beim Einfügen interpretiert hat, wenn du dir die alten Datensätze im PMA anschaust und zwei Zeichen pro Umlaut angezeigt werden. Wenn du nun das SET NAMES weglässt, kodiert MySQL beim Abfragen den Feldinhalt wieder zurück nach Latin1 und du interpretierst ihn als UTF-8 und hast kein Problem. Verwendest du jedoch "SET NAMES utf8" bleiben die Daten UTF-8-kodiert und du siehst die zwei Zeichen, die MySQL damals gelesen hat als zwei UTF-8-kodierte Zeichen und nicht als eins.
gesendet - interpretiert - gespeichert | ausgeliefert - interpretiert - mit SET NAMES - interpretiert
Du: utf8-Ü utf8-Ü UTF8-ü
MySQL: latin1-ü C3 83 C2 BC latin1-ü UTF8-ü
(Ich hoffe, dein Bildschirm/Browser-Viewport ist breit genug.)
Es ist nur für deine Datenintegrität erforderlich, dass du die alten Daten korrigierst. Wenn es wenige sind, mach es mit dem PMA per Hand. Sind es viele, exportiere sie Latin1-kodiert und importiere sie so wie sie sind als UTF-8.
folgende parameter sind auf utf8 eingestellt:
1.das dokument selbst, in dem ich die db-abfrage anschaue
2. die tabelle selbst ist utf8_general_ci
3. die tabellenspalte selbst ist ebenfalls utf8_general_ci
wo sonst kann noch der hund begraben sein, dass die query SET NAMES utf8 notwendig ist. wenn alles korrekt auf utf8 voreingestellt ist, müsste sie ja überflüssig sein, oder?
Ja, "wenn". Aber das ist bei dir nicht der Fall, denn du hast die System-Default-Einstellung nicht beachtet.
auf der startseite von phpMyAdmin stehen für die db folgende parameter:
MySQL-Zeichensatz: UTF-8 Unicode (utf8)
Zeichensatz / Kollation der MySQL-Verbindung: utf8_unicode_ci ==> spießt sich das vielleicht mit dem für die tabelle eingestellten utf8_general_ci??
Das ist für dich uninteressant, weil das nur die Kommunikation zwischen dem PMA und MySQL betrifft, nicht aber die Verbindungen in deinen Scripten.
hier die parameter, die man in phpMyAdmin unter "Servervariablen und -einstellungen" angezeigt bekommt:
character set client utf8
(Globaler Wert) latin1
character set connection utf8
(Globaler Wert) latin1
character set database latin1
character set filesystem binary
character set results utf8
(Globaler Wert) latin1
character set server latin1
character set system utf8
character sets dir C:\Program Files\MySQL\MySQL Server 5.0\share\charsets\ collation connection utf8_unicode_ci
(Globaler Wert) latin1_swedish_ci
collation database latin1_swedish_ci
collation server latin1_swedish_ci
Hiervon interessiert dich einzig jeweils der globale Wert, denn die anderen sind wiederum die induviduellen der PMA-Verbindung. Und siehe da, die von SET NAMES beeinflussten Werte stehen global alle auf latin1, weswegen du ein SET NAMES/mysql()_set_charset() benötigst.
Lo!