it-swarm.it

PHP decodifica e codifica json con caratteri unicode

Ho un po 'di json che devo decodificare, modificare e quindi codificare senza incasinare alcun personaggio.

Se ho un carattere unicode in una stringa JSON, non verrà decodificato. Non sono sicuro del motivo per cui poiché json.org dice che una stringa può contenere: any-Unicode-character- except-"-or-\-or- control-character. Ma non funziona in python.

{"Tag":"Odómetro"}

Posso usare utf8_encode che consentirà la decodifica della stringa con json_decode, tuttavia il personaggio viene trasformato in qualcos'altro. Questo è il risultato di un print_r dell'array dei risultati. Due personaggi.

[Tag] => Odómetro

Quando codifico di nuovo l'array, il personaggio è fuggito su ascii, che è corretto secondo le specifiche json:

"Tag"=>"Od\u00f3metro"

C'è un modo per sfuggire a questo? json_encode non offre tale opzione, neanche utf8_encode sembra funzionare.

Modifica Vedo che esiste un'opzione unescaped_unicode per json_encode. Tuttavia non funziona come previsto. Oh dannazione, è solo su PHP 5.4. Dovrò usare un po 'di regex come ho solo 5.3.

$json = json_encode($array, JSON_UNESCAPED_UNICODE);
Warning: json_encode() expects parameter 2 to be long, string ...
33
Keyo

A giudicare da tutto quello che hai detto, sembra che l'originale Odómetro la stringa con cui hai a che fare è codificata con ISO 8859-1, non UTF-8.

Ecco perché la penso così:

  • json_encode ha prodotto un output analizzabile dopo aver eseguito la stringa di input attraverso utf8_encode, che converte da ISO 8859-1 a UTF-8.
  • Hai detto di avere un output "alterato" quando si utilizza print_r dopo aver eseguito utf8_encode, ma l'output distorto che hai è in realtà esattamente ciò che accadrebbe cercando di analizzare il testo UTF-8 come ISO 8859-1 (ó è \x63\xb3 in UTF-8, ma quella sequenza è ó in ISO 8859-1.
  • La tua soluzione di hackaround htmlentities ha funzionato. htmlentities deve sapere quale funziona correttamente la codifica della stringa di input. Se non ne specifichi uno, assume ISO 8859-1. (html_entity_decode, in modo confuso, per impostazione predefinita è UTF-8, quindi il tuo metodo ha avuto l'effetto di convertire da ISO 8859-1 a UTF-8.)
  • Hai detto di avere lo stesso problema in Python, che sembrerebbe escludere PHP dal problema.

PHP utilizzerà il \uXXXX escape, ma come hai notato, questo è JSON valido.

Quindi, sembra che tu debba configurare la tua connessione a Postgres in modo che ti dia stringhe UTF-8. Il PHP indica che lo faresti aggiungendo options='--client_encoding=UTF8' alla stringa di connessione. Esiste anche la possibilità che i dati attualmente memorizzati nel database abbiano una codifica errata. (Potresti semplicemente usare utf8_encode, ma supporterà solo i caratteri che fanno parte della ISO 8859-1).

Infine, come notato un'altra risposta, devi assicurarti di dichiarare il set di caratteri corretto, con un'intestazione HTTP o altro (ovviamente, questo particolare problema potrebbe essere stato solo un artefatto dell'ambiente in cui hai eseguito il tuo print_r test).

14
John Flatness

Ho trovato il modo seguente per risolvere questo problema ... Spero che questo possa aiutarti.

json_encode($data,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
31
Sunny S.M

JSON_UNESCAPED_UNICODE è stato aggiunto in PHP 5.4, quindi sembra che tu abbia bisogno di aggiornare la tua versione di PHP per sfruttarlo. 5.4 non è ancora stato rilasciato anche se! :(

C'è un 5.4 rilascio candidato alfa sul QA se vuoi giocare sulla tua macchina di sviluppo.

16
Treffynnon

Un modo bizzarro di fare JSON_UNESCAPED_UNICODE in PHP 5.3. Davvero deluso da PHP json. Forse questo aiuterà qualcun altro.

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

prova a impostare utf-8 codifica nella tua pagina:

header('content-type:text/html;charset=utf-8');

questo funziona per me:

$arr = array('tag' => 'Odómetro');
$encoded = json_encode($arr);
$decoded = json_decode($encoded);
echo $decoded->{'tag'};
4
The Mask
$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

Eri vicino, basta usare utf8_decode.

4
Fernando R.

Prova a usare:

utf8_decode() and utf8_encode
3
Jonathan Edgardo

Per codificare un array che contiene caratteri speciali, da ISO 8859-1 a UTF8. (Se utf8_encode e utf8_decode non è ciò che funziona per te, questa potrebbe essere un'opzione)

Tutto ciò che è in ISO-8859-1 dovrebbe essere convertito in UTF8:

$utf8 = utf8_encode('이 감사의 마음을 전합니다!'); //contains UTF8 & ISO 8859-1 characters;    
$iso88591 = mb_convert_encoding($utf8, 'ISO-8859-1', 'UTF-8');
$data = $iso88591;

La codifica dovrebbe funzionare dopo questo:

$encoded_data = json_encode($data);

Converti UTF-8 in e da ISO 8859-1

0
Navaneeth Mohan