PHP JSON: devuelve datos rápido y sin errores

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Depuración de API sobre la marcha: ¿por qué tu JSON devuelve errores?

\n\n

¿Alguna vez te has quedado mirando una pantalla vacía de Postman a las tres de la madrugada pensando: «¿Por qué mi script PHP devuelve HTML en lugar de JSON?»? Si es así, no estás solo. El tema Returning JSON from a PHP Script en Stack Overflow acumula decenas de miles de visitas, y no es casualidad. Uno de cada dos desarrolladores backend principiantes tropieza con los mismos errores: cabeceras olvidadas, salida basura, Content-Type incorrecto.

\n\n

En este artículo no solo copiaremos una respuesta de un foro. Analizaremos cómo devolver JSON desde PHP de forma correcta, rápida y sin sorpresas. Descubrirás por qué exit(json_encode($data)) puede fallarte, cómo ahorrar milisegundos en la serialización y qué hacer si el JSON se «rompe» de repente.

\n\n

¿Listo? ¡Empecemos!

\n\n

Anatomía de una respuesta JSON correcta

\n\n

Empecemos por lo básico. Así es como no se debe hacer:

\n\n
<?php\n$data = ['status' => 'ok', 'message' => '¡Hola!'];\necho json_encode($data);\n?>
\n\n

¿Por qué está mal? Primero, falta la cabecera Content-Type. El navegador o cliente puede interpretar la respuesta como HTML o texto. Segundo, si antes hay un espacio, un echo o un warning en el código, el JSON se romperá.

\n\n

La plantilla mínima correcta es esta:

\n\n
<?php\nheader('Content-Type: application/json; charset=utf-8');\n$data = ['status' => 'ok', 'message' => '¡Hola!'];\necho json_encode($data, JSON_UNESCAPED_UNICODE);\nexit;\n?>
\n\n

Fíjate en JSON_UNESCAPED_UNICODE: conserva los caracteres acentuados y especiales legibles, sin convertirlos en \\u00a1Hola!. Y exit es un seguro contra cualquier salida accidental después de la respuesta.

\n\n

Cabeceras: no solo Content-Type

\n\n

Para optimizar el rendimiento del JSON, añade un par de cabeceras más:

\n\n
header('Content-Type: application/json; charset=utf-8');\nheader('X-Content-Type-Options: nosniff');\nheader('Cache-Control: no-cache, must-revalidate');
\n\n

X-Content-Type-Options: nosniff evita que el navegador «adivine» el tipo de contenido — es seguridad. Y Cache-Control es útil para datos dinámicos, así el cliente no almacena en caché una respuesta obsoleta.

\n\n

Manejo de errores: cuando json_encode falla

\n\n

La función json_encode devuelve false si falla. Y aquí empieza lo interesante. Si simplemente haces echo json_encode($data) y obtienes una cadena vacía, el cliente se quedará desconcertado.

\n\n

Siempre verifica el resultado:

\n\n
$json = json_encode($data, JSON_UNESCAPED_UNICODE);\nif ($json === false) {\n    http_response_code(500);\n    echo json_encode(['error' => 'Error de codificación JSON: ' . json_last_error_msg()]);\n    exit;\n}\necho $json;\nexit;
\n\n

Por cierto, json_last_error_msg() devuelve un mensaje claro: «Malformed UTF-8 characters» o «Inf and NaN cannot be JSON encoded». Esto te ahorrará horas de depuración.

\n\n

Datos profundamente anidados y recursión

\n\n

Otro problema son las referencias circulares en objetos. Si pasas un objeto con referencias mutuas, json_encode lanzará un error. Solución: usa JSON_PARTIAL_OUTPUT_ON_ERROR o convierte el objeto a array previamente.

\n\n
$json = json_encode($complexObject, JSON_UNESCAPED_UNICODE | JSON_PARTIAL_OUTPUT_ON_ERROR);
\n\n

Pero cuidado: la salida parcial puede estar incompleta. Es mejor corregir la estructura de datos.

\n\n

Optimización del rendimiento JSON en PHP

\n\n

Ahora vamos a lo jugoso: cómo acelerar la devolución de JSON desde PHP.

\n\n

1. Caché del JSON serializado

\n\n

Si los datos cambian con poca frecuencia (catálogos, configuraciones, listas de ciudades), no los serialices cada vez. Guarda el JSON listo en un archivo, Memcached

Blogs

Book Recommendations