json_unescaped_unicode - print json php
¿Por qué json_encode devolvería una cadena vacía? (11)
Adam Bubela también presentó una solución realmente buena que me ayudó a resolver mi problema, y aquí está la función simplificada:
function utf8ize($d)
{
if (is_array($d) || is_object($d))
foreach ($d as &$v) $v = utf8ize($v);
else
return utf8_encode($d);
return $d;
}
Tengo una estructura php simple con 3 matrices anidadas.
No uso objetos particulares y construyo las matrices con 2 bucles anidados.
Aquí hay una muestra del var_dump de la matriz que quiero convertir a Json.
array (size=2)
''tram B'' =>
array (size=2)
0 =>
array (size=3)
''name'' => string ''Ile Verte'' (length=9)
''distance'' => int 298
''stationID'' => int 762
1 =>
array (size=3)
''name'' => string ''La Tronche Hôpital'' (length=18)
''distance'' => int 425
''stationID'' => int 771
16 =>
array (size=4)
0 =>
array (size=3)
''name'' => string ''Bastille'' (length=8)
''distance'' => int 531
''stationID'' => int 397
1 =>
array (size=3)
''name'' => string ''Xavier Jouvin'' (length=13)
''distance'' => int 589
''stationID'' => int 438
En otro script, tengo una estructura similar y json_encode
funciona bien. Así que no entiendo por qué json_encode
no funcionará aquí.
Editar: parece haber un problema con la codificación. Cuando mb_detect_encoding
devuelve ASCII, el json_encode
funciona, pero cuando devuelve UTF8, ya no funciona.
Edit2: json_last_error()
devuelve JSON_ERROR_UTF8
que significa: caracteres UTF-8 JSON_ERROR_UTF8
, posiblemente codificados incorrectamente .
Bien después de 2 horas de excavación (cf Edits)
Descubrí lo siguiente:
- En mi caso, es un problema de codificación
-
mb_detect_encoding
devuelve probablemente una respuestamb_detect_encoding
, algunas cadenas probablemente no sean UTF-8 - El uso de
utf8_encode()
en esas cadenas resolvió mi problema.
Aquí hay una función recursiva que puede obligar a convertir a UTF-8 todas las cadenas contenidas en una matriz:
function utf8ize($d) {
if (is_array($d)) {
foreach ($d as $k => $v) {
$d[$k] = utf8ize($v);
}
} else if (is_string ($d)) {
return utf8_encode($d);
}
return $d;
}
Úselo simplemente así:
echo json_encode(utf8ize($data));
El retorno de mb_detect_encoding
puede no ser correcto:
$data = iconv(''UTF-8'', ''ISO-8859-1'', ''La Tronche Hôpital'');
var_dump(
mb_detect_encoding($data),
mb_detect_encoding($data, array(''ISO-8859-1'', ''UTF-8''))
);
Dependiendo de la orden de detección predeterminada, lo anterior puede arrojar resultados diferentes, por lo que la codificación se informa falsamente como UTF-8. ( Aquí hay un ejemplo más grande )
Es probable que sus datos no json_encode
codificados como UTF-8, por lo que json_encode
devuelve false
. Debería ver la conversión de sus cadenas a UTF-8 antes de la codificación JSON:
$fromEncoding = ''ISO-8859-1''; // This depends on the data
array_walk_recursive($array, function (&$value, $key, $fromEncoding) {
if (is_string($value)) {
$value = iconv($fromEncoding, ''UTF-8'', $value);
}
}, $fromEncoding);
El uso de utf8_encode () en esas cadenas resolvió mi problema.
Esta respuesta aceptada funciona. Pero en caso de que obtenga sus datos de MySQL (como yo lo hice), hay una manera más fácil.
Una vez que abre su base de datos, antes de realizar la consulta puede establecer el juego de caracteres usando mysqli de la siguiente manera:
/* change character set to utf8 | Procedural*/
if (!mysqli_set_charset($link, "utf8")) {
printf("Error loading character set utf8: %s/n", mysqli_error($link));
exit();
}
O
/* change character set to utf8 | Object Oriented*/
if (!$mysqli->set_charset("utf8")) {
printf("Error loading character set utf8: %s/n", $mysqli->error);
exit();
}
Estaba obteniendo datos de ob_get_clean () y tenía el mismo problema, pero las soluciones anteriores no funcionan para mí. En mi caso, la solución fue esta, tal vez ayudará a alguien.
$var = mb_convert_encoding($var, ''UTF-8'');
He mejorado la respuesta de Adam Bubela. Odio cuando los bloques no están cerrados por {y}. Es más limpio y no introduces errores o tal vez es que utilicé Perl en el pasado :)
<?php
class App_Updater_String_Util {
/**
* Usage: App_Updater_String_Util::utf8_encode( $data );
*
* @param mixed $d
* @return mixed
* @see http://.com/questions/19361282/why-would-json-encode-returns-an-empty-string
*/
public static function utf8_encode($d) {
if (is_array($d)) {
foreach ($d as $k => $v) {
$d[$k] = self::utf8_encode($v);
}
} elseif (is_object($d)) {
foreach ($d as $k => $v) {
$d->$k = self::utf8_encode($v);
}
} elseif (is_scalar($d)) {
$d = utf8_encode($d);
}
return $d;
}
}
?>
Matthieu Riegler presentó una solución realmente buena; sin embargo, tuve que modificarla ligeramente para manejar objetos también:
function utf8ize($d) {
if (is_array($d))
foreach ($d as $k => $v)
$d[$k] = utf8ize($v);
else if(is_object($d))
foreach ($d as $k => $v)
$d->$k = utf8ize($v);
else
return utf8_encode($d);
return $d;
}
Una nota más: json_last_error() puede ser útil para depurar funciones json_encode () / json_encode ().
Me encontré con este problema en un servidor que ejecuta una versión anterior de PHP (5.2). Estaba usando el indicador JSON_FORCE_OBJECT, y aparentemente eso no es compatible hasta 5.3
Entonces, si usa esa bandera, asegúrese de verificar su versión.
Parece que una solución temporal es simplemente enviar contenido a un objeto antes de la codificación, como:
json_encode((object)$myvar);
Para mí, la respuesta a este problema fue establecer charset = utf8 en mi conexión PDO.
ex: $dbo = new PDO(''mysql:host=localhost;dbname=yourdb;charset=utf8'', $username, $password);
Tengo exactamente el mismo problema en PHP 5.6. Uso Open Server + Nginx en Windows 7. Todos los conjuntos de caracteres están configurados en UTF-8. En teoría, según la documentación oficial , bandera
JSON_UNESCAPED_UNICODE
debería resolver esto. Desafortunadamente este no es mi caso. No se por que. Todos los fragmentos de arriba no resuelven mi problema, así que he encontrado mi propia implementación. Creo que podría ayudar a alguien. Al menos, las letras rusas pasan la prueba.
function utf8ize($d) {
if (is_array($d) || is_object($d)) {
foreach ($d as &$v) $v = utf8ize($v);
} else {
$enc = mb_detect_encoding($d);
$value = iconv($enc, ''UTF-8'', $d);
return $value;
}
return $d;
}