domingo, 30 de junio de 2013

Extensión MySQLi - Parte 1: Consultas de modificación

Hasta la versión 5.5 de PHP se podían usar tres extensiones para interactuar con mysql. La extensión MySQL, la extensión MySQLi y PDO. Sin embargo la primera de ella ha quedado obsoleta y ya no se debe de usar (PHP >=5.5). De hecho si la usamos se generará error de tipo E_DEPRECATED.

Las principales ventajas que proporciona MySQLi respecto el uso de la extensión MySQL son:

- Interfaz orientada a objetos. Aunque también podemos usar la interfaz procedimental.
- Soporte para declaraciones preparadas 
- Posibilidad de usar transacciones.

Errores 

Antes de pasar a interactuar con MySQL, hay que comentar ciertas funciones que nos proporcionaran información de los errores que se pueden producir en las diferentes etapas de dicha interacción.

La extensión MySQLi nos proporciona procedimientos y propiedades de objeto que nos informa del último error producido en la base de datos. El uso de cada uno depende de si se está usando la interfaz orientada a objetos o la interfaz procedimental.

Vamos a ver los principales:

Orientado a objetos (propiedades) Procedimientos  Descripción
string $mysqli->error;
donde $mysqli es una instancia de conexion con el servidor mysql.
string mysqli_error(mysqli $link);
mysqli $link es una instancia de conexion con el servidor mysql.
Devuelve el último mensaje de error generado en la base de datos.
int $mysqli->errno; int mysqli_errno(mysqli $link); Devuelve el código de error generado en la base de datos
string $mysqli->connect_error; string mysqli_connect_error(); Devuelve el mensaje de error generado por el último intento fallido de conexión.
int $mysqli->connect_errno; int mysqli_connect_error(); Devuelve el código de error generado por el último intento fallido de conexión.

Conexión

Antes de realizar la conexión sería buena idea almacenar la información necesaria en constantes que nos faciliten su posterior modificación.

 define("DB_HOST","localhost" );  
 define("DB_USER", "usuario");  
 define("DB_PASS", "mypassword");  
 define("DB_DATABASE", "Demo" );  

A) Interfaz orientada a objetos

Para la conexión simplemente hay que crear una instancia de msqli pasando los datos necesarios para la conexión: host, usuario, contraseña y nombre de la base de datos.


 $mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_DATABASE);   
 if($mysqli->connect_errno > 0){   
      die("Imposible conectarse con la base de datos [" . $mysqli->connect_error . "]");   
 }  

También es posible dejar sin indicar la base de datos al crear la instancia y hacerlo posteriormente mediante $mysqli -> select_db(). Este método devolverá un bool para verificar el posible error al seleccionar la base de datos.

 $mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS);   
 if(!$mysqli->select_db(DB_DATABASE)) die ($mysqli->error);  

B) Interfaz procedimental

Crearemos la conexión mediante el procedimiento mysqli_conect() que tiene como parámetros los datos necesarios para la conexión y devuelve un objeto que representa la conexión al servidor mysql.

 $con = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_DATABASE);  
 if (mysqli_connect_errno())  
 {  
      echo "Imposible conectarse a la base de datos: " . mysqli_connect_error();  
 } else {   
 }  

Consultas que no devuelven resultado

La ejecución de consultas de tipo “DROP”, ”DELETE”, “CREATE”, “UPDATE” e “INSERT” devolverá true o false en caso de error. Pero no davuelven ningun tipo de dato almacenado en la base de datos.

A) Interfaz orientada a objetos

Para este tipo de consultas utilizaremos el método query() de la interfaz orientada a objetos. Dicho método solo necesita un parámetro que será la cadena que contendrá la consulta.
Una propiedad importante, si usamos esta interfaz, es $mysqli->affected_rows que nos devolverá el número de filas afectadas por la última consulta INSERT, UPDATE, o DELETE ejecutada.

- Ejemplo de borrado de tabla

Llevaremos a cabo una comprobación de la existencia de la tabla para que nos devuelva un posible error.

 $sql = "DROP TABLE IF EXISTS usuario";  
 $mysqli->query($sql);  
 if($mysqli->errno) die($mysqli->error);  

También podríamos averiguar si la consulta ha provocado un resultado esperado, comprobando el número de filas afectadas por la misma. Ya que puede que no haya error de sintaxis en la consulta (error en mysql), pero que el resultado sea erróneo.

 if($mysqli->affected_rows!=1) die ('Error...');  

