Aprendiendo PHP, parte 26: Conectar PHP con MySQL

5 Ene

Ahora que ya sabemos programar en PHP y realizar consultas con MySQL, podemos unir ambas tecnologías para conectar a PHP con MySQL y realizar consultas desde nuestra aplicación. Para ello PHP nos provee de una gran variedad de funciones que nos permitirán realizar esto. Así que empecemos.

Para conectar nuestra aplicación a MySQL necesitamos cuatro datos básicamente. En primer lugar el host o IP del servidor al cual conectaremos, en nuestro caso tanto Apache como MySQL se encuentran en el mismo servidor, nuestra máquina, así que será ‘localhost’ o su IP, ‘127.0.0.1’. El nombre del usuario de base de datos, éste será ‘root’ y la contraseña, que por defecto será una cadena vacía. Y finalmente el nombre de la base de datos a la cual vamos a conectarlos, que será lo que venimos trabajando hasta ahora, ‘mi_primer_db’

Todo esto suponiendo que vamos a conectarnos a nuestro localhost, claro ésta. Si vas a conectar PHP con MySQL a un servidor remoto deberías solicitar estos cuatro datos que acabamos de mencionar: el host, usuario, contraseña y nombre de la base de datos, a menos que seas vos el que administre el servicio de MySQL y deberías tenerlos.

Conectar PHP con MySQL

Existen varias formas de conectar PHP con MySQL, una de ellas es mediante PDO, especificado en una publicación que hice hace aproximadamente un año: Php orientado a objetos, parte 10: PDO, Conectarse a una base de datos. Pero ésta está orientada a programadores con conocimientos medios o avanzados de PHP, y también orientados a objetos. En esta ocasión veremos cómo conectarnos mediante la función: mysqli_connect().

Esta función recibirá seis parámetros, aunque los dos últimos no son obligatorios. El primero será el host, el segundo el usuario, el tercero la contraseña y el cuarto el nombre de la base de datos. Los dos últimos vamos a omitirlos, ya que no son necesarios, estos son el puerto y el socket, quinto y sexto respectivamente.

Vamos a conectarnos entonces:

<?php
$conexion = mysqli_connect('localhost', 'root', '', 'mi_primer_db');
mysqli_close($conexion);
?>

Como se ve en el ejemplo, la primer función: mysqli_connect() conecta nuestra aplicación a MySQL, con los valores que mencionamos antes y guardamos dicha conexión en una variable, para así mantenerla a lo largo de nuestro script. Finalmente con la función mysqli_close() realizamos el proceso inverso que es desconectar nuestra aplicación, esta función recibirá un parámetro que será justamente la conexión que queremos cerrar. Esto último es muy importante a tener en cuenta, ya que lo recomendable es conectarnos a nuestra base de datos, realizar las consultas que debemos hacer, como recuperar registros y guardarlos en una variable, y finalmente cerrar la conexión para liberar recursos.

Posible error de conexión

Hablamos en algún momento que existen varios tipos de errores y motivos de los mismos en PHP, pero también señalamos que estos errores pueden darse por un error del programador, o por un error ajeno al programador, pero igual éste debe estar preparado para tapar estos baches.

Cuando conectamos PHP con MySQL, al tratarse de dos servicios que si bien, conviven entre sí, son servicios separados, y uno de estos puede no estar funcionando por diversos motivos. En el caso de que PHP no pueda conectarse a MySQL nosotros deberíamos interrumpir el script para sí evitar que el mismo continúe y genere nuevos errores, provocados por este primero. Para ello vamos a modificar nuestro script de la siguiente forma:

<?php
$conexion = mysqli_connect('localhost', 'root', '', 'mi_primer_db') or die('Error al intentar conectarse a la base de datos.');
echo 'Conectado correctemente';
mysqli_close($conexion);
?>

En primer lugar conectamos nuestra aplicación a MySQL, pero antes de finalizar la línea donde realizamos dicho proceso, agregamos el bloque de código:

