viernes, 11 de junio de 2010

Devolver objetos en JSON desde PHP


Yo digo que es una dona

¡Saludos blogueros!

Ese pequeño artículo va para los que se preguntaban en el ejemplo anterior, ¿qué era ese formato llamado JSON que utiliza flickr para enviarnos la información? Se trata más que nada de una forma para intercambiar datos estructurados entre diferentes sistemas sobre protocolos como HTTP. JSON, define cómo se deberán codificar los objetos de un determinado lenguaje para convertirlos en cadenas de texto, con el propósito de enviarlos hacia otras aplicaciones, y que estas puedan reconstruirlos como objetos nativos, utilizando la decodificación definida por el mismo formato JSON.

Por ejemplo, digamos que mi aplicación desea mandar un objeto que contiene determinada información hacia un cliente Javascript, además de las ya conocidas técnicas basadas en XML o protocolos como SOAP, tenemos la posibilidad de mandarlo codificado en JSON, de modo que desde nuestra aplicación convertiremos ese objeto en una cadena de texto que lo representará, y lo enviaremos a nuestro cliente Javascript como una respuesta en texto simple, el cliente -con previo conocimiento del formato de la respuesta-, solo tendrá que aplicar las reglas de la notación para -partir de la cadena- reconstruir el objeto y utilizarlo dentro de su propia ejecución de instrucciones. Tal y como hicimos en el ejemplo anterior con los servicios de flickr.

La gran ventaja de JSON, es que el cliente Javascript puede utilizar la instrucción eval, para reconstruir el objeto partir de la cadena recibida, sin necesidad de ningún interprete especia, tal y como explica el artículo de la Wikipedia sobre JSON. Del lado de nuestra aplicación en el servidor por otro lado sí se necesitará de una funcionalidad que haga el trabajo de codificar los objetos u arreglos en la notación de JSON, pero para eso la gran mayoría de los lenguajes cuentan ya con bibliotecas de funciones o clases para hacer la tarea.

En este artículo veremos cómo hacer esa tarea del lado del servidor, utilizando la biblioteca de funciones para JSON de PHP, disponible a partir de la versión 5.2.0. Creando la siguiente aplicación web en este lenguaje:

respuestajson.php
<?php

//Clase para representar una serie de diferentes artículos para tiendas

class Articulo {
public $id;
public $nombre;
public $categoria;
public $precioDeSalida;
public $detalles;
}



$articulo = new Articulo();
$articulo->id = 1;
$articulo->nombre = "Nintendo DS";
$articulo->categoria = "Videojuego";
$articulo->precioDeSalida = "$3 500";
$articulo->detalles = array('Soporta juegos para Gameboy advance','Pantalla tactil','Reproducción de MP3');
echo json_encode($articulo);?>


El programa en PHP codificara en notación JSON el objeto $articulo, dando como resultado una cadena que devolverá al cliente, la cual podemos visualizar si accedemos a la aplicación desde el navegador (http://localhost/respuestajson.php):


{"id":1,"nombre":"Nintendo DS","categoria":"Videojuego","precioDeSalida":"$3 500","detalles":["Soporta juegos para Gameboy advance","Pantalla tactil","Reproducci\u00f3n de MP3"]}


Ahora, el cliente AJAX para procesar estos datos sería el siguiente:

clientejson.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Decodifica un objeto en JSON</title>
<script type="application/javascript">
var http_request = new XMLHttpRequest();
var url = "http://localhost/respuestajson.php"; // Esta URL debería devolver datos JSON

// Descarga los datos JSON del servidor.
http_request.onreadystatechange = manejaJSON;
http_request.open("GET", url, true);
http_request.send(null);

function manejaJSON() {
  if (http_request.readyState == 4) {
    if (http_request.status == 200) {
      var cadCodificadaJSON = http_request.responseText;
      var objDatos = eval("(" + cadCodificadaJSON + ")"); //Creamos el objeto utilizando la cadena codificada
      //Ahora con el objeto desplegamos los datos mandados desde el servidor
      document.getElementById("divId").innerHTML = objDatos.id;
      document.getElementById("divNombre").innerHTML = objDatos.nombre;
      document.getElementById("divCategoria").innerHTML = objDatos.categoria;
      document.getElementById("divPrecio").innerHTML = objDatos.precioDeSalida;
      document.getElementById("divDetalles").innerHTML = objDatos.detalles[0] + ", " + objDatos.detalles[1] + ", " + objDatos.detalles[2];
    } else {
      alert("Ocurrio un problema con la URL.");
    }
    http_request = null;
  }
}
</script>
</head>
<body>
<h2>Producto</h2>
<div id="divId"></div>
<div id="divNombre"></div>
<div id="divCategoria"></div>
<div id="divPrecio"></div>
<div id="divDetalles"></div>
</body>
</html>


Este código implementa una sencilla aplicación AJAX, similar a las vistas en los primero ejemplos sobre esta tecnología vistos en este blog. Básicamente accede a la aplicación en PHP que creamos previamente, y procesa el texto plano que recibe como respuesta, almacenándolo en la cadena, debido a que este texto consiste en la codificación en JSON del objeto original, lo decodifica utilizando la instrucción eval("(" + cadCodificadaJSON + ")"), creando el objeto objDatos como resultado.

El resultado obtenido se vería en el navegador como sigue:

Producto


1

Nintendo DS

Videojuego

$3 500

Soporta juegos para Gameboy advance, Pantalla tactil, Reproducción de MP3


De esta forma, podemos transmitir conjuntos de datos estructurados sin recurrir a formatos como XML o protocolos como SOAP, que requieren un mayor trabajo de procesamiento de la información en el cliente, pero que en contra parte, exige que el servidor pueda llevar a cabo la codificación de objetos en JSON. La elección final de la forma en que vayamos a transmitir los datos sobre HTTP, dependerá de los requerimientos que nos exijan la arquitectura y la plataforma que habremos de utilizar.

Saludos.

1 comentarios:

VictorR dijo...

Excelente, Gracias

Publicar un comentario