Question

J'ai un JSON que j'ai besoin de décoder, de modifier puis de coder sans gâcher de caractères.

Si j'ai un caractère Unicode dans une chaîne JSON, il ne décodera pas. Je ne sais pas pourquoi puisque json.org dit qu'une chaîne peut contenir: any-Unicode-character- except-"-or-\-or- control-character. Mais cela ne fonctionne pas non plus dans Python.

{"Tag":"Odómetro"}

Je peux utiliser UTF8_Encode qui permettra à la chaîne d'être décodée avec JSON_DECODE, mais le personnage est mutilé dans autre chose. C'est le résultat d'un print_r du tableau de résultat. Deux personnages.

[Tag] => Odómetro

Lorsque je codez le tableau à nouveau, le personnage s'est échappé à ASCII, ce qui est correct selon la spécification JSON:

"Tag"=>"Od\u00f3metro"

Y a-t-il un moyen de ne pas escaller cela? JSON_ENCODE ne donne pas une telle option, UTF8_Encode ne semble pas fonctionner non plus.

Éditer Je vois qu'il existe une option UNESCAPED_UNICODE pour json_encode. Cependant, cela ne fonctionne pas comme prévu. Oh putain, ce n'est que sur PHP 5.4. Je vais devoir utiliser un regex, car je n'ai que 5.3.

$json = json_encode($array, JSON_UNESCAPED_UNICODE);
Warning: json_encode() expects parameter 2 to be long, string ...
Était-ce utile?

La solution

À en juger par tout ce que vous avez dit, il semble que l'original Odómetro La chaîne avec laquelle vous avez affaire est encodé avec ISO 8859-1, pas UTF-8.

Voici pourquoi je pense que oui:

  • json_encode PRODUIT PRODUITE SORTIE APRÈS APRÈS avoir parcouru la chaîne d'entrée à travers utf8_encode, qui convertit de l'ISO 8859-1 à UTF-8.
  • Vous avez dit que vous aviez une sortie "mutilée" lorsque vous utilisez print_r après avoir fait utf8_encode, mais la sortie mutilée que vous avez obtenue est en fait exactement ce qui se passerait en essayant d'analyser le texte UTF-8 en tant qu'ISO 8859-1 (Ó est \x63\xb3 Dans UTF-8, mais cette séquence est ó dans ISO 8859-1.
  • Ton htmlentities La solution de hackaround a fonctionné. htmlentities doit savoir quel est le codage de la chaîne d'entrée pour fonctionner correctement. Si vous n'en spécifiez pas un, il suppose ISO 8859-1. (html_entity_decode, confus, par défaut vers UTF-8, donc votre méthode a eu pour effet de convertir de l'ISO 8859-1 à UTF-8.)
  • Vous avez dit que vous aviez le même problème à Python, ce qui semble exclure PHP d'être le problème.

Php utilisera le \uXXXX s'échapper, mais comme vous l'avez noté, c'est un JSON valide.

Donc, il semble que vous deviez configurer votre connexion à Postgres afin qu'il vous donne des chaînes UTF-8. Le manuel PHP indique que vous feriez cela en ajoutant options='--client_encoding=UTF8' à la chaîne de connexion. Il est également possible que les données actuellement stockées dans la base de données soient dans le mauvais codage. (Vous pouvez simplement utiliser utf8_encode, mais cela ne prendra en charge que les caractères qui font partie de l'ISO 8859-1).

Enfin, comme l'a noté une autre réponse, vous devez vous assurer que vous déclarez le charme approprié, avec un en-tête HTTP ou autrement (bien sûr, ce problème particulier pourrait être un artefact de l'environnement où vous avez fait votre print_r essai).

Autres conseils

J'ai trouvé le moyen de résoudre ce problème ... J'espère que cela peut vous aider.

json_encode($data,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);

JSON_UNESCAPED_UNICODE a été ajouté dans PHP 5.4, il semble donc que vous ayez besoin de mettre à niveau votre version de PHP pour en profiter. 5.4 n'est pas encore sorti! :(

Il y a un 5.4 candidat à libération alpha sur QA cependant si vous voulez jouer sur votre machine de développement.

Une manière piratage de faire JSON_UNESCAPED_UNICODE dans PHP 5.3. Vraiment déçu par le support PHP JSON. Peut-être que cela aidera quelqu'un d'autre.

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

Essayez de définir le utf-8 Encodage dans votre page:

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

Cela fonctionne pour moi:

$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

Vous étiez proche, utilisez simplement UTF8_DECODE.

Essayez d'utiliser:

utf8_decode() and utf8_encode

Pour encoder un tableau contenant des caractères spéciaux, ISO 8859-1 à UTF8. (Si utf8_encode & utf8_decode n'est pas ce qui fonctionne pour vous, cela pourrait être une option)

Tout ce qui est dans ISO-8859-1 doit être converti en UTF8:

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

Encode doit fonctionner après cela:

$encoded_data = json_encode($data);

Convertir UTF-8 en et depuis ISO 8859-1

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top