echo $begrüßung;
[...] Vermutlich, wie so oft, ein vergessenes SET NAMES nach dem Aufbau der Datenbankverbindung.
könntest Du darauf bitte noch etwes näher eingehen?
Bin ich doch schon so oft. Steht alles im Archiv. :-)
Wenn du als Client dem MySQL-Server nicht mitteilst, welche Kodierung ihr miteinander sprechen wollt, dann nimmt er (s)einen Default-Wert. Genauer gesagt sind es allein für die Verbindung 3 Konfigurationswerte, die man mit SET NAMES einstellt. Reicht es, wenn ich dich da zunächst mal ins MySQL-Handbuch schicke, Kapitel Connection Character Sets and Collations? (Den Rest des Kapitels Character Set Support zu lesen, ist übrigens auch nicht verkehrt.)
SET NAMES ist eigentlich auch nur ein Notbehelf, aber einer, der mit den hierzulande üblichen Kodierungen funktioniert. Denn SET NAMES bewirkt zwar, dass der MySQL-Server nun von der angegebenen Kodierung ausgeht, aber diese Einstellung geht nicht wirklich in die Metadaten der aktuellen Client-Verbindung ein. Ein mysql_real_escape_string(), das diese Client-Verbindungskodierung berücksichtigt, bleibt weiterhin auf dem Wert stehen, der zum Verbindungsaufbau (per Defaultwert) eingestellt war. Der korrekte Weg wäre mysqli_set_charset(). Zu dieser Funktion gibt es jedoch kein Pendant unter den "Nicht-i-mysql-Funktionen". (Wieder ein Grund, wenn auch ein ganz kleiner, auf die MySQL Improved Extension umzusteigen.) Siehe dazu MySQL-API-Beschreibung zu mysql_real_escape_string().
Warum kann dennoch SET NAMES und PHPs mysql_(real_)escape_string() verwendet werden? Die von beiden Funktionen berücksichtigten Zeichen sind in allen Kodierungen der ISO-8859-Reihe und in UTF-8 mit eineindeutigen Bytewerten versehen. Die Zeichen liegen alle im reinen/7-Bit ASCII-Bereich, sind also für alle ISO-8859-X gleich, und alle Nicht-ASCII-Zeichen haben in UTF-8 Byte-Werte jenseits von ASCII. Unter den asiatischen Kodierungen gibt es jedoch mindestens eine, bei der auch unter den mehrbyte-kodierten Zeichen Bytewerte kleiner als 0x80 vorkommen. Doch die verwendet hierzulande ja k(aum )einer.
Ich hab das mal vor geraumer Zeit mit einem nicht dokumentierten Versuch probiert und konnte das beschriebene Verhalten nachvollziehen.
Auch die automatische Umwandlung von Codierungen an der Datenbank erscheint mir noch sehr nebulös. Einen als utf-8 gespeicherten String kann ich doch nicht (nicht immer) als ISO 8859-1 wiedergeben.
Das ist richtig. Dessen muss man sich immer bewusst sein, dass man Werte einer Kodierung nur dann verlustfrei in eine andere Kodierung umkodieren kann, wenn die Werte mit der Zielkodierung darstellbar sind. MySQL kann da auch nicht zaubern, und das fragliche Zeichen wird in dem Fall zu einem Fragezeichen.
Wie ist das also gemeint, dass die Datenbank in der Codierung der Verbindung sendet?
Wenn du mit MySQL in der Kodierung X sprichst, die Felder (oder auch nur eins, oder auch jedes einzelne anders) aber auf Kodierung Y eingestellt sind, was soll MySQL dann machen? Es bleibt ihm nicht viel anderes übrig als eine Umkodierung vorzunehmen, will es nicht zu jedem Einzeldatum die Kodierung mit abspeichern.
Zum Thema Umkodierungen habe ich mal eine Versuchsreihe dokumentiert: </archiv/2007/7/t157019/#m1021663>
echo "$verabschiedung $name";