sábado, 22 de agosto de 2009

Terceros Pasos - Consultas a bases de datos - Altas

Hola amigos/as. Siento haber tardado tanto, hoy quiero mostrarles como conectarse a una base de datos y hacer el famoso ABM (en español siglas para Altas, Bajas y Modificaciones) que también lo conozco como CRUD (en inglés Create, Read, Update and Delete).

Bueno, primero necesitaremos crear una base de datos, para ello si han instalado el appserv como les recomendé en el primer post, podrán dirigirse a la dirección http://localhost/phpMyAdmin/ pondrán el usuario root, y la contraseña que hayan creado cuando instalaron, sino funciona, prueben 123456 que suele ser lo típico.

Una vez dentro verán una página dividida en dos columnas, la de la izquierda les mostrará la lista de base de datos que tengan, algunas opciones como por ej, abrir un popup para ejecutar consultas SQL dentro, la documentación del phpMyAdmin, la documentación de SQL, y uno especial que es para salir; En la parte derecha, veran información del servidor, así como un campo para crear una base de datos, pongan alli un nombre de base de datos que quieran, por ej.:

base_de_ejemplo

les sugiero no usar espacios, en su lugar usen un guion bajo. (una vez sin querer puse un espacio, y me lo permitió, pero a la hora de conectar me daba un error, si a Ustedes no les pasa lo mismo, bien por ustedes, pero les puede ahorrar algunos minutos de rabia ;P) luego de esto, presionen el boton 'crear'.
Lo ventajoso del sistema phpMyAdmin, es que nos ahorra (un poco) las sentencias sql.
Ok, supongo que les salió algo como esto:

Base de datos base_de_ejemplo se creó.
consulta SQL:
CREATE DATABASE `base_de_ejemplo` ;

[Editar] [ Crear código PHP ]

ok, con eso ya tendremos nuestra base de datos funcionando, ahora necesitaremos crear una tabla para poner en práctica nuestro ejemplo de ABM.

Si se fijan abajo del mensaje, aparece algo como:

No se han encontrado tablas en la base de datos.

Crear nueva tabla en la base de datos: base_de_ejemplo

para ello pongan el nombre user dentro del campo, y coloquen el numero 5 dentro del campo que se denota bajo el titulo numero de campos. A continuación presionen el boton Continuar.

En la ventana les saldra una tabla conteniendo cinco filas para completar, algo similar a esto:

Campo Tipo? Longitud/Valores*1 Cotejamiento Atributos Nulo Predeterminado2 Extra p r u
--- t
Comentarios



El primero es el nombre del campo, en este caso tendremos los siguientes campos con las siguientes características:
id (tipo numerico entero, autoincrementable y clave primaria de la tabla)
nombre_completo (tipo varchar [cadena de caracteres de longitud variable] con una logitud de 20 que admite nulos)
nick (tipo varchar de longitud 12 no admite nulos y tiene que ser único en toda la base de datos)
password (tipo varchar de longitud 40 no admite nulos)
estado (tipo enum con los valores 'a','i' no admite nulos y por defecto es 'i' [a es para activo, i es para inactivo] tampoco admite valores nulos)

A continuacion van poniendo esos nombres en los campos primero seleccionamos id, de la lista que aparece a lado de el, seleccionamos la opcion que dice INT, luego se dezplazan mas a la derecha, y busquen el simbolo de clave primaria, normalmente es una pequeña llave dorada sobre una tabla, a su izquierda hayuna opcion que se llama extra, seleccionen la opcion auto_increment.
Esto permite que a medida que vayamos insertando campos en nuestra tabla, el campo id, se autoincremente por sí solo, sin que tengamos que intervenir. Cuando seleccionamos la opción primary key, o clave primaria, lo que hacemos es que cada fila tenga un número de identificación único. Podriamos hacer que el campo nick sea la clave primaria, pero yo utilizo el argumento de que al ser un campo numérico puede indexarse más rapido que utilizando el campo de nick de usuario.

Ahora pasemos a la segunda fila, en este caso corresponde a la opcion nombre_completo
seleccionen la opcion varchar (por defecto suele estar seleccionada) a su izquierda coloquen el numero de caracteres que quieren sea el límite. como antes dije, yo pondré 20, pero pueden poner el numero que quieran, creo que habia un limite de 256, no estoy seguro, pero si quieren saberlo pueden buscar la información en el sitio de MySQL http://dev.mysql.com/ (siempre es importante conocer y estar registrado en su página para poder utilizar tranquilamente sus servicios, entre ellos el MySQL workbench, MySQL connector, etc. a los que solo se accede si tienen un usuario y contraseña, hasta ahora todo ha sido siempre gratuito :)

