dedlfix: mysql real escape wandelt nicht in utf8 um

Beitrag lesen

Hi!

Wenn ich Sonderzeichen in der URL habe und die Variablen durch mysql_real_escape_string() schicke, werden trotzdem nicht-UTF Zeichen in die Datenbank geschrieben. Ich dachte,die Eingaben werden automatisch in UTF8 umgewandelt...

Nein. Diese Funktion beachtet nur eine mit mysql_set_charset() eingestellte Kodierung beim Interpretieren der übergebenen Daten. Allerdings sind alle behandelten Zeichen im ASCII-Bereich und damit ist die eingestellte Kodierung (im Falle von ISO-8859-x und UTF-8) nicht mehr wichtig.

Eine Zeichenumkodierung findet potentiell nur auf dem MySQL-Server selbst statt, die mysql(i)_*-Funktionen machen in der Hinsicht nichts. Welche Kodierung der Server zu erwarten hat, kann man ihm mit der erwähnten Funktion mysql(i)_set_charset() oder einem SET-NAMES-Statement mitteilen.

Wenn ich Text per POST schicke, funktioniert das mit mysql_real_escape. Aber wenn ich zum Beispiel ?user=Halöle aufrufe, dann wird der UMlaut in der Datenbank nicht richtig gespeichert.

Das ist ein anderes Problem und hat nichts mit dem DBMS zu tun, sondern mit der Kommunikation zwischen Browser und Webserver. Wenn ein Formular abgesendet wird, orientiert sich der Browser bei der Kodierung der Zeichen an der Kodierung der Seite, in der das Formular enthalten war. Mit dem Attribut accept-charset des form-Elements kann man gezielt festlegen, welche Kodierung man wünscht, aber das behandeln nicht alle Browser wie vorgesehen.

Wenn Daten in die URL direkt eingegeben werden, hat der Browser keinen Anhaltspunkt, welche Kodierung er verwenden soll. Er hat keine Response vorliegen, die irgendeinen Bezug zu der Eingabe hat, an der er sich orientieren könnte. Er kann auch nicht vorab den Server befragen, welche Kodierung er zu dieser URL gern hätte, denn die Eingabe gehört schließlich zur URL und eine andere Zeichenkodierung ergibt eine andere URL. Es gibt auch keinen Standard, der da was regelt. Das heißt, du musst theoretisch mit allen Zeichenkodierungen rechnen.

Ich habe das jetzt so gelöst, dass alle Daten, die per URL kommen und Sonderzeichen enthalten können anschließend noch utf8_encode() durchlaufen.
Aber ist das so alles korrekt oder habe ich irgendwo ein Konzeptionsfehler?

Nein, das ist in einigen Fällen korrekt, aber nicht für alle Browser und alle Konfigurationen. Es ist auch nicht zweifelsfrei möglich, aus einem String die Kodierung abzuleiten. Lediglich einige Indizien kann man mit einer Restfehlerquote auswerten.

  • Enthält der String Bytes oberhalb von 0x7F und ergeben diese gültige UTF-8-Sequenzen, so liegt vermutlich UTF-8 vor.
  • Ergeben diese Bytes keine gültigen UTF-8-Sequenzen, liegt anzunehmenderweise ISO-8859 vor. Bei einem Publikum vorzugsweise aus dem westlichen Kulturkreis wird das dann ISO-8859-1 und seltener -15 sein. Auch Windows-1252 kommt in Frage, was eine Erweiterung von ISO-8859-1 darstellt. Da Latin1 im MySQL-Server aber effektiv Windows-1252 ist, spielt der Unterschied keine Rolle.
  • Bei Zeichen unterhalb von 0x80 ist es ASCII und damit sowohl gültiges UTF-8 als auch ISO-8859-1/Win-1252.

Lo!