- Ejemplo de borrado de una fila de la tabla

 $sql = "DELETE FROM usuario WHERE id = '1'";  
 $mysqli->query($sql);  
 if($mysqli->errno) die($mysqli->error);  

- Ejemplo de creación de una tabla

Para este ejemplo vamos a utilizar heredoc para cadenas  en PHP.  Documentación oficial

 $sql = <<<EOT  
 CREATE TABLE usuario (  
   ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT,  
   nombre VARCHAR(50) NOT NULL,  
   mail VARCHAR(100) NOT NULL) ENGINE=InnoDB  
 EOT;  
 $mysqli->query($sql);  
 if($mysqli->errno) die($mysqli->error);  

- Ejemplo de inserción de una fila

 $sql = "INSERT INTO usuario (nombre, mail) VALUES ('usuario 1', 'usuario1@ejemplo.com')";  
 $mysqli->query($sql);  
 if($mysqli->errno) die($mysqli->error);  

Los ID's de las tablas pueden ser autoincrementales por lo que mysql se encarga de ello y no tenemos que definirlo a la hora de hacer la inserción. Pero puede ser muy útil conocer el ID de la última inserción, y para ello mysqli proporciona la propiedad $mysqli->insert_id.

- Ejemplo de actualización de una fila

 $sql = "UPDATE usuario SET name='jose' WHERE id = '2'";  
 $mysqli->query($sql);  
 if($mysqli->errno) die($mysqli->error);  

B) Interfaz procedimental

Como hemos visto a la hora de conectar con la base de datos o de mostrar errores, todo método y propiedades disponibles en la interfaz orientada a objetos tiene un equivalente en la interfaz procedimental.
El equivalente para el método query() de la interfaz orientada a objetos lo tenemos en el procedimiento mysqli_query(mysqli $link, string $consulta). Ahora, aparte de la cadena que contendrá la consulta, también necesita un identificador devuelto por mysqli_connect().

Otro método importante es mysqli_affected_rows(mysqli $link) que nos devolverá el número de filas afectadas por la consulta INSERT, UPDATE, o DELETE ejecutada anteriormente.

- Ejemplo de borrado de tabla (si existe)

 $con = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_DATABASE);  
 ...  
 $sql = "DROP TABLE IF EXISTS usuario";  
 $resultado = mysqli_query($con, $sql);  
 if(mysqli_errno($con)) die(mysqli_error($con));  

- Ejemplo de borrado de de una fila de la tabla

 $con = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_DATABASE);  
 ...  
 $sql = "DELETE FROM usuario WHERE id = '1'";  
 $resultado = mysqli_query($con, $sql);  
 if(mysqli_errno($con)) die(mysqli_error($con));  

También podríamos averiguar si la consulta no ha se ha ejecutado con el resultado esperado. Para ello consultaríamos el número de filas afectadas por la consulta.

 if(mysqli_affected_rows($con)!=1) die ('Error ...');  

- Ejemplo de creación de una tabla

 $con = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_DATABASE);  
 ...  
 $sql = <<<EOT  
 CREATE TABLE usuario (  
   ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT,  
   nombre VARCHAR(50) NOT NULL,  
   mail VARCHAR(100) NOT NULL) ENGINE=InnoDB  
 EOT;  
 $resultado = mysqli_query($con, $sql);  
 if(mysqli_errno($con)) die(mysqli_error($con));  

- Ejemplo de inserción de una fila

 $con = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_DATABASE);  
 ...  
 $sql = "INSERT INTO usuario (nombre, mail) VALUES ('usuario 1', 'usuario1@ejemplo.com')";  
 $resultado = mysqli_query($con, $sql);  
 if(mysqli_errno($con)) die(mysqli_error($con));  

Para obtener el ID de la última inserción mysqli proporciona el procedimiento mysqli_insert_id(mysqli $link).

 echo "El id de la última inserción es " . mysqli_insert_id($con);  

- Ejemplo de actualización de una fila

 $sql = "UPDATE usuario SET name='jose' WHERE id = '2'";  
 $resultado = mysqli_query($con, $sql);  
 if(mysqli_errno($con)) die(mysqli_error($con));  


Entradas relacionadas

Extensión MySQLi - Parte 2: Consultas de selección
Extensión MySQLi - Parte 3: Consultas preparadas y escapado
Extensión MySQLi - Parte 4: Transacciones

2 comentarios: