web-dev-qa-db-fra.com

Pourquoi le PHP La fonction json_encode convertit les chaînes UTF-8 en entités hexadécimales?

J'ai un script PHP qui traite une grande variété de langues. Malheureusement, chaque fois que j'essaie d'utiliser json_encode, toute sortie Unicode est convertie en entités hexadécimales. Est-ce le comportement attendu? Est-il possible de convertir la sortie en caractères UTF-8?

Voici un exemple de ce que je vois:

CONTRIBUTION

echo $text;

SORTIE

База данни грешка.

CONTRIBUTION

json_encode($text);

SORTIE

"\u0411\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u0438 \u0433\u0440\u0435\u0448\u043a\u0430."
107
David Jones

Depuis PHP/5.4.0, il existe une option appelée "JSON_UNESCAPED_UNICODE". Vérifiez-le:

http://se2.php.net/json_encode

Par conséquent, vous devriez essayer:

json_encode( $text, JSON_UNESCAPED_UNICODE );
249
John Severinson

JSON_UNESCAPED_UNICODE est disponible sur PHP version 5.4 ou ultérieure.
Le code suivant concerne la version 5.3.

MIS À JOUR

  • html_entity_decode est un peu plus efficace que pack + mb_convert_encoding.
  • (*SKIP)(*FAIL) ignore les barres obliques inverses et les caractères spécifiés par les indicateurs JSON_HEX_*.

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

Une solution consiste à d'abord encoder les données, puis à les décoder dans le même fichier:

$string =json_encode($input, JSON_UNESCAPED_UNICODE) ; 
echo $decoded = html_entity_decode( $string );
2
Steffo Dimfelt

Voici ma solution combinée pour diverses versions de PHP.

Dans mon entreprise, nous travaillons avec différents serveurs avec différentes versions de PHP. J'ai donc dû trouver une solution qui fonctionne pour tous.

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

Les crédits devraient aller à Marco Gasi & abu . La solution pour PHP> = 5.4 est fournie dans la documentation json_encode.

1
gaba

Vous aimez définir un jeu de caractères et unicode non échappé

 header('Content-Type: application/json;charset=utf-8');  
 json_encode($data,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
1
Adrian Romero

La fonction raw_json_encode () above n'a pas résolu le problème (pour une raison quelconque, la fonction de rappel a généré une erreur sur mon serveur PHP 5.2.5).

Mais cette autre solution a effectivement fonctionné.

https://www.experts-exchange.com/questions/28628085/json-encode-fails-with-special-characters.html

Les crédits devraient aller à Marco Gasi . Je viens d'appeler sa fonction au lieu d'appeler json_encode ():

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 ) );
}
0
abu
json_encode($text, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
0
Hoàng Vũ Tgtt