ok, continuemos, no hace falta modificar nada más en la segunda fila, con especificar el nombre del campo, su tipo y longitud, podemos pasar al tercero que en este caso será nick, escriban el nombre de campo, seleccionen varchar, y su longitud de 12 caracteres, busquen mas a la derecha (cerca de donde está la clave primaria) una opción que se denota bajo el nombre "Único", por lo general su ícono es una U de color rojo sobre una tabla. Esto pone una restricción en la base de datos, similar a la clave primaria, pero hace que este campo sea absolutamente único en la tabla. Esto es, para evitar que dos usuarios tengan el mismo nick. Así nos evitará errores durante nuestra programación. Ya que de no ponerlo así, y si por error cuando programamos nuestro sitio, nos olvidáramos de corroborar que el usuario no exista, tendríamos un error bastante grave ya que podrían, por ejemplo existir dos p431i7o (y nadie quiere eso ;P )

Continuamos con el siguiente campo que es password, y repetimos lo mismo, seleccionamos varchar, y colocamos la longitud 40

Luego, el campo estado, seleccionamos la opcion ENUM, y al lado colocamos
'i','a'
solo esos valores serán admitidos, y por si no es especificado ninguno, pondremos en la opción "predeterminado" el valor
i
(sin comillas)
Listo, con eso tenemos seteado todos los campos, solo nos falta decidir un último detalle, si se fijan más abajo, dice algo como Motor de almacenamiento, y hay varias opciones, entre las cuales destaco dos:
El que está por defecto MyISAM... y InnoDB
El primero es un motor muy rápido, ideal para la web, sólo que carece de la capacidad de controlar relaciones, esto es por ej. si tenemos dos tablas, una de ellas usuario y otra por ej. Publicaciones, no podremos asociar el id del usuario con el autor de una publicación por la base de datos, con lo que NO obtendriamos una integridad referencial (leer wikipedia) que es algo que si tenemos con el motor InnoDB pero a cambio, perdemos un poco de rapidez, ya que para cada Inserción, Modificación o Borrado, se hará un chequeo de integridad. Esto es lo que basicamente diferencia a uno de otro, tendremos que elegir entre 'rapidez e inseguridad' y 'seguridad y lentitud' tampoco es una cosa de que es 'demasiado lento' para nada, por lo general suelo utilizar InnoDB y la diferencia no es apreciable a simple vista, pero cuando contamos con una tabla de 1 millon de registros, si se hará visible.

En este caso, recomiendo usar simplemente MyISAM ya que sólo haremos un pequeño ABM y no es necesario nada que tenga que ver con el control referencial. Es más, cuando utilizen sus bases de datos pueden hacer el uso de ambos en diferentes tablas según crean conveniente.

Luego de seleccionar el motor que les guste, presionen el boton Grabar.

deberia salir algo como lo que sigue:

Tabla `base_de_ejemplo`.`user` se creó.
consulta SQL:
CREATE TABLE `user` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`nombre_completo` VARCHAR( 20 ) NOT NULL ,
`nick` VARCHAR( 12 ) NOT NULL ,
`pasword` VARCHAR( 40 ) NOT NULL ,
`estado` ENUM( 'a', 'i' ) NOT NULL DEFAULT 'i',
UNIQUE (
`nick`
)
) ENGINE = MYISAM ;

Listo, con eso ya tienen creada su tabla.
Ahora, a programar algo de codigo.

Deben crear una carpeta llamada proyecto1 dentro de su carpeta www
dentro de ella crean un archivo llamado alta.php
Tambien crearemos un archivo llamado configuracion.php
y adentro de este ultimo colocaremos el siguiente código:

<?php
$servidor = "localhost";
$base_datos = "base_de_ejemplo";
$usuario = "root";
$password = "AQUItuPASSWORD";
$id_conexion = mysql_connect($servidor,$usuario,$password) or die('Alguno de los datos anteriores esta mal '.mysql_error($id_conexion));
if(!mysql_select_db($base_datos,$id_conexion)){
die("Error al seleccionar la base de datos. Deteniendo ejecucion del script");
}
?>
A continuacion una pequeña explicación de qué tenemos aquí.
Las primeras son variables conteniendo los valores que necesitamos para realizar la conexion. (no se olviden de poner la contraseña que crearon cuando instalaron en lugar de la que alli puse)
$id_conexion tendra un valor que sirve para identificar a esa conexion de base de datos, pues, imaginense que haya mil usuarios utilizando tu pagina, cada uno de ellos tendra una conexion diferente, pero no te preocupes, esas conexiones se manejan a nivel del script, que está a salvo en el servidor, ellos solo tienen acceso a la página.

Si por A o B motivos alguno de los datos está mal y no se puede conectar, se ejecutará la parte de la sentencia que corresponde al die(). Esta sentencia lo que hace es parar toda ejecucion. y desplegar el mensaje que tiene adentro. en nuestro caso desplegamos una cadena, y le adjuntamos el mensaje de error de mysql.

Luego, en la siguiente sentencia, preguntamos si la selección de base de datos es correcta, si asi no fuera devolveria un valor false, lo que negamos mediante el simbolo de admiracion cerrado !
este simbolo hace la negacion, por ejemplo
si tenemos true, nos devuelve false, y viceversa, si tenemos false, nos devuelve true.

