This course will become read-only in the near future. Tell us at community.p2pu.org if that is a problem.

Agrega un toque de AJAX



Nuestro guestbook está trabajando bastante bien. Sin embargo, todavía hay una cosa que podemos hacer para mejorarlo: Ahora mismo, si dos usuarios tienen la página abierta y uno de ellos escribe algo, el otro usuario tendría que darle refresh al browser para ver el nuevo mensaje (puedes hacer la prueba abriendo la página en dos tabs diferentes).

Sin embargo, usando un poquito de AJAX podríamos hacer que la página automáticamente busque los mensajes nuevos y los agregue al muro, sin tener que darle refresh al browser. Esto es lo que hacen páginas como Facebook y Twitter.

¿Qué es AJAX y cómo funciona?

El término AJAX proviene de Javascript y XML asíncrono (hoy día AJAX puede funcionar sin XML, pero se sigue usando este acrónimo por tradición).

AJAX es la técnica de intercambiar información con nuestro servidor web utilizando Javascript, que es un lenguaje de programación que se ejecuta en el navegador (Javascript es un tema inmenso por sí solo, en este taller solo lo veremos por encima).

Quiero los últimos mensajes

Nuestra aplicación va a funcionar de la siguiente manera:

Cuando la página carga va a mostrar todos los mensajes que se han publicado hasta el momento. Luego, utilizaremos AJAX para comunicarnos con el servidor cada 15 segundos y preguntarle si hay mensajes nuevos por agregar al muro.

Nota: Esta es una práctica que se conoce como "javascript polling". Hay otras técnicas que nos permiten conseguir el mismo resultado sin consumir tantos recursos, pero requieren de más trabajo y conocimientos.

Para empezar, vamos a crear un script en PHP que solo nos muestre los mensajes que se han publicado después de una fecha específica. El archivo se llamará 'mensajes_desde.php' y tomará un parámetro mediante GET llamado fecha, de esta manera:

http://midominio.com/mensajes_desde.php?fecha=2012-02-13 11:30:22
 

Crea un archivo llamado 'mensajes_desde.php' y agrega el siguiente código:

