Warum konvertiert die PHP-Funktion json_encode UTF-8-Zeichenfolgen in hexadezimale Entitäten?

148

Ich habe ein PHP-Skript, das sich mit einer Vielzahl von Sprachen befasst. Leider wird json_encodejede Unicode-Ausgabe bei jedem Versuch in hexadezimale Entitäten konvertiert. Ist das das erwartete Verhalten? Gibt es eine Möglichkeit, die Ausgabe in UTF-8-Zeichen zu konvertieren?

Hier ist ein Beispiel für das, was ich sehe:

EINGANG

echo $text;

AUSGABE

База данни грешка.

EINGANG

json_encode($text);

AUSGABE

"\u0411\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u0438 \u0433\u0440\u0435\u0448\u043a\u0430."
David Jones
quelle

Antworten:

355

Seit PHP / 5.4.0 gibt es eine Option namens "JSON_UNESCAPED_UNICODE". Hör zu:

http://se2.php.net/json_encode

Deshalb sollten Sie versuchen:

json_encode( $text, JSON_UNESCAPED_UNICODE );
John Severinson
quelle
3
Aha. Vielen Dank! Ich hätte die Dokumentation genauer lesen sollen. Vielen Dank.
David Jones
3
JSON_UNESCAPED_UNICODE wurde in PHP 5.4.0 eingeführt und ist in früheren Versionen nicht verfügbar. Wenn Sie es in früheren Versionen verwenden, wird folgende Fehlermeldung angezeigt: "Warnung: json_encode () erwartet, dass Parameter 2 lang ist und die Zeichenfolge in ... angegeben ist." In der Antwort von CertaiN unten finden Sie eine 5.3-Lösung.
Octavian Naicu
Dies funktioniert auch mit dänischen Buchstaben Æ, æ, Ø, ø, Å, å Danke!
Ymerdrengene
Fantastisch, das war die Antwort, nach der ich gesucht habe!
Randomizer
2
Du hast mir gerade das Leben gerettet. VIELEN DANK.
Jon Zangitu
57

JSON_UNESCAPED_UNICODE ist in PHP Version 5.4 oder höher verfügbar.
Der folgende Code gilt für Version 5.3.

AKTUALISIERT

  • html_entity_decodeist etwas effizienter als pack+ mb_convert_encoding.
  • (*SKIP)(*FAIL)Überspringt Backslashes selbst und bestimmte Zeichen durch JSON_HEX_*Flags.

 

function raw_json_encode($input, $flags = 0) {
    $fails = implode('|', array_filter(array(
        '\\\\',
        $flags & JSON_HEX_TAG ? 'u003[CE]' : '',
        $flags & JSON_HEX_AMP ? 'u0026' : '',
        $flags & JSON_HEX_APOS ? 'u0027' : '',
        $flags & JSON_HEX_QUOT ? 'u0022' : '',
    )));
    $pattern = "/\\\\(?:(?:$fails)(*SKIP)(*FAIL)|u([0-9a-fA-F]{4}))/";
    $callback = function ($m) {
        return html_entity_decode("&#x$m[1];", ENT_QUOTES, 'UTF-8');
    };
    return preg_replace_callback($pattern, $callback, json_encode($input, $flags));
}
mpyw
quelle
1
Sollte das \ u nicht \ U sein, dh Großbuchstaben?
Malhal
4
Gute
Ich habe 3 Tage gesucht, um diese Lösung für Version 5.3 zu finden, da mein Host nicht auf 5.4 aktualisiert hat. Für mich bist du ein Lebensretter und weil ich so vollständig bin, würde ich dies lieber als akzeptierte Antwort markieren!
Laci
Fehler behoben, wenn String enthält \\ . Neuere Versionen haben eine \\ höhere Priorität als \u.
Mpyw
Dies sollte in der PHP-Bibliothek hinzugefügt werden. Gut gemacht.
Beraki
7

Sie möchten Zeichensatz und nicht entkoppelten Unicode einstellen

 header('Content-Type: application/json;charset=utf-8');  
 json_encode($data,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
Adrian Romero
quelle
4

Eine Lösung besteht darin, Daten zuerst zu codieren und dann in derselben Datei zu decodieren:

$string =json_encode($input, JSON_UNESCAPED_UNICODE) ; 
echo $decoded = html_entity_decode( $string );
Steffo Dimfelt
quelle
1

Hier ist meine kombinierte Lösung für verschiedene PHP-Versionen.

In meiner Firma arbeiten wir mit verschiedenen Servern mit verschiedenen PHP-Versionen, daher musste ich eine Lösung finden, die für alle funktioniert.

$phpVersion = substr(phpversion(), 0, 3)*1;

if($phpVersion >= 5.4) {
  $encodedValue = json_encode($value, JSON_UNESCAPED_UNICODE);
} else {
  $encodedValue = preg_replace('/\\\\u([a-f0-9]{4})/e', "iconv('UCS-4LE','UTF-8',pack('V', hexdec('U$1')))", json_encode($value));
}

Credits sollten an Marco Gasi & abu gehen . Die Lösung für PHP> = 5.4 finden Sie in den Dokumenten zu json_encode.

gaba
quelle
0

Die raw_json_encode () Funktion oben hätte löst mir nicht das Problem (aus irgendeinem Grunde, hob die Callback - Funktion einen Fehler auf meinem PHP 5.2.5 - Server).

Aber diese andere Lösung hat tatsächlich funktioniert.

https://www.experts-exchange.com/questions/28628085/json-encode-fails-with-special-characters.html

Credits sollten an Marco Gasi gehen . Ich rufe einfach seine Funktion auf, anstatt json_encode () aufzurufen:

function jsonRemoveUnicodeSequences( $json_struct )
{ 
    return preg_replace( "/\\\\u([a-f0-9]{4})/e", "iconv('UCS-4LE','UTF-8',pack('V', hexdec('U$1')))", json_encode( $json_struct ) );
}
abu
quelle
0
json_encode($text, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
Hoàng Vũ Tgtt
quelle
-2

Da hast du gefragt:

Gibt es eine Möglichkeit, die Ausgabe in UTF-8-Zeichen zu konvertieren?

Eine andere Lösung ist die Verwendung von utf8_encode .

Dadurch wird Ihre Zeichenfolge in codiert UTF-8 .

z.B

foreach ($rows as $key => $row) {
  $rows[$key]["keyword"] = utf8_encode($row["keyword"]);
}

echo json_encode($rows);
Robin Carlo Katakutan
quelle
2
Benutze das nicht. Wie auf der PHP-Dokumentseite angegeben, ist utf8_encode nur geeignet, wenn Ihre ursprüngliche Zeichenfolge ISO-8859-1 (Latin1) -codiert ist. Es ist keine Allzweckfunktion "Stellen Sie sicher, dass diese Zeichenfolge utf-8-codiert ist".
Telomer