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."

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 );

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));
}

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);

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 );

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.


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 ) );
}


-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);

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.