Domanda

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

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

{"Tag":"Odómetro"}

Posso usare utf8_encode che consentirà di decodificare la stringa con json_decode, tuttavia il carattere viene alterato 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 carattere è sfuggito ad ascii, che è corretto secondo le specifiche json:

"Tag"=>"Od\u00f3metro"

C'è un modo per annullare l'escape? json_encode non fornisce tale opzione, neanche utf8_encode sembra funzionare.

Modifica Vedo che è presente un'opzione unescaped_unicode per json_encode. Tuttavia non funziona come previsto. Oh dannazione, è solo su php 5.4. Dovrò usare alcune espressioni regolari poiché ho solo 5.3.

$json = json_encode($array, JSON_UNESCAPED_UNICODE);
Warning: json_encode() expects parameter 2 to be long, string ...
È stato utile?

Soluzione

A giudicare da tutto ciò che hai detto, sembra che la stringa Odómetro originale con cui hai a che fare sia 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 tramite utf8_encode, che converte da ISO 8859-1 a UTF-8.
  • Hai detto che hai "alterato" l'output quando usi print_r dopo aver eseguito utf8_encode, ma l'output alterato che hai è in realtà esattamente ciò che accadrebbe provando ad 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 ha bisogno di sapere quale sia la codifica della stringa di input per funzionare correttamente. Se non ne specifichi uno, assume ISO 8859-1. (html_entity_decode, in modo confuso, il valore predefinito è UTF-8, quindi il tuo metodo ha avuto l'effetto di convertire da ISO 8859-1 a UTF-8.)
  • Hai affermato di avere lo stesso problema in Python, il che sembrerebbe escludere PHP dall'essere il problema.

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

Quindi, sembra che tu debba configurare la tua connessione a Postgres in modo che ti dia le stringhe UTF-8. Il manuale PHP indica che lo faresti aggiungendo options='--client_encoding=UTF8' alla stringa di connessione. C'è anche la possibilità che i dati attualmente archiviati nel database siano nella codifica sbagliata. (Potresti semplicemente usare utf8_encode, ma questo supporterà solo i caratteri che fanno parte di ISO 8859-1).

Infine, come ha 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 fatto il tuo test print_r).

Altri suggerimenti

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

json_encode($data,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);

JSON_UNESCAPED_UNICODE è stato aggiunto in PHP 5.4 quindi sembra che sia necessario aggiornare la versione di PHP per trarne vantaggio.La versione 5.4 non è ancora stata rilasciata!:(

Esiste un candidato alla versione 5.4 alpha su QA, anche se vuoi giocare sulla tua macchina di sviluppo.

Un modo hacky di eseguire JSON_UNESCAPED_UNICODE in PHP 5.3.Davvero deluso dal supporto 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);

prova a impostare la codifica utf-8 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'};
$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, usa solo utf8_decode.

Prova a utilizzare:

utf8_decode() and utf8_encode

Per codificare un array che contiene caratteri speciali, da ISO 8859-1 a UTF8.(Se utf8_encode & 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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top