or die('Error al intentar conectarse a la base de datos.');

El cual se ejecutará si al intentar conectarse con la base de datos algo falla. La función die(), al igual que exit(), finalizará el script, por tanto todo lo que siga será omitido por nuestro servidor. Podemos simular este error apagando el servicio de MySQL o ingresando algún valor de la función en forma errónea.

Para ejemplificar esto, podemos imaginarnos esto, debemos conectar nuestra aplicación a MySQL y tirar una consulta para recuperar una serie de registros, pero si la conexión falla, obviamente no podremos recuperar esos registros, entonces PHP nos devolverá dos errores, al intentar conectar con la base de datos, y al realizar una consulta a una base de datos con la que no hemos podido establecer una comunicación. Como vimos, de esta forma, al encontrar el primer error el script finalizará y mostramos un error por pantalla antes de terminar.

Consultas

Para realizar una consulta, debemos usar la función mysqli_query(), que recibirá dos parámetros, la conexión y la consulta misma.

Por ejemplo podemos realizar un INSERT:

<?php
$conexion = mysqli_connect('localhost', 'root', '', 'mi_primer_db') or die('Error al intentar conectarse a la base de datos.');
mysqli_query($conexion, 'SET NAMES "utf8"');
$valor = 'Música';
$consulta = "INSERT INTO interes(valor) VALUES('$valor')";
if(mysqli_query($conexion, $consulta)){
   echo 'Registro insertado correctamente.';
}else{
   echo 'Error: ' . mysqli_error($conexion);
}
mysqli_close($conexion);
?>

Vamos a analizar el código:

En primer lugar conectamos con la base de datos, ya hemos visto esto:

$conexion = mysqli_connect('localhost', 'root', '', 'mi_primer_db') or die('Error al intentar conectarse a la base de datos.');

En segundo lugar disparamos una consulta mediante mysqli_query() con el código SQL: ‘SET NAMES “utf8″‘, esto es necesario cuando debemos enviar datos que pueden contener caracteres especiales. Lo que haremos a continuación es insertar el nombre de un nuevo interés, el cual puede contener algún tilde o ñ, por tanto debemos especificar previamente a MySQL que será una conexión utf8, que es la que soportará este tipo de caracteres.

Luego creamos dos variables, una que guardará el nombre del interés y otro la consulta:

$valor = 'Música';
$consulta = "INSERT INTO interes(valor) VALUES('$valor')";

Y finalmente mediante la función mysqli_query() ejecutamos la consulta, la cuál nos devolverá true si la misma se ha podido realizar o false si no ha sido así:

if(mysqli_query($conexion, $consulta)){
   echo 'Registro insertado correctamente.';
}else{
   echo 'Error: ' . mysqli_error($conexion);
}

Notar que si la consulta no ha podido realizarse, mostramos que ha habido un error, concatenándolo con el resultado que nos devuelve la función: mysqli_error(), esta función será la que nos permita recuperar los errores ocasionados por MySQL.

Y finalmente cerramos la conexión:

mysqli_close($conexion);

Ahora supongamos que quisiéramos recuperar el id del registro que acabamos de insertar, deberíamos hacer esto:

<?php
$conexion = mysqli_connect('localhost', 'root', '', 'mi_primer_db') or die('Error al intentar conectarse a la base de datos.');
mysqli_query($conexion, 'SET NAMES "utf8"');
$valor = 'Cine';
$consulta = "INSERT INTO interes(valor) VALUES('$valor')";
if (mysqli_query($conexion, $consulta)) {
   echo 'Registro insertado correctamente con el id: ' . mysqli_insert_id($conexion);
} else {
   echo 'Error: ' . mysqli_error($conexion);
}
mysqli_close($conexion);
?>

La función mysqli_insert_id() nos devolverá el id o clave primaria del último registro que acabamos de insertar.

