Saltar al contenido

Cómo evitar que json_encode() suelte cadenas con caracteres no válidos

Ya no necesitas investigar más por internet porque estás al sitio indicado, tenemos la solución que necesitas sin complicaciones.

Solución:

php intenta arrojar un error, pero solo si desactivas display_errors. Esto es raro porque el display_errors La configuración solo está destinada a controlar si los errores se imprimen o no en la salida estándar, no si se activa o no un error. Quiero enfatizar que cuando tienes display_errors encendido, aunque puede ver todo tipo de otros errores de php, php no solo oculta este error, ni siquiera lo activará. Eso significa que no aparecerá en ningún registro de errores, ni se llamará a ningún manejador de errores personalizado. El error simplemente nunca ocurre.

Aquí hay un código que demuestra esto:

error_reporting(-1);//report all errors
$invalid_utf8_char = chr(193);

ini_set('display_errors', 1);//display errors to standard output
var_dump(json_encode($invalid_utf8_char));
var_dump(error_get_last());//nothing

ini_set('display_errors', 0);//do not display errors to standard output
var_dump(json_encode($invalid_utf8_char));
var_dump(error_get_last());// json_encode(): Invalid UTF-8 sequence in argument

Ese comportamiento extraño y desafortunado está relacionado con este error https://bugs.php.net/bug.php?id=47494 y algunos otros, y parece que nunca se solucionará.

solución alterna:

Limpiando el string antes de pasarlo a json_encode puede ser una solución viable.

$stripped_of_invalid_utf8_chars_string = iconv('UTF-8', 'UTF-8//IGNORE', $orig_string);
if ($stripped_of_invalid_utf8_chars_string !== $orig_string) 
    // one or more chars were invalid, and so they were stripped out.
    // if you need to know where in the string the first stripped character was, 
    // then see http://stackoverflow.com/questions/7475437/find-first-character-that-is-different-between-two-strings

$json = json_encode($stripped_of_invalid_utf8_chars_string);

http://php.net/manual/en/function.iconv.php

el manual dice

//IGNORE descarta silenciosamente los caracteres que son ilegales en el conjunto de caracteres de destino.

Entonces, al eliminar primero los caracteres problemáticos, en teoría, json_encode () no debería obtener nada con lo que se ahogue y falle. No he verificado que la salida de iconv con el //IGNORE flag es perfectamente compatible con la noción json_encodes de qué caracteres utf8 válidos son, por lo que el comprador debe tener cuidado… ya que puede haber casos extremos en los que todavía falla. ugh, odio los problemas con el conjunto de personajes.

Editar

en php 7.2+, parece haber algunas banderas nuevas para json_encode:
JSON_INVALID_UTF8_IGNORE y JSON_INVALID_UTF8_SUBSTITUTE

Todavía no hay mucha documentación, pero por ahora, esta prueba debería ayudarlo a comprender el comportamiento esperado: https://github.com/php/php-src/blob/master/ext/json/tests/json_encode_invalid_utf8.phpt

Y, en php 7.3+ está la nueva bandera JSON_THROW_ON_ERROR. Ver http://php.net/manual/en/class.jsonexception.php

$s = iconv('UTF-8', 'UTF-8//IGNORE', $s);

Esto resolvió el problema. No estoy seguro de por qué los chicos de php no han hecho la vida más fácil arreglando json_encode().

De todos modos, usar lo anterior permite que json_encode() cree objetos incluso si los datos contienen caracteres especiales (letras suecas, por ejemplo).

Luego puede usar el resultado en javascript sin la necesidad de decodificar los datos a su codificación original (con escape(), unescape(), encodeURIComponent(), decodeURIComponent());

Lo estoy usando así en php (inteligente):

$template = iconv('UTF-8', 'UTF-8//IGNORE', $screen->fetch("my_template.tpl"));

Luego estoy enviando el resultado a javascript y solo innerHTML la plantilla lista (paz html) en mi documento.

Simplemente dicha línea anterior debe implementarse en json_encode() de alguna manera para permitir que funcione con cualquier codificación.

Esta función eliminará todos los caracteres UTF8 no válidos de un string:

function removeInvalidChars( $text)  [xE0-xEF][x80-xBF]2 

Lo uso después de convertir un documento de Excel a json, ya que no se garantiza que los documentos de Excel estén en UTF8.

No creo que haya una forma particularmente sensata de convertir caracteres no válidos en un carácter visible pero válido. Puede reemplazar los caracteres no válidos con U + FFFD, que es el carácter de reemplazo de Unicode al girar la expresión regular anterior, pero eso realmente no proporciona una mejor experiencia de usuario que simplemente eliminar los caracteres no válidos.

Aquí tienes las reseñas y puntuaciones

Si haces scroll puedes encontrar las ilustraciones de otros gestores de proyectos, tú además tienes el poder mostrar el tuyo si lo crees conveniente.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *