jueves, 29 de enero de 2009

Lo nuevo de PHP6


¡Saludos nuevamente blogueros!

Una disculpa por retrasar la salida del siguiente post, pero me tope con otro tema que creo vendría bien mencionarlo, además, como pueden ver anduve manipulando la hoja de estilo CSS, con la intención de mejorar la aparición de los códigos fuente en la página, ahora ya no aparecerán saltos de línea cuando una instrucción sobrepasaba la capacidad de la pantalla, sino que el código se mostrará tal cual gracias a una barra de desplazamiento. Espero que a todos los parezca un cambio para mejorar y de no ser así, me gustaría ver sus comentarios al respecto -aunque tendrá que ser muy convincente para hacerme meter reversa -.

En este post haré un pequeño paréntesis en el tema de Ajax, para hablar un poco sobre las novedades de la versión 6 de PHP, que este año recién hizo su aparición, y que ya podemos encontrar en las versiones más recientes de paquetes como el AppServ.

Éste será un post corto, porque considero que son pocos los puntos importantes que hay que tratar, ya que realmente se siguió con la tendencia que venía desde PHP5, de hecho algunas de las novedades ya se podían probar en la versión 5.3.

PHP6 = Unicode + PHP5

El gran logro que veo en ésta versión es que el núcleo de PHP finalmente utilizará Unicode de manera nativa, es decir que al momento de escribir nuestro código, ya no temeremos utilizar caracteres internacionales -es decir, que estén fuera del idioma inglés- en las cadenas que pasemos como parámetros a las funciones del lenguaje, lo cual es un avance importante ya que ayudará a estandarizar más nuestros programas.

¿Cómo podremos hacerlo?

Para habilitar el uso de Unicode en nuestros scripts de PHP6 tendremos que indicarlo en el archivo php.ini, bastará con realizar los siguiente ajustes en las líneas que se indican, primero configurando que trabajaremos en modo Unicode :
unicode.semantics = on
Y si por ejemplo deseamos utilizar la codificación UTF-8, deberemos configurar la codificación de datos de entrada y de salida para UTF-8 :
unicode.http_input_encoding = utf-8
unicode.output_encoding = utf-8
No es necesario escribir nuestros scripts de PHP en Unicode para obtener una salida Unicode, sin embargo, ciertamente esto haría las cosas más sencillas. Podremos indicar la codificación por defecto de nuestros scripts en la siguiente línea de php.ini:
unicode.script_encoding = utf-8
A partir de ahí, podremos escribir nuestros scripts en UTF-8 en el editor de texto de nuestra elección, ya que PHP asumirá que esta es la codificación de todos los scripts. La otra alternativa es escribir nuestro código con otra codificación de caracteres, pero indicándole a PHP la codificación que estamos utilizando con la instrucción declare. Por ejemplo si nuestro script fue escrito en ISO-8859-1, la instrucción deberá ser declare(encoding="iso-8859-1" ); (y esta tiene que se la primer línea de código PHP que se ejecute).

Otros puntos a considerar

En cuanto al resto, se eliminaron los lastres que se venían arrastrando desde la versión 3 de PHP, al eliminar de manera definitiva los Register Globals -registros globales-, lo cual en lo personal no me afecta mucho porque nunca los use, jeje. Se eliminaron también los Magic Quotes -comillas mágicas-. En la programación orientada a objetos, la instrucción var significará lo mismo que public al momento de procesarla. Las funciones ereg se movieron dentro de PECL. El resto de los detalles sobre todos los cambios que se incluyeron, los podrán encontrar aquí: Minutes PHP Developers Meeting

La información sobre la habilitación de Unicode los obtuve de ésta pagina Preparing yourself fot PHP6.

Hasta la próxima.

miércoles, 28 de enero de 2009

Combinando Ajax con PHP, Parte 2


En el último post quedó pendiente la implementación del programa en el servidor, en este caso la aplicación en PHP contenida en el archivo validaDatos.php, que es de los que nos ocuparemos ahora:

Programación del lado del servidor

En el post anterior declaramos algunas de las características de la aplicación PHP, entre estas se encuentra el recibir los datos por medio de las variables predefinidas de PHP, y generar una respuesta en formato HTML. A esto se añadirá que será evaluada la validez de los datos utilizando expresiones regulares, gracias a los cual se podrá incluir un mensaje de salida que indique el resultado de esta evaluación.

El código PHP que deberá incluir el archivo validaDatos.php es el siguiente:


<?
//Expresiones regulares para la validación de los datos
$er_titulo = "/^([a-z]|[A-Z]|[ÁÉÍÓÚáéíóúÑñÜü]|[0-9]|[\s\.\-,:'\"])+$/";
$er_autor = "/^([a-z]|[A-Z]|[ÁÉÍÓÚáéíóúÑñÜü]|[\s,\.'\-])+$/";
$er_anio = "/^([1-2][0-9][0-9][0-9])$/";
//Validamos que se hayan enviado todos los datos por post
if(isset($_POST['txtAutor']) && isset($_POST['txtAnio']) && isset($_POST['txtTitulo'])){
  //Validamos el contenido de los campos
  $autor = stripslashes(trim($_POST['txtAutor']));
  $anio = trim($_POST['txtAnio']);
  $titulo = stripslashes(trim($_POST['txtTitulo']));
  if(!preg_match($er_autor,$autor)){
    $campo = "autor";
  }
  else if(!preg_match($er_anio,$anio)){
    $campo = "año";
  }
  else if(!preg_match($er_titulo,$titulo)){
    $campo = "título";
  }
  else{
    $mensaje = "Todos los campos capturados son correctos :)";
  }
  if(isset($campo))
    $mensaje = "Error: El texto capturado en el campo $campo es incorrecto";
}
else{
  $mensaje = "No se recibieron los valores";
}
?>
<p><?=$mensaje?></p>
<p><u>Valores recibidos</u>:<br />
Autor: <?=$_POST['txtAutor']?><br />
Año: <?=$_POST['txtAnio']?><br />
Título: <?=$_POST['txtTitulo']?><br />
</p>

En sí es un programa sencillo de entender, pero podemos observar que en lugar de embedir el código PHP dentro del HTML, se separaron, dejando la parte del código HTML solo para desplegar el resultado de la evaluación y los valores de los datos recibidos, esta es una buena práctica para facilitar los mantenimientos posteriores a nuestros archivos php.

Al inicio del código observamos que aparecen declaradas tres variables:
$er_titulo = "/^([a-z]|[A-Z]|[ÁÉÍÓÚáéíóúÑñÜü]|[0-9]|[\s\.\-,:'\"])+$/";
$er_autor = "/^([a-z]|[A-Z]|[ÁÉÍÓÚáéíóúÑñÜü]|[\s,\.'\-])+$/";
$er_anio = "/^([1-2][0-9][0-9][0-9])$/";
Como vemos se trata de tres cadenas de texto, las cuales representan las expresiones regulares que utilizaremos para evaluar cada uno de los campos, así el campo título utilizará la expresión regular $er_titulo, la cual indica que solo podrá contener caracteres alfabéticos latinoamericanos, dígitos, espacios y algunos caracteres especiales.

