Tengo una estructura php simple con 3 matrices anidadas.
No utilizo 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. Entonces no entiendo por qué json_encode
no funcionará aquí.
Editar: parece haber un problema con la codificación. Cuando mb_detect_encoding
devuelve ASCII, json_encode
funciona, pero cuando devuelve UTF8, ya no funciona.
Edit2: json_last_error()
devuelve lo JSON_ERROR_UTF8
que significa: caracteres UTF-8 mal formados , posiblemente codificados incorrectamente .
This function only works with UTF-8 encoded data.
que no debería haber ningún problema con la codificación.utf8_encode()
en susname
campos de matriz antes de entregar la cadena ajson_encode()
.JSON_PARTIAL_OUTPUT_ON_ERROR
opción para ver el problema (por ejemplo, el campo con UTF8 será nulo).Respuestas:
Bueno, después de 2 horas de excavación (cf. Ediciones)
Descubrí lo siguiente:
mb_detect_encoding
devuelve probablemente una respuesta defectuosa, algunas cadenas probablemente no eran UTF-8utf8_encode()
en esa cadena resolvió mi problema, pero vea la nota a continuaciónAquí hay una función recursiva que puede forzar la conversión a UTF-8 de todas las cadenas contenidas en una matriz:
Úselo simplemente así:
Nota: utf8_encode () codifica la cadena ISO-8859-1 a UTF-8 según los documentos, por lo que si no está seguro de la codificación de entrada, iconv () o mb_convert_encoding () pueden ser mejores opciones como se indica en los comentarios y otras soluciones.
fuente
} else {
a} else if (is_string ($d)) {
; de lo contrario, cambiará todo a cadenas (p. ej.INT
se convertirá en aSTRING
).Matthieu Riegler presentó una solución realmente buena, sin embargo, tuve que modificarla ligeramente para manejar objetos también:
Una nota más: json_last_error () puede ser útil para depurar funciones json_encode () / json_encode ().
fuente
elseif
lugar deelse if
? (es decir, sin espacio en blanco).if(): elseif:
else if(is_int($d)||is_bool($d)) return $d;
antes del último, debido a:{"success":true, "message":"Ⲃⲟⲟ𝓵ⲉⲁⲛ ⲁⲛⲇ Ⲓⲛϯⲉ𝓰ⲉꞅ𝛓"}
else
porelse if(is_string ($d))
; de lo contrario, cambiará todo a cadenas (por ejemplo,INT
se convertirá en aSTRING
).Para mí, la respuesta a este problema fue configurar
charset=utf8
mi conexión PDO.fuente
$mysqli->set_charset("utf8");
después de manejar su base de datos.utf8mb4
en versiones recientes de MySQL.utf8
es obsoleto.Adam Bubela también presentó una solución realmente buena que me ayudó a resolver mi problema, y aquí está la función simplificada:
fuente
Tengo exactamente el mismo problema en PHP 5.6. Utilizo Open Server + Nginx en Windows 7. Todos los juegos de caracteres están configurados en UTF-8. En teoría, según la documentación oficial , bandera
debería resolver esto. Desafortunadamente este no es mi caso. No se por que. Todos los fragmentos anteriores no resuelven mi problema, por lo que he encontrado mi propia implementación. Creo que podría ayudar a alguien. Al menos, las letras rusas pasan la prueba.
fuente
Esta respuesta aceptada funciona. Pero en caso de que obtenga sus datos de MySQL (como yo), hay una manera más fácil.
Una vez que abra su base de datos, antes de realizar la consulta, puede configurar el juego de caracteres usando mysqli de la siguiente manera:
O
ENLACE: http://php.net/manual/en/mysqli.set-charset.php
fuente
Me encontré con este problema en un servidor que ejecuta una versión anterior de PHP (5.2). Estaba usando la bandera JSON_FORCE_OBJECT, y aparentemente eso no es compatible hasta 5.3
Entonces, si está usando esa bandera, ¡asegúrese de verificar su versión!
Una solución alternativa parece ser simplemente enviar a un objeto antes de codificar, como:
fuente
La devolución de
mb_detect_encoding
puede no ser correcta:Según el orden de detección predeterminado, lo anterior puede devolver 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 estén codificados como UTF-8, por
json_encode
lo que regresanfalse
. Debería considerar convertir sus cadenas a UTF-8 antes de la codificación JSON:fuente
Estaba obteniendo datos de ob_get_clean () y tuve el mismo problema, pero las soluciones anteriores no me funcionan. En mi caso, la solución fue esta, tal vez ayude a alguien.
fuente
usando utf8_encode () en esas cadenas resolvió mi problema.
fuente
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 usé Perl en el pasado :)
fuente
Si obtiene estos datos de una base de datos, utilícelos
mysqli_set_charset($connection, "utf8");
en conexión cuando obtenga los parámetros de la base de datosfuente
Este problema surge a veces: no está pasando el control de acceso al encabezado.
En mi caso, si se agregó un eco antes de json_encode. Estaba mostrando el resultado, de lo contrario venía una página en blanco.
yo añadí
y mi problema resuelto.
fuente