Como el if() se ejecuta con true y tenemos que la sentencia mysql_select_db() devuelve false y con la negacion de esta tenemos true. se ejecutara el codigo que tiene dentro.
Esto es el mensaje die(); indicando que no se ha seleccionado la base de datos.

Lo he puesto de esa manera, porque solo me interesa que se detenga la ejecución cuando los datos son incorrectos.

ok, si quieren probar que realmente se conecta, pueden agregar una sentencia antes del cierre de la etiqueta php y poner el siguiente código:

echo $id_conexion;

y en su navegador al visitar la página http://localhost/proyecto1/configuracion.php
les imprimira algo como

Resource id #2

Si les sale algun mensaje de error verifiquen los datos que han puesto en las variables y prueben de nuevo.

Ok, listo, con esto tenemos establecido nuestra configuracion de base de datos.

Ahora pongamos el siguiente codigo dentro del archivo alta.php

<?php
//preguntamos si se recibió algun dato por post en este caso, si se presiono el boton de envio
if(isset($_POST['boton_envio'])){
//incluimos el archivo de configuracion
require_once('configuracion.php');

//verificamos los datos que recibimos por POST
if(isset($_POST['nombre'],$_POST['nick'],$_POST['password'],$_POST['estado'])){
//todos los datos estan seteados

$nombre_completo = mysql_escape_string($_POST['nombre']);
$nick = mysql_escape_string($_POST['nick']);
$password = mysql_escape_string($_POST['password']);
$estado = mysql_escape_string($_POST['estado']);
//con esto limpiamos algunas cositas que pueden provocar una injeccion
//sql a nuestra sentencia.

//Ahora armaremos la sentencia
$sql = "INSERT INTO `user` (`nick`,`nombre_completo`,`password`,`estado`)";
$sql .= " VALUES ('$nick','$nombre_completo','$password','$estado')";

//el simbolo .= significa lo mismo que hacer $sql = $sql . "resto de la cadena";
//las variables dentro de la cadena seran reemplazadas
//automaticamente por el interprete, siempre y cuando esten formadas por
//comillas dobles ""

//Ejecutamos la consulta
$resultado = mysql_query($sql,$id_conexion);
if(mysql_errno($id_conexion) == 0 && mysql_affected_rows($id_conexion)>0){
//todo fue un exito y se pudo insertar
$todo_ok = true;
$mensaje = "Se insertó con exito el registro";
}else{
//hubo un error
$todo_ok = false;
//guardamos el mensaje de error de mysql y el codigo
$mensaje = "Error al insertar: ".mysql_error($id_conexion)." codigo: ".mysql_errno($id_conexion);
}
}
}
/*
con esto incluimos el formulario para hacer altas y mantenemos el codigo
mas limpio y ordenado
*/

include('formulario_de_envio.php');

A continuación el código del formulario_de_envio.php

<html lang="es">
<head>
<title>Formulario de envio<title>
<style>
.clear{
clear:both;
}
input{
clear:both;
margin-bottom:10px;
margin-left:25px;
}
fieldset{
display:block;
border:solid 1px dashed;
width:200px;
margin-bottom:15px;

}
<style>
</head>
<body>
<?php
//si hay algun mensaje de error o exito, lo imprimimos aqui
if(isset($mensaje)){
echo "
<h1>".$mensaje."</h1>";
}

?>
<form method="post" action="alta.php">
<label class="label" for="">Nombre:</label>
<div class="clear"><div>
<input type="text" name="nombre" value=" if(isset($_POST['nombre']) && !$todo_ok) echo $_POST['nombre']; ?>" />
<div class="clear"><div>
<label class="label" for="">Nick:<label>
<div class="clear"><div>
<input type="text" name="nick" value=" if(isset($_POST['nick']) && !$todo_ok) echo $_POST['nick']; ?>" />
<div class="clear"><div>
<label class="label" for="">Password<label>
<div class="clear"><div>
<input type="password" name="password" />
<fieldset>
<legend>Estado</legend>

<input type="radio" id="a" name="estado" value='a' />
<label for="a">activo<label>
<div class="clear"><div>

<input type="radio" id="i" name="estado" value='i' checked="checked" />
<label for="i">inactivo<label>
<fieldset>
<div class="clear"><div>
<input type="submit" name="boton_envio" value="Enviar" />
<input type="reset" value="Restablecer">
<form>
</body>

</html>
En teoría con eso, ya pueden hacer las altas, para revisar, nada mas vayan al phpMyAdmin, y revisen en la tabla mediante la opción Examinar, si hay filas insertadas

en mi caso, he probado el codigo anterior y obtuve
Textos completos id nombre_completo nick password estado
Editar Borrar 1 pablo ruiz diaz p431i7o 1234asdf a

y el mensaje:

Se insertó con exito el registro


Bueno, por hoy eso sería todo, quise hacer tambien, el listado de filas y su correspondiente baja y modificación pero lo dejo para otra ocasión, espero les sirva y guste, espero sus comentarios