• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

[HOW-TO/TUTORIAL] MySQL und UTF8-Abfragen

dertypdernixkan

New member
Moinsen

ich bin eben über ein seltsames Verhalten von MySQL in Verbindung mit Ajax und UTF8 gestoßen, was ich mir gleich mal zum Anlass nehmen möchte euch darüber zu berichten. Auch für diejenigen, die mal auf diese Problem stoßen werden.

Folgendes Szenario:

Ich habt eine Seite bei der Content über die URI abgerufen wird, normal machen es die meisten über IDs, in meinem Fall wird der Username ausgelesen. Solange der Username keine Umlaute enthält ist alles prima, aber wehe wenn doch!

Die Seite ist via Meta-Tag und Header-Befehl auf UTF8 gestellt, die Datenbank ebenfalls, leider kam bei der Überprüfung des Usernamen "Arschmän" folgendes raus:

arschm%c3%a4n

Via

PHP:
urldecode

wurde daraus ganz schnell wieder "arschmän". Schön und gut, gefunden wurde er in der Datenbank trotzdem nicht. Also habe ich den Fehler gesucht und auch recht flott gefunden, ich musste den Default Client Character Set mitteilen, und das geht so:

Meine db_conig.php

PHP:
$mysqli = new mysqli(host, benutzer, passwort, datenbank);

if ($mysqli->connect_error) {
	include $_SERVER["DOCUMENT_ROOT"]."/fvs/mistake.html";	exit();
}

# das ist der entsprechende Zusatz
if (!$mysqli->set_charset("utf8")) {
	printf("Das Charset \"UTF8\" konnte nicht gesetzt werden. Es können Fehler bei der Datenbankabfrage auftreten!");
}

Super! Jetzt wird auch der User "Arschmän" aus der Datenbank geholt!

Wenn da nicht noch der Ajax-Request wäre. Der hat mich fast zur Verzweiflung getrieben! Der sah folgendermaßen aus (den JS-Teil lasse ich einfach weg, der ist dabei unwichtig!)

PHP:
$stmt = $mysqli->prepare("SELECT `mgb` FROM `xxx` WHERE `id` = ? LIMIT 1");
$stmt->bind_param("i", $dbi);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($b_mgb);
$stmt->fetch();
$stmt->close();

$b_mgb = make_clean($b_mgb, $mysqli);
$b_mgb = change($b_mgb, $mysqli);
$b_mgb = bb_code($b_mgb, "", $mysqli);
$b_mgb = utf8_encode($b_mgb);

$reback = array("r" => $b_mgb, "n" => $topline, "s" => $scroll);
echo json_encode($reback, JSON_HEX_TAG);

Der hat nämlich aus den Umlauten wieder sinnlose Zeichen gemacht die kein Alphabet der Welt kennt. Ich habe überlegt und überlegt und ... dabei war die Lösung doch relativ simpel.

Am Ende des Umwandlungsblocks arbeite ich mit utf8-encode, ohne diesen kam die Fehlermeldung "Uncaught SyntaxError: Unexpected end of input". Kennen wir alle, wollen wir aber nicht lesen!

Des Rätsels Lösung: vorher erstmal decodieren bevor man codiert!

PHP:
$stmt = $mysqli->prepare("SELECT `mgb` FROM `xxx` WHERE `id` = ? LIMIT 1");
$stmt->bind_param("i", $dbi);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($b_mgb);
$stmt->fetch();
$stmt->close();

$b_mgb = utf8_decode($b_mgb); // diese Zeile hinzugefügt
$b_mgb = make_clean($b_mgb, $mysqli);
$b_mgb = change($b_mgb, $mysqli);
$b_mgb = bb_code($b_mgb, "", $mysqli);
$b_mgb = utf8_encode($b_mgb);

$reback = array("r" => $b_mgb, "n" => $topline, "s" => $scroll);
echo json_encode($reback, JSON_HEX_TAG);

Und nun werden auch die Umlaute wieder korrekt angeziegt! :D
 
Zuletzt bearbeitet:
ich bin eben über ein seltsames Verhalten von MySQL in Verbindung mit Ajax und UTF8 gestoßen
wenn alles mit utf8 arbeitet und bei jedem contextwechsel vernünftig escapest, hast du keine probleme

Die Seite ist via Meta-Tag und Header-Befehl auf UTF8 gestellt, die Datenbank ebenfalls, leider kam bei der Überprüfung des Usernamen "Arschmän" folgendes raus:

arschm%c3%a4n
klar, auf clientseite richtig escaped für den contextwechsel und auf php-seite musst du en dann decodieren. um es in die datenbank einzutragen nutzt du dann sicher real_escape_string

Schön und gut, gefunden wurde er in der Datenbank trotzdem nicht. Also habe ich den Fehler gesucht und auch recht flott gefunden, ich musste den Default Client Character Set mitteilen, und das geht so:
dann solltest du mal nachsehen, ob dein default character set in mysql tatsächlich auf utf8 gesetzt ist

Am Ende des Umwandlungsblocks arbeite ich mit utf8-encode, ohne diesen kam die Fehlermeldung "Uncaught SyntaxError: Unexpected end of input". Kennen wir alle, wollen wir aber nicht lesen!
??? nee, kenne ich nicht

Des Rätsels Lösung: vorher erstmal decodieren bevor man codiert!
die lösung ist einen utf8 codierten string nach iso8859 zu wandeln um diesen dann wieder in einen utf8 codierten string zu konvertieren?
das klingt komisch und nicht nach einer lösung
 
Zurück
Oben