21 - De PHP a JSON (utilizando la librería JSON.php)


En el concepto anterior habíamos visto como generar un archivo con formato JSON en el servidor y enviárselo al cliente (navegador). Esta metodología de generar el string con formato JSON puede ser muy engorroso cuando las estructuras comienzan a ser más complejas.

Se cuenta con una clase que transforma vectores y clases de PHP a formato JSON en forma automática.

Para ver esta librería llamada JSON.php confeccionaremos un problema que rescate un conjunto de registros de una tabla MySQL y seguidamente los transforme en formato JSON. En el navegador mediante eval generaremos un vector JavaScript y procederemos a mostrarlo.

Como podemos observar mientras sea más compleja la estructura a generar, más propenso a errores será la generación.

El problema que resolveremos es el siguiente:
Se tiene una tabla llamada "perifericos" donde almacenamos el código, descripción y precio de distintos periféricos de computadoras. Generar un archivo JSON en el servidor y proceder a mostrar los datos de los periféricos en el navegador.

pagina1.html:

<html>
<head>
<title>Problema</title>
<script src="funciones.js" language="JavaScript"></script>
</head>
<body>
<h2>Recuperar datos del servidor almacenados en una base de datos en formato 
JSON utilizando la librería JSON.php</h2>
<br>
<input type="button" value="Recuperar" id="boton1">
<div id="resultados"></div>
</body>
</html> 

Este archivo no tiene nada nuevo.

Lo más interesante y nuevo se presenta en el archivo pagina1.php:

<?php
$conexion=mysql_connect("localhost","root","z80") 
  or die("Problemas en la conexion");
mysql_select_db("bdajax",$conexion) 
  or die("Problemas en la seleccion de la base de datos");
$registros=mysql_query("select codigo,descripcion,precio from perifericos",$conexion) 
  or die("Problemas en el select".mysql_error());
while ($reg=mysql_fetch_array($registros))
{
  $vec[]=$reg;
}

require('../JSON.php');
$json=new Services_JSON();
$cad=$json->encode($vec);
echo $cad;
?>

Lo primero que hacemos es guardar todos los registros de la tabla perifericos en el vector llamado $vec, esto mediante el ciclo:

while ($reg=mysql_fetch_array($registros))
{
  $vec[]=$reg;
}

Ahora debemos incluir el archivo llamado "JSON.php" y crear un objeto de la clase services_JSON:

require('../JSON.php');
$json=new Services_JSON();

El archivo yo lo almacené en una carpeta que se encuentra inmediatamente en el nivel superior, por eso la sintaxis ../

Luego el método que automáticamente convierte el vector PHP en formato JSON es:

$cad=$json->encode($vec);

Ahora ya tenemos en la variable $cad el contenido del vector en formato JSON.

Procedemos seguidamente a la salida de esta cadena:

echo $cad;

Tengamos en cuenta que las cuatro líneas presentadas anteriormente nos evitan tener que generar la cadena en formato JSON en forma manual como podemos ver seguidamente:

$cad='[';
while ($reg=mysql_fetch_array($registros))
{
  $cad.="{'codigo':'".$reg['codigo']."',";
  $cad.="'descripcion':'".$reg['descripcion']."',";
  $cad.="'precio':'".$reg['precio']."'},";
}
$cad.=']';
echo $cad;

Este metodología es engorrosa y propensa a errores.

Luego el archivo JavaScript es:

addEvent(window,'load',inicializarEventos,false);

function inicializarEventos()
{
  var ob=document.getElementById('boton1');
  addEvent(ob,'click',presionBoton,false);
}

var conexion1;
function presionBoton(e)
{
  conexion1=crearXMLHttpRequest();
  conexion1.onreadystatechange = procesarEventos;
  conexion1.open('GET','pagina1.php', true);
  conexion1.send(null);
}

function procesarEventos()
{
  var resultados = document.getElementById("resultados");
  if(conexion1.readyState == 4)
  {
    alert('Cadena en formato JSON:  '+conexion1.responseText);

    var datos=eval("(" + conexion1.responseText + ")");
    var salida='';
    for(f=0;f<datos.length;f++)
    {
      salida += 'Codigo:'+datos[f].codigo+"<br>";
      salida += 'Descripcion:'+datos[f].descripcion+"<br>";
      salida += 'Precio:'+datos[f].precio+"<br><br>";
    }
    resultados.innerHTML = salida;
  } 
  else 
  {
    resultados.innerHTML = "Cargando...";
  }
}

//***************************************
//Funciones comunes a todos los problemas
//***************************************
function addEvent(elemento,nomevento,funcion,captura)
{
  if (elemento.attachEvent)
  {
    elemento.attachEvent('on'+nomevento,funcion);
    return true;
  }
  else  
    if (elemento.addEventListener)
    {
      elemento.addEventListener(nomevento,funcion,captura);
      return true;
    }
    else
      return false;
}

function crearXMLHttpRequest() 
{
  var xmlHttp=null;
  if (window.ActiveXObject) 
    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
  else 
    if (window.XMLHttpRequest) 
      xmlHttp = new XMLHttpRequest();
  return xmlHttp;
}

La función procesarEventos rescata los datos envidos por el servidor y los muestra inicialmente tal como llegan en una ventana mediante el comando alert:

    alert('Cadena en formato JSON:  '+conexion1.responseText);

Podemos ver que se trata de un string JSON correctamente formado.

Ahora sí mediante el comando eval procedemos a generar un vector JavaScript y mostramos los datos dentro de un div:

    var datos=eval("(" + conexion1.responseText + ")");
    var salida='';
    for(f=0;f<datos.length;f++)
    {
      salida += 'Codigo:'+datos[f].codigo+"<br>";
      salida += 'Descripcion:'+datos[f].descripcion+"<br>";
      salida += 'Precio:'+datos[f].precio+"<br><br>";
    }
    resultados.innerHTML = salida;

Para este problema posiblemente es más fácil generar un trozo de HTML en el servidor y en el navegador solo mostrarlo, pero hay muchas situaciones que necesitamos recuperar una estructura de datos del servidor y proceder a su procesamiento en el navegador.