Menu

PHP json_encode(): convertir arrays y objetos a JSON

json_encode($value) convierte un array, un objeto o un escalar de PHP en una cadena JSON. Los arrays asociativos se convierten en objetos JSON, las listas en arrays JSON, y opciones como JSON_PRETTY_PRINT y JSON_UNESCAPED_UNICODE controlan la salida.

Esta página incluye editores ejecutables: edita, ejecuta y ve el resultado al instante.

json_encode($value) devuelve el texto JSON de un valor de PHP. Un array asociativo se convierte en un objeto JSON, una lista (claves 0, 1, 2...) en un array JSON, y las cadenas, los números, true, false y null en sus equivalentes JSON.

Salida:

{"name":"Ada","age":36,"langs":["php","js"],"admin":true,"manager":null}
string

El resultado es una cadena simple, lista para enviarla a un navegador, guardarla en un archivo o en una columna de base de datos, o pasarla a otro programa. Para convertir JSON de vuelta en PHP, usa json_decode().

JSON legible con pretty print

json_encode() recibe opciones como segundo argumento. JSON_PRETTY_PRINT añade saltos de línea e indentación de 4 espacios, que es lo que quieres en un archivo de configuración o en un log de depuración. Combina varias opciones con |:

Salida:

{
    "app": "shop",
    "debug": false,
    "db": {
        "host": "localhost",
        "port": 3306
    },
    "tags": []
}

Mantener legible el japonés y otro texto UTF-8

Por defecto, json_encode() escribe cada carácter no ASCII como un escape \u y pone una barra invertida delante de cada /. Las dos cosas son JSON válido y se decodifican al mismo texto, pero hacen la salida difícil de leer y más larga. JSON_UNESCAPED_UNICODE conserva los caracteres, y JSON_UNESCAPED_SLASHES deja las URLs tal cual:

Salida:

{"name":"\u308a\u3093\u3054","price":120,"url":"https:\/\/example.com\/fruit\/apple"}
{"name":"りんご","price":120,"url":"https://example.com/fruit/apple"}

Si el texto japonés se ve corrupto (文字化け) después de decodificarlo, el problema no son los escapes: la cadena no era UTF-8 desde el principio. json_encode() solo acepta UTF-8 y devuelve false con cualquier otra cosa, como muestra la sección sobre los errores.

Cuándo un array se convierte en objeto en lugar de en lista

Un array de PHP se codifica como array JSON solo cuando sus claves son exactamente 0, 1, 2... en orden. Cualquier otra clave lo convierte en un objeto JSON. Esto pilla a mucha gente después de unset() o array_filter(), que dejan huecos en las claves:

Salida:

{"0":"apple","2":"cherry"}
["apple","cherry"]
{"1":"a","2":"b"}
[]
{}
{"0":"a","1":"b"}

Llama a array_values() antes de codificar siempre que el código que recibe espere una lista. Si espera un objeto que puede estar vacío, usa new stdClass() o (object) $array para que un valor vacío siga saliendo como {}.

Codificar un objeto y controlar su JSON con JsonSerializable

Un objeto normal se codifica solo con sus propiedades públicas; las protegidas y privadas se saltan. Para decidir exactamente qué aspecto tiene un objeto en JSON, implementa la interfaz JsonSerializable y devuelve los datos desde jsonSerialize():

Salida:

{"name":"Ada","nick":null}
{"date":"2026-03-14 09:30:00.000000","timezone_type":3,"timezone":"UTC"}
{
    "id": 7,
    "total": 19.5,
    "created": "2026-03-14T09:30:00+00:00"
}

Un backed enum como enum Status: string se codifica como su valor ("active"). Un enum puro no tiene valor, así que json_encode() falla con él con "Non-backed enums have no default serialization".

Números, floats y cadenas numéricas

Los enteros y los floats se escriben como números JSON, y las cadenas siguen siendo cadenas aunque contengan dígitos. Tres opciones cambian eso:

Salida:

{"price":10}
{"price":10.0}
0.30000000000000004
{"qty":"3","id":"007"}
{"qty":3,"id":7}

JSON_NUMERIC_CHECK convierte todas las cadenas numéricas, así que un ID como "007" o un código postal como "01234" pierde sus ceros iniciales. Convierte con (int) los campos que quieras en lugar de aplicarlo a un array entero.

json_encode devuelve false: encontrar el error

json_encode() devuelve false cuando no puede codificar el valor. Las causas habituales son una cadena que no es UTF-8 válido (texto leído de un archivo antiguo o de una base de datos Latin-1) y los valores float NAN e INF. json_last_error_msg() dice qué falló; JSON_THROW_ON_ERROR hace que lance una JsonException en su lugar:

Salida:

bool(false)
Malformed UTF-8 characters, possibly incorrectly encoded
{"name":"Caf\ufffd"}
{"name":"Café"}
JsonException: Inf and NaN cannot be JSON encoded

JSON_THROW_ON_ERROR es la mejor opción por defecto en código nuevo: un false que nadie comprueba acaba guardado o enviado como una cadena vacía.

Devolver JSON desde una API en PHP

Un script PHP que responde con JSON fija la cabecera Content-Type antes de imprimir nada, codifica una vez y se detiene:

<?php
header('Content-Type: application/json; charset=utf-8');

$products = [
    ['id' => 1, 'name' => 'りんご', 'price' => 120],
    ['id' => 2, 'name' => 'みかん', 'price' => 80],
];

echo json_encode(['data' => $products], JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
exit;

Cuando en cambio imprimas JSON dentro de una etiqueta HTML <script>, añade JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT. El escape de barras por defecto convierte </script> en <\/script>, pero esa protección desaparece en cuanto alguien añade JSON_UNESCAPED_SLASHES, y un <!-- en un valor sigue cambiando cómo analiza el script el navegador. Las opciones escriben <, >, &, ' y " como \u003C, \u003E, \u0026, \u0027 y \u0022, que JavaScript vuelve a leer como los mismos caracteres.

Preguntas frecuentes

¿Cómo convierto un array de PHP a JSON?

Pásalo a json_encode(): json_encode(['name' => 'Ada', 'age' => 36]) devuelve {"name":"Ada","age":36}. Un array con claves 0, 1, 2... en orden se convierte en cambio en un array JSON: json_encode(['a', 'b']) devuelve ["a","b"].

¿Cómo formateo JSON de forma legible en PHP?

Añade la opción JSON_PRETTY_PRINT: json_encode($data, JSON_PRETTY_PRINT) indenta con 4 espacios y pone cada valor en su propia línea. Combina opciones con |, por ejemplo JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE.

¿Por qué json_encode convierte el texto japonés en códigos \u?

Por defecto, cada carácter no ASCII se escribe como un escape \uXXXX, así que りんご se convierte en \u308a\u3093\u3054. Sigue siendo JSON válido, pero pasa JSON_UNESCAPED_UNICODE para mantener legibles los caracteres.

¿Por qué json_encode devuelve false?

Normalmente porque una cadena no es UTF-8 válido, o porque los datos contienen NAN o INF. Llama a json_last_error_msg() para ver el motivo, o pasa JSON_THROW_ON_ERROR para que lance una JsonException en lugar de devolver false.

¿Cómo hago que json_encode devuelva {} en lugar de [] para un array vacío?

Un array vacío de PHP siempre se codifica como []. Usa new stdClass() o (object) [] para un objeto vacío, o la opción JSON_FORCE_OBJECT, que convierte en objeto todos los arrays del valor.

Ilustración de los lenguajes de programación de Coddy

Aprende a programar con Coddy

COMENZAR