En la siguiente línea se incluye una validación en la condición, con la que se verifica que todos los datos hayan sido recibidos antes de continuar con el proceso, utilizando la variable predefinida $_POST:
if(isset($_POST['txtAutor'])&&isset($_POST['txtAnio'])&& isset($_POST['txtTitulo']))
{
  ...

Una vez pasada ésta validación, alamacenamos los datos recibidos en sus respectivas variables:
$autor = stripslashes(trim($_POST['txtAutor']));
$anio = trim($_POST['txtAnio']);
$titulo = stripslashes(trim($_POST['txtTitulo']));
A los datos que se reciben -que son todos cadenas- se les aplica la función trim, para eliminar los espacios en blanco sobrantes al inicio y al final de cada una, así como la función stripslashes, para eliminar el caracter diagonal invertida "\", que en las versiones 5 y anteriores de PHP se agrega automáticamente, al encontrarse con los caracteres comilla simple y comilla doble, lo que se denomina comillas mágicas.

En las siguientes líneas de código es donde se lleva a cabo la validación de la información proporcionada:
if(!preg_match($er_autor,$autor)){
  $campo = "autor";
}
else if(!preg_match($er_anio,$anio)){
  $campo = "año";
}
else if(!preg_match($er_titulo,$titulo)){
  $campo = "título";
}
else{
  $mensaje = "Todos los campos capturados son correctos :)";
}
if(isset($campo))
  $mensaje = "Error: El texto capturado en el campo $campo es incorrecto";
En éstas condiciones se utiliza la función preg_match para evaluar si los datos proporcionados, cumplen con el patrón de su respectiva expresión regular. En caso contrario se guarda el nombre del campo para incluirlo en un mensaje de error.

En la sección donde encontramos el código HTML del archivo se desplegará un mensaje que indicará el resultado del proceso de evaluación, enseguida del cual se mostrarán los valores recibidos por $_POST.

Al almacenar el archivo validaEntradas.php en la raíz del directorio de páginas web de nuestro servidor, podemos probar el programa que creamos en el post anterior. Así, abrimos el archivo HTML y realizamos la captura de los datos en su formulario:



Al validar los datos, obtenemos el siguiente resultado:



En caso de capturar algún dato que no concuerde con las expresiones regulares que hemos establecido, tendremos un resultado como el siguiente:



De esta manera, combinamos la captura de datos en nuestro cliente con la validación del lado del servidor, para obtener un sencillo sistema de validación de entradas de un formulario.

Conclusiones

Hemos podido darnos cuenta de la capacidad que tiene Ajax para combinarse con otros sistemas, y crear aplicaciones más robustas en nuestros clientes Web, sin embargo, ésta apenas es la punta del iceberg de las capacidades que podemos alcanzar con Ajax, del lado del servidor se podría no solo llevar a cabo la validación de los datos sino también la actualización de una base de datos, además las respuestas que PHP puede devolver no se limitan a contenido HTML, éstas pueden ser también archivos XML, imágenes, archivos PDF o hasta animaciones Flash. Así que esto apenas comienza, en los siguientes post veremos como utilizar PHP para generar respuestas XML que serán procesadas en Ajax, y posteriormente veremos el manejo de bases de datos y la utilización de servicios Web.

Hasta la próxima

Combinando Ajax con PHP, Parte 1


En los ejemplos anteriores observamos como se puede solicitar un recurso a nuestro servidor Web para desplegar su información en la pantalla, además de archivos de texto simple o XML también podríamos haber solicitado una página HTML, pero la limitación de este proceso es que solo desplegamos información estática, si queremos que los recursos a los que accedamos puedan devolvernos una respuesta dinámica, es necesario contar con una aplicación del lado del servidor que permita arrojar resultados distintos, en las diferentes peticiones que se realicen. Una de las formas de lograrlo es accediendo a un servicio web o a una aplicación web, que pueden ser desarrolladas en distintos lenguajes de programación. En este ejemplo veremos como acceder a una pequeña aplicación web programada en PHP, y para hacerlo un poco más interactivo probaremos además enviar datos a esta aplicación, como parte de los parámetros de nuestra petición.

Principios a tener en cuenta:
  • En este caso tendremos que llevar a cabo dos programaciones, una en Javascript+Ajax en la página HTML desde la que realizaremos nuestra petición, que estará en nuestro cliente o navagador de Internet, y otra del lado del servidor que consistirá en la aplicación PHP.
  • Del lado del cliente los datos se enviarán como parte de la petición al servidor. Hay que tomar en cuenta que en una petición "el objeto XMLHttpRequest puede enviar parámetros tanto con el método GET como con el método POST de HTTP. En ambos casos, los parámetros se envían como una serie de pares clave/valor concatenados por símbolos &. El siguiente ejemplo muestra una URL que envía parámetros al servidor mediante el método GET:
    http://localhost/aplicacion?parametro1=valor1&parametro2=valor2
  • La principal diferencia entre ambos métodos es que mediante el método POST los parámetros se envían en el cuerpo de la petición y mediante el método GET los parámetros se concatenan a la URL accedida. El método GET se utiliza cuando se accede a un recurso que depende de la información proporcionada por el usuario. El método POST se utiliza en operaciones que crean, borran o actualizan información."[1]
  • Del lado del servidor se tendrá un archivo llamado validaDatos.php, en el que se obtendrán los datos por medio de las variables predefinidas de PHP, y dependiendo del tipo de dato recibido se generará una respuesta de salida como parte del contenido de una página HTML.
Programación del lado del cliente:

Los datos que enviaremos como parte de la petición se tomaran de un formulario HTML, y se incluirán en una cadena de texto estructurada, que se enviará como parte de la petición al servidor web, esta cadena recibe el nombre de consulta (query).

El código HTML para este formulario aparece a continuación, dentro de éste no se incluye el código Javascript para llevar a cabo la petición con Ajax, pero se indica el lugar en el que se deberá colocar posteriormente, esto se hace así para explicar con más calma el ejemplo:


<!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>Tercer ejemplo con Ajax, combinándolo con PHP</title>
<script language="javascript">
<!--Sitio del código Javacript-->
</script>
</head>
<body>
<form>
<label for="txtAutor">Autor:</label>
<input type="text" id="txtAutor" name="txtAutor" size="40" /><br/>
<label for="txtAnio">Año:</label>
<input type="text" id="txtAnio" name="txtAnio" size="10" /><br/>
<label for="txtTitulo">Títiulo:</label>
<input type="text" id="txtTitulo" name="txtTitulo" size="50" /><br/>
<input type="button" value="Validar datos" onclick="valida()" />
</form>
<div id="divRespuesta"></div>
</body>
</html>


En ésta ocasión utilizaremos el conjunto de caracteres UTF-8 para la codificación de nuestros archivos, lo cual aparece señalado por el campo chaset en el encabezado de la página HTML. Como podemos ver el formulario consiste en tres cuadros de texto señalados con etiquetas y un botón a través del cual se iniciará el proceso, que tiene una apariencia como la siguiente:


Ahora bien, el código Javascript que utilizaremos iniciará su ejecución al hacer clic sobre el botón "Validar datos", por lo que antes de indicar éste evento en el botón deberemos incluir dentro de las etiquetas <script>...</script> el siguiente programa:


var READY_STATE_COMPLETE=4;
var peticionHttp = null;
//Función que devuelve el objeto de la clase XMLHttpRequest
function inicializaXhr() {
if(window.XMLHttpRequest) {
return new XMLHttpRequest();
}
else if(window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
//Función que crea la cadena con los parámetros de la petición POST
function creaCadenaDeDatos() {
var autor = document.getElementById("txtAutor");
var anio = document.getElementById("txtAnio");
var titulo = document.getElementById("txtTitulo");
return "txtAutor=" + encodeURIComponent(autor.value) + "&txtAnio=" + encodeURIComponent(anio.value) + "&txtTitulo=" + encodeURIComponent(titulo.value) + "&nocache=" + Math.random();
}
//Función que inicia todo el proceso y lleva a cabo la petición al servidor
function valida() {
peticionHttp = inicializaXhr();
if(peticionHttp) {
peticionHttp.onreadystatechange = procesaRespuesta;
peticionHttp.open("POST", "http://localhost/validaDatos.php", true);
peticionHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
var cadenaDeDatos = creaCadenaDeDatos();
peticionHttp.send(cadenaDeDatos);
}
}
//Función que procesa la respuesta HTML del servidor Web
function procesaRespuesta() {
if(peticionHttp.readyState == READY_STATE_COMPLETE) {
if(peticionHttp.status == 200) {
document.getElementById("divRespuesta").innerHTML = peticionHttp.responseText;
}
}
}


Dentro del código nos encontramos con una refactorización de algunos pasos, lo cual obedece a facilitar su utilización a partir de este ejemplo y los que sigan, facilitando además el mantenimiento de estos programas. En el nuevo código fuente vemos que al inicio se declaran dos variables globales:
var READY_STATE_COMPLETE=4;
var peticionHttp = null;
La variable READY_STATE_COMPLETE se utiliza como una constante, que servirá para comprobar que el estado de la respuesta del servidor se encuentra completa en la función procesaRespuesta que veremos más adelante, debido a que en éste ejemplo solo nos intereza el estado completo de la respuesta no declaramos los otros 4 posibles estados (no inicializada , cargando, cargada e interactiva). La segunda variable global es peticionHttp, al igual que la anterior podrá ser accedida por todas las funciones del programa, y al iniciarse el proceso -como en los ejemplos anteriores- se convertirá en el objeto a través del cual llevaremos a cabo la petición al servidor. La segunda refactorización importante consiste en la creación de la función inicializaXhr:
function inicializaXhr() {
if(window.XMLHttpRequest) {
return new XMLHttpRequest();
}
else if(window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
Esta función se utilizará se emplea para encapsular la creación del objeto XMLHttpRequest, incluyendo la validación de compatibilidad y devolviendo la instancia de la clase XMLHttpRequest. De modo que bastará con inicializar una variable con el resultado devuelto para tener creado nuestro objeto XMLHttpRequest.
function creaCadenaDeDatos() {
var autor = document.getElementById("txtAutor");
var anio = document.getElementById("txtAnio");
var titulo = document.getElementById("txtTitulo");
return "txtAutor="+encodeURIComponent(autor.value)+"&txtAnio="+ encodeURIComponent(anio.value)+"&txtTitulo="+encodeURIComponent(titulo.value) + "&nocache=" + Math.random();
}
La función creaCadenaDeDatos obtiene los datos del formulario, accediendo a cada uno de sus elementos por medio de sus identificadores, creando un objeto del DOM para cada uno, lo cual permite utilizar su propiedad value y obtener los valores capturados por el usuario, con el propósito de concatenarlos en una cadena. Estos valores son codificados para formar una URI válida antes de ser concatenados. Esta cadena representa los parámetros que serán enviados al servidor, contando con las parejas clave/valor separadas por el caracter ampersand "&" como habíamos mencionado en las notas iniciales. Una vez concatenada la cadena ésta es devuelta como la respuesta de la función.

La siguiente función que aparece, llamada valida, en donde se iniciará todo el proceso y se llevara a cabo la petición al servidor:
function valida() {
peticionHttp = inicializaXhr();
if(peticionHttp) {
...
Al inicio de la función valida se lleva a cabo la creación del objeto de la clase XMLHttpRequest , que será peticionHttp como ya habíamos mencionado. Después realizamos una validación para comprobar que el objeto se haya instanciado correctamente, por medio de la condición que aparece. En las siguientes dos líneas:
peticionHttp.onreadystatechange = procesaRespuesta;
peticionHttp.open("POST", "http://localhost/validaDatos.php", true);
Indicamos que cuando el servidor regrese la respuesta a la petición se ejecute la función procesaRespuesta. En la segunda línea indicamos que el tipo de petición será POST, que la dirección URL del recurso solicitado es "http://localhost/validaDatos.php" y que la petición será asíncrona. La clave del envio de datos al servidor se encuentra en las siguientes tres líneas:
peticionHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
var cadenaDeDatos = creaCadenaDeDatos();
peticionHttp.send(cadenaDeDatos);

El método setRequestHeader en este caso establece que se enviará un encabezado como parte de la petición que incluye un Content-Type de tipo application/x-www-form-urlencoded, es decir que le indica al servidor que los datos que se están enviando en la petición son del tipo indicado por éste segundo parámetro. De no indicarse el tipo de contenido por medio de este método o al hacerlo de manera incorrecta, el servidor descartará todos los datos que sean enviados dentro de la petición HTTP. Así, para enviar parámetros mediante el método POST, es obligatorio incluir el encabezado Content-Type mediante éste método.

Los parámestros que serán enviados se obtienen por medio del método creaCadenaDeDatos y se almacenan en cadenaDeDatos, el método send recibe ésta cadena envía su contenido como parámetros al servidor.

La función procesaRespuesta se encargará de desplegar la información devuelta por la página PHP y es similiar a las que ya habiamos utilizado para este propósito, añadiendose la variable READY_STATE_COMPLETE para comprobar el estado de la respuesta.
document.getElementById("divRespuesta").innerHTML = peticionHttp.responseText;
Solo que en este caso todo la información será desplegada dentro del elemento "divRespuesta" de la página HTML.

Una vez que agregamos éste código Javascript a nuestro archivo HTML bastará con incluir en el botón "Validar datos" la llamada a la función valida() en su evento onclick, es decir:
<input type="button" value="Validar datos" onclick="valida()" />
para tener finalizada la programación del lado del cliente en este ejemplo.

Ahora solo necesitamos implementar el progrmaa PHP que contedrá el archivo validarDatos.php que se alojará en nuestro servidor Web, pero ese será el contenido de la segunda parte de este tema, que veremos en el siguiente post.

Hasta la próxima.

Referencias.
[1]Introducción a Ajax. Javier Equíluz Pérez. Junio de 2008.


lunes, 26 de enero de 2009

Accediendo a un archivo XML con Ajax


En el post anterior vimos un ejemplo sencillo del uso de Ajax, veamos que más podemos hacer:

Supongamos que deseamos acceder a un archivo de texto estructurado, en este caso un archivo XML, que contenga la información de una serie de elementos que queremos desplegar en nuestra página web.

Para el ejemplo, el archivo XML al que vamos a acceder tendrá una estructura como la que se muestra a continuación:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<Obras_literarias>
  <Libro>
     <Autor>Juan Rulfo</Autor>
     <Titulo>Pedro Páramo</Titulo>
  </Libro>
  <Libro>
     <Autor>Juan Rulfo</Autor>
     <Titulo>El Llano en Llamas</Titulo>
  </Libro>
  <Libro>
     <Autor>Pablo Neruda</Autor>
     <Titulo>Veinte poemas de amor y una canción desesperada</Titulo>
  </Libro>
  <Libro>
     <Autor>Miguel de Cervantes Saavedra</Autor>
     <Titulo>Don Quijote de la Mancha</Titulo>
  </Libro>
  <Libro>
     <Autor>Jorge Luis Borges</Autor>
     <Titulo>Ficciones</Titulo>
  </Libro>
</Obras_literarias>

Este archivo, que podemos crear en un editor de texto sencillo como el bloc de notas, recibirá el nombre listaX.xml. Posee una estructura XML algo simple, ya que solo contiene una serie de entradas denominadas elementos sin contar con algún atributo. Más que nada se trata de una lista de libros con sus autores y títulos, que -como en todo archivo XML- se encuentra estructurada en una jerarquía de árbol, en las que el elemento padre -más externo- puede contener contener uno o más elementos hijos -más internos-

Ahora nuestro código Ajax solicitará al servidor Web que le sea devuelto éste archivo de texto, y una vez que el contenido haya sido recibido, el programa procesará la información utilizando un objeto de tipo documento XML, de forma que el contenido podrá ser procesado con métodos DOM para documentos XML, es decir, que el documento XML será manejado como un objeto y poseerá sus propios métodos y propiedades. De modo que crearemos un nuevo archivo HTML basándonos en el código del primer ejemplo con los siguientes cambios:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/
xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Obtener lista XML de autores con Ajax</title>
<script type="text/javascript">
function descargaArchivo() {
  // Obtener la instancia del objeto XMLHttpRequest
  if(window.XMLHttpRequest) {
     peticionHttp = new XMLHttpRequest();
  }
  else if(window.ActiveXObject) {
    peticionHttp = new ActiveXObject("Microsoft.XMLHTTP");
  }
  // Preparar la funcion de respuesta
  peticionHttp.onreadystatechange = muestraContenido;
  // Realizar peticion HTTP
  peticionHttp.open('GET', 'http://localhost/listaX.xml', true);
  peticionHttp.send(null);
  function muestraContenido() {
    if(peticionHttp.readyState == 4) {
      if(peticionHttp.status == 200) {
        //Creamos el objeto de tipo documento XML
        var documentoXml = peticionHttp.responseXML;
        //Obtenemos la raíz del documento
        var root = documentoXml.getElementsByTagName("Obras_literarias")[0];
        var tope = root.getElementsByTagName("Libro").length;
        //Recorremos todos los elementos Libro del documento
        for(var i = 0; i < tope; i++){
          libro = root.getElementsByTagName("Libro")[i];
          autor = libro.getElementsByTagName("Autor")[0].firstChild.nodeValue;
          titulo = libro.getElementsByTagName("Titulo")[0].firstChild.nodeValue;
          muestraHTML('pRespuesta',"Autor: "+autor+", t&iacute;tulo: "+titulo+"<br/>");
        }
      }
    }
  }
  function muestraHTML(id, texto){
    if(document.getElementById){
      document.getElementById(id).innerHTML += texto;
    }
  }
}
window.onload = descargaArchivo;
</script>
</head>
<body>
<p id="pRespuesta"></p>
</body>
</html>

Podemos ver que el proceso ver que el proceso de petición del archivo es casi idéntico al del ejemplo anterior, con la diferencia del nombre del archivo solicitado al servidor Web:
peticionHttp.open('GET', 'http://localhost/listaX.xml', true);

La parte interesante se da al momento de procesar la respuesta dentro de la función muestraContenido, cuando se accede al contenido del archivo XML:

var documentoXml = peticionHttp.responseXML;

En ésta primer línea utilizamos la propiedad responseXML para crear un objeto que manejará la información del documento XML llamado documentoXML. Siguiendo con el código:
var root = documentoXml.getElementsByTagName("Obras_literarias")[0];
var tope = root.getElementsByTagName("Libro").length;

En la primer línea se crea un nuevo objeto llamado root que contendrá la raíz del documento XML, es decir el elemento padre Obras_literarias, y a partir de éste objeto accederemos al resto de la información del documento. En la segunda línea guardamos en la variable tope la cantidad total de elementos hijo Libro que contiene root por medio de su propiedad length.
for(var i = 0; i < tope; i++){
   libro = root.getElementsByTagName("Libro")[i];
   autor = libro.getElementsByTagName("Autor")[0].firstChild.nodeValue;
   titulo = libro.getElementsByTagName("Titulo")[0].firstChild.nodeValue;
   muestraHTML('pRespuesta',"Autor: "+autor+", t&iacute;tulo: "+titulo+"<br/>");
}

Ésta parte del código consiste en un sencillo ciclo for que recorrerá todos los elementos Libro del objeto root. Con cada elemento Libro se creará un objeto llamado libro, después obtendremos el contenido de los elementos Autor y Titulo de este objeto, almacenando el valor de sus contenidos en las variables autor y titulo respectivamente. Por último, una vez que tenemos estos valores los mostramos en nuestra página web por medio de la función muestraHTML, cuya explicación aparece a continuación:
function muestraHTML(id, texto){
  if(document.getElementById){
    document.getElementById(id).innerHTML += texto;
  }
}

Ésta función recibe como primer parámetro el identificador del elemento de la página HTML, en el que se mostrará el texto que recibe como segundo parámetro.

Una vez que creamos el archivo listaX.xml, lo almacenamos en el servidor Web e implementamos el código HTML que acabamos de revisar, al momento de probar este programa debemos obtener en la pantalla de nuestro navegador un resultado como el que se muestra a continuación:

Autor: Juan Rulfo, título: Pedro Páramo
Autor: Juan Rulfo, título: El Llano en Llamas
Autor: Pablo Neruda, título: Veinte poemas de amor y una canción desesperada
Autor: Miguel de Cervantes Saavedra, título: Don Quijote de la Mancha
Autor: Jorge Luis Borges, título: Ficciones

Donde apreciamos como se accedió correctamente a cada uno de los elementos con contenido de texto del archivo, formándose una lista sencilla de autores y obras literarias.

La importancia de éste segundo ejemplo radica en que al utilizar Ajax, muchas veces es útil obtener respuestas en formato XML, para poder conseguir información más estructurada de nuestro servidor Web y no solo texto simple, sobre todo al momento de combinar Ajax con lenguajes del lado de servidor como PHP y trabajar con bases de datos. A medida que vayamos avanzando en el manejo de Ajax y veamos ejemplos más avanzados, se verá el potencial del manejo de respuestas XML.

En el ejemplo de nuestro siguiente post, veremos como se puede combinar Ajax con PHP, para desde un formulario HTML enviar datos al servidor Web que serán procesados en un programa PHP.

Hasta la próxima.

viernes, 23 de enero de 2009

Más notas sobre Ajax


Un resultado muy común en Internet al buscar información sobre Ajax

Como una nota adicional, podemos darnos cuenta que el nombre Asynchronous proviene precisamente de que en la práctica, Ajax es utilizado solo en modo asíncrono, por la ventaja que ya mencionamos.

Pero vayamos al primer ejemplo:

Nota: Ajax fue introducido en el navegador Internet Explorer como un ActiveX y se mantuvo así en sus versiones 5 y 6, siendo hasta la versión 7 que se incorporó de forma nativa por medio de la clase HttpXMLRequest (como lo hacen los navegadores Firefox, Safari y Opera), pero por motivos de compatibilidad con versiones obsoletas de Internet Explorer, en los ejemplos se consideraran ambos casos.

Para nuestro primer ejemplo, supongamos que en un servidor Web tenemos un archivo de texto al que deseamos acceder, llamado lista.txt, que contiene una lista de nombres como la que aparece a continuación:
Juan Rulfo
Octavio Paz
Pablo Neruda
Miguel de Cervantes Saavedra
Jorge Luis Borges
Para hacer la prueba de manera local es necesario contar con un servidor Web funcionando en nuestro sistema, una buena opción es el servidor Apache, que pueden instalar utilizando un paquete como el AppServ, el cual en lo personal me gusta mucho porque además ya trae consigo el CGI de PHP, el servidor MySQL y el phpMyAdmin.

Entonces implementaremos un programa en Javascript que nos permita acceder a este archivo por medio de Ajax, y desplegarlo en nuestro navegador. Para ello crearemos un archivo HTML que contenga el siguiente código:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Obtener lista de autores con Ajax</title>
<script type="text/javascript">
function descargaArchivo() {
  // Obtener la instancia del la clase XMLHttpRequest
  if(window.XMLHttpRequest) {
    peticionHttp = new XMLHttpRequest();
  }
  else if(window.ActiveXObject) {
    peticionHttp = new ActiveXObject("Microsoft.XMLHTTP");
  }
  // Preparar la funcion de respuesta
  peticionHttp.onreadystatechange = muestraContenido;
  // Realizar peticion HTTP
  peticionHttp.open('GET','http://localhost/lista.txt',true);
  peticionHttp.send(null);

  function muestraContenido() {
    if(peticionHttp.readyState == 4) {
      if(peticionHttp.status == 200) {
        alert(peticionHttp.responseText);
      }
    }
  }
}
window.onload = descargaArchivo;
</script>
</head>
<body></body>
</html>

Ahora analicemos el código Javascript, primero tenemos la función descargaArchivo donde ocurrirá todo el proceso, dentro de ésta encontramos dos condiciones:
if(window.XMLHttpRequest) {
  peticionHttp = new XMLHttpRequest();
}
else if(window.ActiveXObject) {
  peticionHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
En estas instrucciones comprobamos si el navegador que estamos usando posee la clase HttpXMLRequest de forma nativa o si lo hace por medio de un ActiveX -en el caso de los navegadores obsoletos-, ésta comprobación la realizamos por motivos de compatibilidad como habíamos indicado en un principio. En ambos casos se crea un objeto llamado peticionHttp que es una instancia de la clase XMLHttpRequest, este objeto se encargará de llevar a cabo la petición asíncrona del recurso -en este caso el archivo de texto lista.txt- a nuestro servidor Web.
peticionHttp.onreadystatechange = muestraContenido;
Éste bloque del código le indica al objeto peticionHttp que una vez que el servidor Web envíe la respuesta la función muestraContenido sea ejecutada.
peticionHttp.open('GET', 'http://localhost/lista.txt', true);
peticionHttp.send(null);
En estas dos lineas de código es donde por fin vemos funcionar a Ajax, la primera instrucción crea una petición HTTP al servidor Web por medio del método open, donde por medio de los parámetros se indica que la petición es de tipo GET, la URL solicitada es http://localhost/lista.txt y el tercer parámetro que vale true determina que la petición será asíncrona. En la segunda línea se indica que no se enviaran datos al servidor Web junto con la petición, al establecer el valor null en el método send. Al ser ésta una petición asíncrona el navegador no se quedará congelado en espera de que el servidor Web responda, por lo que después de estas líneas podría seguir código adicional que continuaría ejecutándose, y más importante aún es que con Ajax el usuario podrá seguir utilizando los componentes de la página Web, mientras se realiza la respuesta del servidor.
function muestraContenido() {
  if(peticionHttp.readyState == 4) {
    if(peticionHttp.status == 200) {
    alert(peticionHttp.responseText);
    }
  }
}
Como dijimos ésta función se ejecutara en el momento en el que el objeto peticionHttp reciba unas respuesta del servidor Web, primero se confirma que se haya recibido la respuesta con la propiedad readyState, después se confirma que sea una respuesta válida y correcta -comprobando si el código de estado HTTP devuelto es igual a 200-, y finalmente se muestra el contenido de la respuesta recibida -en este caso el contenido del archivo lista.txt- en la pantalla con la función alert que despliega la propiedad responseText.
window.onload = descargaArchivo;
Esta última instrucción será ejecutada en cuanto el navegador procese nuestra página HTML, la cual le indica al navegador que al iniciar la carga del contenido ejecute la función descargaArchivo.

Al llevar a cabo la prueba de nuestra primera aplicación con Ajax, debemos obtener un resultado en la pantalla del navegador como el que aparece a continuación:



jueves, 22 de enero de 2009

Mis notas sobre Ajax


Hola a todos los blogueros de la red, ésta es mi primer aportación al mundo de los diarios personales en línea y espero que sea la primera de muchas más. Hacía tiempo que tenía el deseo de iniciar mi propio blog pero me atacaban las dudas que ya todos conocen ¿de qué va a tratar? ¿como lo organizaré? ¿quién rayos me va a leer?, pero gracias a un proyecto en el que estoy participando finalmente disipe todas esas dudas, ya que no tenía otra alternativa jaja.

Ahora que ya pasó la presentación pasemos a el objetivo de este mensaje, que es hablar un poco sobre Ajax (acrónimo de Asynchronous JavaScript And XML dice la santa Wikipedia), para los programadores no tan expertos que ya hayan tenido contacto con el desarrollo de páginas web, este término les será conocido, como lo era para mí, pero realmente hace poco que comencé a adentrarme en el uso de esta herramienta, así que espero que a todos los programadores que les interese comenzar a aprender sobre Ajax les sirvan las anotaciones que haga, entonces:

  • Primero que nada me refiero a él como una herramienta, porque Ajax realmente es un componente que fue incorporado al lenguaje Javascript y no es un nuevo lenguaje de programación en sí, como algunos podrían esperar -sí, yo también me decepcioné al principio- pero viendo el lado bueno, resulta mucho más rápido aprender a utilizarlo si ya tenias un conocimiento de Javascript, pudiendo incorporar nueva funcionalidad a los scripts que ya realizabas es éste último. Por lo tanto:
  • Segundo, si tuviera que hacer una definición de lo que es Ajax diría que "es un componente del lenguaje Javascript que nos permite realizar peticiones de recursos web normalmente de forma asíncrona", ¿Qué significa todo este rollo? que desde un script en Javascript que es ejecutado en nuestro cliente o navegador, podemos acceder al contenido de otras páginas y a otros tipos de recursos web, sin tener que recargar la página desde la que se está ejecutando este código, por medio de los métodos que ofrece una clase llamada XMLHttpRequest, y podemos hacerlo de manera síncrona o asíncrona, siendo esta última las más común, ya que evita que nuestro navegador se quede colgado en la espera de las respuesta, esto que estoy diciendo se verá más claro cuando veamos unos ejemplos en el siguiente post.
  • Tercero, todo lo que necesitas para utilizar Ajax es tener conocimientos de diseño de páginas HTML y de programación en Javascript, fuera de eso solo es necesario un simple editor de texto para escribir tus scripts y un navegador de Internet para probar su funcionamiento, yo recomiendo Mozilla Firefox, pero también están Internet Explorer, Opera o Safari, entre otros. Si quieres una herramienta más avanzada para editar tus scripts puedes utilizar el Notepad++, o un entorno de desarrollo más completo como Dreamweaver o Eclipse; tanto Notepad++ como Eclipse son herramientas de software completamente gratuitas que puedes descargar desde los enlaces indicados -en el caso de Eclipse tienen que elegir el sistema operativo con el que trabajan-.
  • Cuarto, no se olviden de la sabiduría de los libros, existe un libro introductorio muy bueno que pueden consultar y descargar en línea, de manera totalmente gratuita y español que encontraran en este sitio www.librosweb.es .
  • Pasando a cuestiones más técnicas, como ya dijimos Ajax forma parte del lenguaje Javascript y realiza peticiones de recursos web, ésto significa que se comunica con un servidor Web y le puede solicitar que le regrese un simple archivo de texto o una página HTML, y hasta puede ejecutar servicios Web. Al comunicarse con los servidores para pedirles alguno de estos recursos utiliza el protocolo HTTP, y tanto las peticiones como respuestas pueden estar codificadas en el lenguaje XML, pero no es un requisito que sea así, todo depende del tipo de consulta que deseemos realizar y del tipo de respuesta que esperemos del servidor. La siguiente imagen muestra de manera muy básica el proceso de las peticiones:
  • así, el script Javascript que se encuentra en el navagador (Web Browser) realiza una peticion al servidor (Server) por medio de una solicitud también llamada consulta (query), tras lo cual el servidor regresa una respuesta (answer).
  • Y por último, lo mejor de todo es que solo tenemos que aprender a utilizar la clase XMLHttpRequest, creando instancias de ésta clase llamados objetos XMLHttpRequest. Para el primer ejemplo que planeo mostrar serán necesario al menos otro post, por lo que espero que tengan un poco de paciencia al ser éste mi primer blog y no disponer de todo el tiempo del mundo, pero espero al menos haber llamado su atención para que me sigan leyendo.