miércoles, 14 de diciembre de 2011

Leyendo de la BD

Ya sabemos conectar, ahora a trabajar. En una situación normal la base de datos ya estaría creada y con alguna tabla con datos. Sigamos, por tanto, preparando el entorno en el que va a trabajar nuestra aplicación PHP.

Desde un cliente cualquiera (phpMyAdmin, MySQL Workbench, etc.), entrando con un usuario con los suficientes privilegios (si la instancia de MySQL es local, probablemente será el root), ejecutamos las siguiente órdenes:

create database phpbd;
use phpbd; 

create table usuario (usuario integer, nombre varchar(20), ingreso date, 
primary key (usuario)) engine=innodb; 

insert into usuario values (3,'Pepe',now()),(10,'Juan',now()),(1,'María','2011-11-30');

grant select on phpbd.* to 'phpuser'@'%';


Ahora que ya tenemos una conexión abierta con el servidor, toca elegir la base de datos con la que trabajar.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>PHPsimplón</title>
  </head>
  <body>
    <?php
      $link = @mysql_connect('localhost', 'phpuser', 'phpcontra')
                            or die('Error de conexión.');
      $db_selected = mysql_select_db('phpbd', $link)
                            or die ('Error de BD.');

      $result = mysql_query("select usuario,nombre,ingreso
                               from usuario
                               order by usuario")
                            or die ('Error de consulta.');;
      while ($row = mysql_fetch_assoc($result)) {
        echo $row['usuario'] . '-' . $row['nombre'] . ' Ingresó en ' .
                 $row['ingreso'] . '<br />';
     
      mysql_close($link);
    ?>
  </body>
</html>


El resultado que vamos a obtener es el siguiente:
1-María. Ingresó en 2011-11-30
3-Pepe. Ingresó en 2011-12-13
10-Juan. Ingresó en 2011-12-13

Ahora, volvamos y expliquemos paso a paso:

$db_selected = mysql_select_db('phpbd', $link)

En primer lugar, antes de hacer nada, hay que seleccionar la base de datos con la que vamos a trabajar. Obviamente, debe ser alguna para la que el usuario que se conecta (phpuser en nuestro caso) tenga algún privilegio. A la variable $db_selected no le vamos a dar uso, con lo que pudiéramos habérnosla ahorrado. La costumbre.

$result = mysql_query("select usuario,nombre,ingreso
                               from usuario
                               order by usuario")

Esta es nuestra primera consulta. Tampoco necesita mucha explicación. Se puede enviar casi cualquier orden SQL si sabemos lo que estamos haciendo en todo momento y dependiendo, casi es lo más importante, de lo que nuestro usuario tenga permiso para hacer.

No vamos a hacer mucho más hincapié en los privilegios otorgados al usuario que accede desde PHP pero, como advertencia, es imprescindible que sean los mínimos indispensables, no queremos torpedear a nuestro servidor de base de datos con agujeros de seguridad.

Aquí la variable $result sí es importante. Es la que va a almacenar todas las filas que obtengamos de la consulta. En otros casos, por ejemplo en órdenes insert solo contendrá un valor lógico, verdadero o falso en cuanto a si la inserción ha tenido éxito o no. En realidad se trata de un array construído para la ocasión y que se maneja tal y como se muestra a continuación.

while ($row = mysql_fetch_assoc($result)) {
        echo $row['usuario'] . '-' . $row['nombre'] . ' Ingresó en ' .
                 $row['ingreso'] . '<br />';

Hay que decir que no es la única forma de procesar el array devuelto por mysql_query(). Este array contiene tantos elementos como filas se han devuelto desde MySQL. A su vez, cada elemento es otro array con tantas componentes como columnas hemos recuperado desde la select. Es decir, se trata de una matriz a la que podemos acceder con 2 índices: número de fila y componente.


PHP nos facilita el proceso mediante algunas funciones como mysql_fetch_assoc(). Como se ve en el bucle anterior, la llamada a esta función tiene dos objetivos:
  1. recuperar la siguiente fila y
  2. saber cuándo se ha terminado
En nuestro ejemplo, $result contiene un array de 3 elementos, cada uno de los cuales contiene a su vez 3 componentes. La primera llamada a mysql_fetch_assoc() nos devuelve la primera fila recuperada y prepara los datos para las siguientes llamadas que, nos darán la segunda y la tercera. Cuando ya no queden filas por devolver, en $row se almacenará un valor falso y el bucle while se detendrá.

Así, en cada pasada del bucle while, $row se carga con un array de datos. La particularidad de mysql_fetch_assoc() es que se puede hacer referencia a cada componente por su nombre de columna, no necesitamos conocer el orden de la componente dentro del vector. Por eso utilizamos, por ejemplo, $row['usuario']. Es así como generamos, finalmente, el texto HTML que va a ser nuestra página resultado. En realidad, como código HTML solo hemos utilizado el salto de línea <br />. El operador concatenación es el "punto" ('.') que aparece tantas veces como no es necesario.

Para los muy, muy novatos, $result, $row, $db_selected, $link, son nombres de variable, se pueden cambiar por $pepito, $manolito... :)