El mismo proceso se utiliza para realizar consultas UPDATE y DELETE. Sin embargo, imaginemos que queremos hacer un SELECT, por ejemplo para recuperar los países de nuestra base de nuestra tabla nacionalidad:

<?php
$conexion = mysqli_connect('localhost', 'root', '', 'mi_primer_db') or die('Error al intentar conectarse a la base de datos.');
$consulta = "SELECT nacionalidad_id, valor FROM nacionalidad ORDER BY valor";
$resultado = mysqli_query($conexion, $consulta);
while($registro = mysqli_fetch_array($resultado)){
   echo $registro['valor'] . '<br />';
}
mysqli_close($conexion);
?>

Gracias a la función mysqli_fetch_array() podremos recuperar los registros que nos devuelva la consulta en forma de array asociativo, sin embargo cada vez que llamemos a esta función la misma nos devolverá de a un registro, por eso al incluirlo dentro de un while, nosotros repetiremos esta acción hasta que ya no queden registros y el ciclo finalice.

Sql injection

Hasta ahora hemos hecho consultas mediante PHP, pero debemos tener en cuenta una cosa. Las consultas no siempre serán escritas 100% por nosotros, osea, con esto me refiero a que, muchas veces los valores que se ingresen en éstas, vendrán de formularios que deberán llenar los visitantes de nuestro sitio. Por ejemplo, un formulario para registrar un usuario, los datos que ingrese el usuario como nombre y apellido, serán enviados al servidor e incluidos dentro de la consulta.

Primer problema: el usuario puede ingresar valores que rompan nuestra consulta. Por ejemplo, si la consulta es:

SELECT valor FROM nacionalidad WHERE valor = '$nacionalidad';

Suponemos que el usuario ingresó en un campo de formulario: ‘Argentina’, y se recupera ese valor desde una variable POST, entonces la consulta que se envíe a MySQL será:

SELECT valor FROM nacionalidad WHERE valor = 'Argentina';

Hasta acá todo muy lindo. Pero, qué pasa si el usuario ingresa un caracter que rompa ese SELECT, por ejemplo envíe el valor: ”Argentina’, osea una comilla simple y nombre. Entonces la consulta quedará:

SELECT valor FROM nacionalidad WHERE valor = ''Argentina';

Esto se romperá.

Segunda problema: Al permitirle al usuario ingresar datos en la consulta, como acabamos de ver, esto da a lugar a que visitantes malintencionados, ingresen texto que pueda llegar a alterar el verdadero propósito de nuestra consulta. Eso se llama sql injection. No voy dar ejemplos de sql injection debido a que pretendo enseñar a evitar ataques, no a provocarlos. Pero este método ha ocasionado muchos dolores de cabeza de los hackers a los programadores, incluso mediante el sql injection, se han alterado consultas SQL que provocaron que visitantes puedan acceder a información a la cual no estaban autorizados.

Teniendo en cuenta estos dos puntos, debemos tener en cuenta que esos valores que el visitante ingresa, deben ser procesados y formateados antes de realizar una consulta con los mismos.

Supongamos que el usuario se registra:

<?php
$conexion = mysqli_connect('localhost', 'root', '', 'mi_primer_db') or die('Error al intentar conectarse a la base de datos.');
mysqli_query($conexion, 'SET NAMES "utf8"');
//Datos ingresados por el usuario.
$nombre = 'Fernando';
$apellido = 'Gaitán';
$email = 'fgaitan@mail.com';
$contrasena = md5('1234');
$nacionalidad_id = 1;
//Escapar valores ingresados.
$nombre = mysqli_real_escape_string($conexion, $nombre);
$apellido = mysqli_real_escape_string($conexion, $apellido);
$email = mysqli_real_escape_string($conexion, $email);
$contrasena = mysqli_real_escape_string($conexion, $contrasena);
$nacionalidad_id = mysqli_real_escape_string($conexion, $nacionalidad_id);
$consulta = "INSERT INTO usuario(nombre, apellido, email, contrasena, fecha_alta, fecha_modificacion, nacionalidad_id) VALUES('$nombre', '$apellido', '$email', '$contrasena', sysdate(), sysdate(), $nacionalidad_id)";
if(mysqli_query($conexion, $consulta)){
   echo 'El usuario ha sido insertado correctamente.';
}else{
   echo 'Error: ' . mysqli_error($conexion);
}
mysqli_close($conexion);
?>