<?php  
  //Validar que se haya mandado una fecha
  if(!$_GET[fecha]) {
    die('Se debe especificar una fecha.');
  }

  //Convertir la fecha a timestamp
  $fecha = strtotime($_GET[fecha]);
  if(!$fecha) {
    die('Formato incorrecto para la fecha.');
  }

  // Datos para la conexion
  $host = 'mysql_host';
  $database = 'mysql_database';
  $username = 'mysql_user';
  $password = 'mysql_pd';
  
  // Conectarse a MySQL
  $link = mysql_connect($host, $username, $password);
  if (!$link) {
      die('Error al conectarse a mysql: ' . mysql_error());
  }
  
  // Seleccionar nuestra base de datos
  $db_selected = mysql_select_db($database, $link);
  if (!$db_selected) {
      die ('Error al abrir la base de datos: ' . mysql_error());
  }
  
  // Buscar todos los mensajes desde la fecha especificada
  $query = sprintf("SELECT * from guestbook WHERE fecha_publicacion > '%s' 
    ORDER BY fecha_publicacion DESC", strftime('%F %H:%M:%S', $fecha));
  $result = mysql_query($query);
  if (!$result) {
    die('Query invalido: ' . mysql_error());
  }

  // Desplegar cada comentario como HTML
  while ($fila = mysql_fetch_assoc($result)) {
    echo sprintf('
      <div class="mensaje">
        <p><span class="autor">%s:</span> %s</p>
        <p class="fecha">%s</p>
      </div>',
      htmlspecialchars($fila['nombre']), 
      htmlspecialchars($fila['mensaje']), 
      $fila['fecha_publicacion']
    );
  }

  mysql_free_result($result);
?>

(Recuerda que debes cambiar los datos de conexión para usar los valores de tu hosting.)

Si vemos el código nos daremos cuenta que empezamos validando dos cosas:

  1. Que el parámetro $_GET[fecha] no esté en blanco.
     
  2. Que la fecha tenga el formato correcto. Para esto utilizamos la función strtotime(), que da falso si PHP no puede convertir la fecha a timestamp.
     

El resto del código es idéntico a nuestro programa anterior, con la excepción del query:

$query = sprintf("SELECT * from guestbook WHERE fecha_publicacion > '%s' 
    ORDER BY fecha_publicacion DESC", strftime('%F %H:%M:%S', $fecha));
 

Como puedes observar, agregamos el comando WHERE para decirle a MySQL que solo nos muestre los mensajes que se hayan publicado después de la fecha que le estamos dando.

Nuestro archivo 'mensajes_desde.php' debe quedar funcionando de esta manera. Fíjate que si le cambias el parámetro fecha, también cambian los mensajes que se muestran.

Agreguemos Javascript

Ahora debemos regresar a nuestro formulario inicial y agregarle el código Javascript para que se comunique cada 15 segundos con el servidor web. Para ser más específicos, el Javascript estará haciendo un llamado a 'mensajes_desde.php' cada 15 segundos.

Abre el archivo donde tienes tu formulario y agrega el siguiente código dentro del elemento <head>:

<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script>
  var buscarNuevos = function() {
    //Fecha del ultimo mensaje publicado en la pagina
    var fecha = $('.fecha:first').text();

    //Hacer solicitud por AJAX para añadir mensajes nuevos
    var url = encodeURI('mensajes_desde.php?fecha=' + fecha);
    $.get(url, function(data) {
        $('form').after(data);
    });
  }
  setInterval(buscarNuevos, 15000);
</script>
 
Ahora tu aplicación debe funcionar de esta manera. Si abres la página en dos tabs o ventanas diferentes y escribes un mensaje en una de ellas, verás que el mensaje se añadirá automáticamente al muro de la otra ventana, sin tener que hacer refresh.
 
Analicemos el ejemplo
 
La primera línea que vemos es la siguiente:
 
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
 

Aquí estamos cargando una librería de javascript muy popular llamada jQuery. Aunque pudimos haber escrito este ejemplo usando Javascript común y corriente, jQuery nos ayuda a simplificar el trabajo y la cantidad de código significativamente.

Luego vemos esta línea:

 var buscarNuevos = function() {
 

Aquí simplemente estamos definiendo una función llamada buscarNuevos, que es la que se va a ejecutar cada 15 segundos.

Dentro de buscarNuevos vemos esto:

//Fecha del ultimo mensaje publicado en la pagina
var fecha = $('.fecha:first').text();
 

Aquí estamos usando la magia de jQuery para buscar la fecha del último mensaje publicado. Con el comando $('.fecha:first') le estamos diciendo a jQuery que haga una búsqueda en el HTML y se detenga cuando encuentre el primer elemento con class="fecha". Luego, con el comando .text() le estamos diciendo que seleccione el texto dentro de ese elemento, para poder guardarlo en la variable fecha.

Con la siguiente línea:

var url = encodeURI('mensajes_desde.php?fecha=' + fecha);
 

Simplemente estamos definiendo la dirección hacia el script PHP que contiene los nuevos posts.

Luego hacemos la solicitud mediante AJAX usando el comando $.get:

$.get(url, function(data) {
    $('form').after(data);
});
 

Cualquier data que nos envíe el PHP de vuelta va a ser colocada después del formulario, es decir, arriba de los posts anteriores.

Finalmente, utilizamos setInterval() para decirle a Javascript que ejecute nuestra función buscarNuevos() cada 15 segundos:

setInterval(buscarNuevos, 15000);
 

Y así hemos terminado nuestra primera aplicación utilizando AJAX. Como mencionamos anteriormente, Javascript es un tema muy completo. Si deseas averiguar cómo funciona Javascript a fondo, te recomendamos visitar este link.

Discusión de la Tarea