php - json_unescaped_unicode - json_encode() non utf-8 strings?
php json_encode utf8 (8)
¿Hay alguna manera de hacer que json_encode () funcione y muestre estos caracteres en lugar de tener que usar utf8_encode () en todas mis cadenas y termine con cosas como "/ u0082"?
Si tiene una cadena codificada ANSI, usar utf8_encode()
es la función incorrecta para resolver esto. Primero debe convertirlo correctamente de ANSI a UTF-8. Eso ciertamente reducirá el número de secuencias de escape de Unicode como /u0082
de la salida de json, pero técnicamente estas secuencias son válidas para json , no debes /u0082
.
Convertir ANSI a UTF-8 con PHP
json_encode
funciona solo con cadenas codificadas en UTF-8
. Si necesita crear un json
válido con éxito a partir de una cadena codificada ANSI
, primero debe volver a codificarlo / convertirlo a UTF-8
. Entonces json_encode
funcionará como se documenta.
Para convertir una codificación de ANSI
(más correctamente, asumo que tiene una cadena codificada de Windows-1252
, que es popular pero erróneamente conocida como ANSI
) a UTF-8
puede usar la función mb_convert_encoding()
:
$str = mb_convert_encoding($str, "UTF-8", "Windows-1252");
Otra función en PHP que puede convertir la codificación / conjunto de caracteres de una cadena se llama iconv
basada en libiconv . Puedes usarlo también:
$str = iconv("CP1252", "UTF-8", $str);
Nota sobre utf8_encode ()
utf8_encode()
solo funciona para Latin-1
, no para ANSI
. Así que destruirás parte de tus personajes dentro de esa cadena cuando la ejecutes a través de esa función.
Relacionados: ¿Qué es el formato ANSI?
Para obtener un control más detallado de lo que json_encode()
, consulte la lista de constantes predeterminadas (dependiendo de la versión de PHP, incluido PHP 5.4, algunas constantes permanecen sin documentar y están disponibles en el código fuente hasta el momento).
Cambio de la codificación de una matriz / iterativamente (comentario de PDO)
Como escribió en un comentario que tiene problemas para aplicar la función a una matriz, aquí hay un ejemplo de código. Siempre es necesario cambiar primero la codificación antes de usar json_encode
. Eso es solo una operación de matriz estándar, para el caso más simple de pdo::fetch()
una iteración de foreach
:
while($row = $q->fetch(PDO::FETCH_ASSOC))
{
foreach($row as &$value)
{
$value = mb_convert_encoding($value, "UTF-8", "Windows-1252");
}
unset($value); # safety: remove reference
$items[] = array_map(''utf8_encode'', $row );
}
Así que tengo una serie de cadenas, y todas las cadenas están usando la codificación ANSI predeterminada del sistema y fueron extraídas de una base de datos SQL. Por lo tanto, hay 256 valores diferentes de bytes de caracteres posibles (codificación de un solo byte). ¿Hay alguna manera de hacer que json_encode () funcione y muestre estos caracteres en lugar de tener que usar utf8_encode () en todas mis cadenas y termine con cosas como "/ u0082"?
¿O es que el estándar para json?
El estándar JSON ENFORCE la codificación Unicode . Desde RFC4627 :
3. Encoding
JSON text SHALL be encoded in Unicode. The default encoding is
UTF-8.
Since the first two characters of a JSON text will always be ASCII
characters [RFC0020], it is possible to determine whether an octet
stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking
at the pattern of nulls in the first four octets.
00 00 00 xx UTF-32BE
00 xx 00 xx UTF-16BE
xx 00 00 00 UTF-32LE
xx 00 xx 00 UTF-16LE
xx xx xx xx UTF-8
Por lo tanto, en el sentido más estricto, JSON codificado ANSI no sería JSON válido; esta es la razón por la que PHP aplica la codificación Unicode cuando se utiliza json_encode()
.
En cuanto a "ANSI predeterminado", estoy bastante seguro de que sus cadenas están codificadas en Windows-1252. Se le conoce incorrectamente como ANSI.
Encontré la siguiente respuesta para un problema análogo con una matriz anidada no codificada en utf-8 que tuve que codificar con json:
$inputArray = array(
''a''=>''First item - à'',
''c''=>''Third item - é''
);
$inputArray[''b'']= array (
''a''=>''First subitem - ù'',
''b''=>''Second subitem - ì''
);
if (!function_exists(''recursive_utf8'')) {
function recursive_utf8 ($data) {
if (!is_array($data)) {
return utf8_encode($data);
}
$result = array();
foreach ($data as $index=>$item) {
if (is_array($item)) {
$result[$index] = array();
foreach($item as $key=>$value) {
$result[$index][$key] = recursive_utf8($value);
}
}
else if (is_object($item)) {
$result[$index] = array();
foreach(get_object_vars($item) as $key=>$value) {
$result[$index][$key] = recursive_utf8($value);
}
}
else {
$result[$index] = recursive_utf8($item);
}
}
return $result;
}
}
$outputArray = json_encode(array_map(''recursive_utf8'', $inputArray ));
Para imprimir la palabra en español, finalmente obtuve la solución como abajo con la aplicación de dos funciones.
$conn->set_charset("utf8");
mb_convert_encoding(''THE BULLOCK ÉTAGÈRE - 3 SHELVES'', "UTF-8", "Windows-1252")
Donde ''THE BULLOCK Ã AG TAGˆRE - 3 SHELVES'' esta cadena proviene de la base de datos, así que tengo el primer objeto de la base de datos $ conn para configurar el carácter como utf8 y luego he codificado la palabra española UTF-8 a Windows-1252
Sí, este es el comportamiento estándar para json dentro de PHP
Si lees la documentación: json_encode
Verás que solo puede funcionar con datos codificados en utf-8,
por otro lado, puede usar el primer comentario en: http://php.net/manual/en/function.json-encode.php#104278
y cree su propia función de codificación / decodificación trabajando con ANSI
Use esto en su lugar:
<?php
//$return_arr = the array of data to json encode
//$out = the output of the function
//don''t forget to escape the data before use it!
$out = ''["'' . implode(''","'', $return_arr) . ''"]'';
?>
Copia de los json_encode . Siempre lea los comentarios. Son útiles.
json_encode($str,JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS|JSON_HEX_QUOT);
eso convertirá las ventanas basadas en ANSI a utf-8 y el error no será más.
<?php
$array = array(''first word'' => array(''Слово'',''Кириллица''),''second word'' => ''Кириллица'',''last word'' => ''Кириллица'');
echo json_encode($array);
/*
return {"first word":["/u0421/u043b/u043e/u0432/u043e","/u041a/u0438/u0440/u0438/u043b/u043b/u0438/u0446/u0430"],"second word":"/u041a/u0438/u0440/u0438/u043b/u043b/u0438/u0446/u0430","last word":"/u041a/u0438/u0440/u0438/u043b/u043b/u0438/u0446/u0430"}
*/
echo json_encode($array,256);
/*
return {"first word":["Слово","Кириллица"],"second word":"Кириллица","last word":"Кириллица"}
*/
?>
JSON_UNESCAPED_UNICODE (integer) Codifique los caracteres Unicode multibyte literalmente (el valor predeterminado es escapar como / uXXXX). Disponible desde PHP 5.4.0.
http://php.net/manual/en/json.constants.php#constant.json-unescaped-unicode