Vamos a analizar el código:

$nombre = 'Fernando';
$apellido = 'Gaitán';
$email = 'fgaitan@mail.com';
$contrasena = md5('1234');
$nacionalidad_id = 1;

Aquí simularemos una serie de datos ingresados por el usuario para registrarse. Notar que la contraseña pasará por un proceso de encriptación gracias a la función md5(), así podremos proteger las contraseñas en nuestra base de datos, convertidas en cadena disfrazadas.

Y ahora lo que nos interesa:

$nombre = mysqli_real_escape_string($conexion, $nombre);
$apellido = mysqli_real_escape_string($conexion, $apellido);
$email = mysqli_real_escape_string($conexion, $email);
$contrasena = mysqli_real_escape_string($conexion, $contrasena);
$nacionalidad_id = mysqli_real_escape_string($conexion, $nacionalidad_id);

La función mysqli_real_escape_string(), le dará un formato a nuestros valores ingresados para así corregir aquellas combinaciones de caracteres que puedan romper la consulta o bien alterarla.

Si ejecutamos el script se insertará un usuario.

Ahora supongamos que queremos verificar si los datos que ingresó el mismo son correctos para así loguearlo:

<?php
$conexion = mysqli_connect('localhost', 'root', '', 'mi_primer_db') or die('Error al intentar conectarse a la base de datos.');
mysqli_query($conexion, 'SET NAMES "utf8"');
//Datos ingresados por el usuario.
$email = 'fgaitan@mail.com';
$contrasena = md5('1234');
//Escapar valores ingresados.
$email = mysqli_real_escape_string($conexion, $email);
$contrasena = mysqli_real_escape_string($conexion, $contrasena);
$consulta = "SELECT usuario_id FROM usuario WHERE email = '$email' AND contrasena = '$contrasena'";
$resultado = mysqli_query($conexion, $consulta);
$usuario = mysqli_fetch_array($resultado);
if($usuario){
   echo 'Se ha logueado un usuario con el id: ' . $usuario['usuario_id'];
}else{
   echo 'Datos incorrectos.';
}
mysqli_close($conexion);
?>

Aquí repetimos el mismo proceso, formateamos los datos ingresados por el usuario, para así evitar sql injection, y verificamos con un if si la consulta nos ha devuelto algún registro:

if($usuario){
   echo 'Se ha logueado un usuario con el id: ' . $usuario['usuario_id'];
}else{
   echo 'Datos incorrectos.';
}

 

Saludos!

Anterior: Aprendiendo PHP, parte 25: Introducción a MySQL, registros

Redes sociables

    4 thoughts on “Aprendiendo PHP, parte 26: Conectar PHP con MySQL

    1. Hola Fernando, muy interesante tu blog y mas este tema “Aprendiendo PHP” realmente mes ayudado demasiado con toda la información que publicas y compartes con nosotros. ¿Hasta acá viene este tema de php parte 26 o seguirá? porque realmente sueño con hacer cosas muy grandes con PHP y mysql como poder crear un sistema de ventas y compras, un sistema pos, un sistema de facturación, en fin, un montón de cosas y con este blog he salido de muchas cosas que creaban conflictos en mi cabeza. otra pregunta. ¿Te puedo preguntar cositas que no se y tu me ayudas? ante mano muchas gracias por todo.

    Deja un comentario

    Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *


    *