Ver índice de contenidos del libro

11.6. JSON

JSON (JavaScript Object Notation) es un formato sencillo para intercambiar datos. Consiste básicamente en un array asociativo de JavaScript (ver ejemplo en el listado 11-26) que se utilizar para incluir información del objeto. JSON ofrece 2 grandes ventajas para las interacciones Ajax: es muy fácil de leer en JavaScript y puede reducir el tamaño en bytes de la respuesta del servidor.

Listado 11-26 - Ejemplo de objeto JSON en JavaScript

var misDatosJson = {"menu": {
  "id": "archivo",
  "valor": "Archivo",
  "popup": {
    "menuitem": [
      {"value": "Nuevo", "onclick": "CrearNuevoDocumento()"},
      {"value": "Abrir", "onclick": "AbrirDocumento()"},
      {"value": "Cerrar", "onclick": "CerrarDocumento()"}
    ]
  }
}}

El formato JSON es el más adecuado para la respuesta del servidor cuando la acción Ajax debe devolver una estructura de datos a la página que realizó la llamada de forma que se pueda procesar con JavaScript. Este mecanismo es útil por ejemplo cuando una sola petición Ajax debe actualizar varios elementos en la página.

En el listado 11-27 se muestra un ejemplo de página que contiene 2 elementos que deben ser actualizados. Un helper remoto solo puede actualizar uno de los elementos de la página (o titulo o nombre) pero no los 2 a la vez.

Listado 11-27 - Plantilla de ejemplo para actualizaciones Ajax múltiples

<h1 id="titulo">Carta normal</h1>
<p>Estimado <span id="nombre">el_nombre</span>,</p>
<p>Hemos recibido su email y le contestaremos en el menor plazo de tiempo.</p>
<p>Reciba un saludo cordial,</p>

Para actualizar los dos elementos, la respuesta Ajax podría estar formada por el siguiente array en formato JSON:

[["titulo", "Mi carta normal"], ["nombre", "Sr. Pérez"]]

Mediante algunas pocas instrucciones de JavaScript se puede interpretar la respuesta del servidor y actualizar varios elementos de la página de forma seguida. El listado 11-28 muestra el código que se podría añadir a la plantilla del listado 11-27 para conseguir este efecto.

Listado 11-28 - Actualizando más de un elemento mediante una respuesta remota

<?php echo link_to_remote('Actualizar la carta', array(
  'url'      => 'publicaciones/actualizar',
  'complete' => 'actualizaJSON(ajax)'
)) ?>
 
<?php echo javascript_tag("
function actualizaJSON(ajax)
{
  json = ajax.responseJSON;
  for (var i = 0; i < json.length; i++)
  {
     Element.update(json[i][0], json[i][1]);
  }
}
") ?>

Dentro de la opción complete se tiene acceso directo a la respuesta AJAX y por tanto se puede enviar el objeto de la respuesta del servidor a una función externa. La función actualizaJSON() recorre los datos JSON obtenidos mediante la propiedad responseJSON y para cada elemento del array actualiza el elemento cuyo atributo id coincide con el primer parámetro del array y muestra el contenido incluido en el segundo parámetro del array.

El listado 11-29 muestra como devuelve la acción publicaciones/actualizar una respuesta de tipo JSON.

Listado 11-29 - Ejemplo de acción que devuelve datos JSON

class publicacionesActions extends sfActions
{
  public function executeActualizar()
  {
    $this->getResponse()->setHttpHeader('Content-Type', 'application/json; charset=utf-8');
    $resultado = '[["titulo", "Mi carta normal"], ["nombre", "Sr. Pérez"]]';
    return $this->renderText('('.$resultado.')');
  }

Si se utiliza la cabecera que establece el tipo de contenido a application/json, las librerías como Prototype pueden evaluar automáticamente el código JSON de la respuesta. Además, este método es preferible a enviar los datos JSON en la propia cabecera HTTP, ya que estas cabeceras están limitadas en tamaño y algunos navegadores pueden sufrir problemas con las respuestas de servidor que sólo tienen cabeceras y ningún contenido. Por último, el método ->renderText() hace que no se utilice ninguna plantilla, por lo que mejora el rendimiento de la aplicación.

JSON se ha convertido en un estandar en el desarrollo de aplicaciones web. Los servicios web proponen la utilización de JSON en vez de XML para permitir la integración de servicios en el navegador del usuario en vez de en el servidor. El formato JSON es seguramente la mejor opción para el intercambio de información entre el servidor y las funciones JavaScript.

Truco Desde la versión 5.2 de PHP existen dos funciones, json_encode() y json_decode(), que permiten convertir un array PHP en un array JSON y viceversa (http://www.php.net/manual/es/ref.json.php). Estas funciones facilitan la integración de los arrays JSON (y de Ajax en general) y permiten escribir código PHP nativo más fácil de leer.

$resultado = array("titulo" => "Mi carta normal", "nombre" => "Sr. Pérez");
return $this->renderText(json_encode($resultado));