PHP-Dekodierung und JSON-Kodierung mit Unicode-Zeichen
-
29-10-2019 - |
Frage
Ich habe JSON, das ich dekodieren, ändern und dann kodieren muss, ohne irgendwelche Zeichen durcheinander zu bringen.
Wenn ich ein Unicode-Zeichen in einer JSON-Zeichenfolge habe, wird es nicht dekodiert.Ich bin mir nicht sicher, warum, da json.org sagt, dass eine Zeichenfolge Folgendes enthalten kann: any-Unicode-character- except-"-or-\-or- control-character
.Aber es funktioniert auch nicht in Python.
{"Tag":"Odómetro"}
Ich kann utf8_encode verwenden, wodurch die Zeichenfolge mit json_decode dekodiert werden kann, das Zeichen wird jedoch in etwas anderes verstümmelt.Dies ist das Ergebnis eines print_r des Ergebnisarrays.Zwei Charaktere.
[Tag] => Odómetro
Wenn ich das Array erneut codiere, wird das Zeichen in ASCII umgeschrieben, was gemäß der JSON-Spezifikation korrekt ist:
"Tag"=>"Od\u00f3metro"
Gibt es eine Möglichkeit, dem zu entkommen?json_encode bietet keine solche Option, utf8_encode scheint auch nicht zu funktionieren.
Bearbeiten Ich sehe, dass es eine unescaped_unicode-Option für json_encode gibt.Allerdings funktioniert es nicht wie erwartet.Oh verdammt, es ist nur auf PHP 5.4.Ich muss etwas Regex verwenden, da ich nur 5.3 habe.
$json = json_encode($array, JSON_UNESCAPED_UNICODE);
Warning: json_encode() expects parameter 2 to be long, string ...
Lösung
Nach allem, was Sie gesagt haben, scheint es das Original zu sein Odómetro
Die Zeichenfolge, mit der Sie es zu tun haben, ist mit ISO 8859-1 und nicht mit UTF-8 codiert.
Hier ist der Grund, warum ich das denke:
json_encode
erzeugte eine analysierbare Ausgabe, nachdem Sie die Eingabezeichenfolge durchlaufen habenutf8_encode
, das von ISO 8859-1 nach UTF-8 konvertiert.- Sie haben gesagt, dass Sie bei der Verwendung eine „verstümmelte“ Ausgabe erhalten haben
print_r
danachutf8_encode
, aber die verstümmelte Ausgabe, die Sie erhalten haben, ist tatsächlich genau das, was passieren würde, wenn Sie versuchen würden, UTF-8-Text als ISO 8859-1 (ó) zu analysieren\x63\xb3
in UTF-8, aber diese Sequenz istó
in ISO 8859-1. - Dein
htmlentities
Hackaround-Lösung hat funktioniert.htmlentities
Um korrekt zu funktionieren, muss die Codierung der Eingabezeichenfolge bekannt sein.Wenn Sie keines angeben, wird ISO 8859-1 angenommen.(html_entity_decode
, Verwirrenderweise ist die Standardeinstellung UTF-8, sodass Ihre Methode eine Konvertierung von ISO 8859-1 nach UTF-8 zur Folge hatte.) - Sie sagten, Sie hätten das gleiche Problem in Python, was PHP als Problem auszuschließen scheint.
PHP wird das verwenden \uXXXX
Escapezeichen, aber wie Sie bemerkt haben, ist dies gültiges JSON.
Es sieht also so aus, als müssten Sie Ihre Verbindung zu Postgres so konfigurieren, dass Sie UTF-8-Zeichenfolgen erhalten.Das PHP-Handbuch gibt an, dass Sie dies durch Anhängen tun würden options='--client_encoding=UTF8'
zur Verbindungszeichenfolge.Es besteht auch die Möglichkeit, dass die derzeit in der Datenbank gespeicherten Daten in der falschen Codierung vorliegen.(Sie könnten einfach verwenden utf8_encode
, aber dies unterstützt nur Zeichen, die Teil von ISO 8859-1 sind).
Schließlich müssen Sie, wie in einer anderen Antwort erwähnt, sicherstellen, dass Sie den richtigen Zeichensatz deklarieren, mit einem HTTP-Header oder auf andere Weise (natürlich könnte dieses spezielle Problem nur ein Artefakt der Umgebung gewesen sein, in der Sie es getan haben). print_r
testen).
Andere Tipps
Ich habe folgenden Weg gefunden, um dieses Problem zu beheben ... Ich hoffe, dies kann Ihnen helfen.
json_encode($data,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
JSON_UNESCAPED_UNICODE
wurde in PHP 5.4 hinzugefügt, sodass Sie anscheinend Ihre PHP-Version aktualisieren müssen, um sie nutzen zu können.5.4 ist allerdings noch nicht veröffentlicht!:(
Es gibt einen 5.4 Alpha Release Candidate für die Qualitätssicherung, wenn Sie auf Ihrem Entwicklungscomputer spielen möchten.
Eine hackige Methode, um JSON_UNESCAPED_UNICODE in PHP 5.3 auszuführen.Wirklich enttäuscht von der Unterstützung von PHP JSON.Vielleicht hilft das jemand anderem.
$array = some_json();
// Encode all string children in the array to html entities.
array_walk_recursive($array, function(&$item, $key) {
if(is_string($item)) {
$item = htmlentities($item);
}
});
$json = json_encode($array);
// Decode the html entities and end up with unicode again.
$json = html_entity_decode($rson);
Versuchen Sie, die utf-8
-Codierung auf Ihrer Seite festzulegen:
header('content-type:text/html;charset=utf-8');
das funktioniert bei mir:
$arr = array('tag' => 'Odómetro');
$encoded = json_encode($arr);
$decoded = json_decode($encoded);
echo $decoded->{'tag'};
$json = array('tag' => 'Odómetro'); // Original array
$json = json_encode($json); // {"Tag":"Od\u00f3metro"}
$json = json_decode($json); // Od\u00f3metro becomes Odómetro
echo $json->{'tag'}; // Odómetro
echo utf8_decode($json->{'tag'}); // Odómetro
Sie waren nah dran, verwenden Sie einfach utf8_decode.
Versuchen Sie Folgendes:
utf8_decode() and utf8_encode
Um ein Array zu codieren, das Sonderzeichen enthält, ISO 8859-1 bis UTF8.(Wenn utf8_encode & utf8_decode nicht für Sie geeignet ist, ist dies möglicherweise eine Option.)
Alles, was in ISO-8859-1 enthalten ist, sollte in UTF8 konvertiert werden:
$utf8 = utf8_encode('이 감사의 마음을 전합니다!'); //contains UTF8 & ISO 8859-1 characters;
$iso88591 = mb_convert_encoding($utf8, 'ISO-8859-1', 'UTF-8');
$data = $iso88591;
Die Codierung sollte danach funktionieren:
$encoded_data = json_encode($data);