Inicio Apuntes FPApuntes DAM Cómo conectar Php y Mysql a través de PDO o MySQLi

Cómo conectar Php y Mysql a través de PDO o MySQLi

Publicado por entreunosyceros
Publicado el: Última actualización:

AVISO: Esta entrada tiene más de dos años desde su publicación. Es posible que el contenido esté desactualizado.

El artículo que voy a dejar hoy colgado en entreunosyceros viene requerido por varias razones. La primera es que me parece una información muy útil tener a mano (ya que no te puedes acordar de todo siempre) y la segunda es por que ya no es la primera vez que me han preguntado acerca de como hacerlo. En este artículo veremos como integrar Php y Mysql para poder aumentar la funcionalidad de nuestros desarrollos web. Primero veremos como abrir la conexión en el servidor Mysql. Después ejecutaremos comandos en nuestra base de datos a través de nuestra aplicación y finalmente aprenderemos a llamar procedimientos almacenados.

Hace ya tiempo que Php ha declarado obsoleta su API clásica de conexión MySQL para proyectos que usen versiones de Php superiores a la 5.5.0. No obstante existen otras dos APIs de integración, llamadas MySQLi y PDO_MySQL. En este artículo cubriremos la acción de estas tres APIs para que se puedan ver las características de codificación en cada una para que llegado el momento cada cual pueda elegir la que mejor le venga para sus proyectos.

Cadenas de conexión entre Php y MySQL

Haremos exactamente lo mismo que con la conexión Mysql-Java y Sql Server-C#. Usaremos las cadenas que indiquen el servidor, el nombre de la base de datos y el usuario que vamos a emplear para abrir la conexión. Yo siembre he recomendado como medida de seguridad puedes crear un archivo .php (en este ejemplo le llamaré al archivo mysql-login.php) que guarde estos datos en variables locales de forma externa.

//Datos de conexión a la base de datos
$hostname = 'localhost';
$database = 'datos';
$username = 'usuario';
$password = 'contraseña';

Después incluiremos este archivo con la sentencia require_once en el archivo donde abriremos la conexión a la base de datos. Para abrir la conexión se usarán los siguientes fragmentos de código:

//MySQL clásico
require_once 'mysql-login.php';
//Conectando
$con = mysql_connect($hostname, $username, $password);
//Manejo de errores
if (!$con)
die("Falló la conexión a MySQL: " . mysql_error());
else
echo "Conexión exitosa!";
//Seleccionar base de datos
mysql_select_db($database)
or die("Seleccion de base de datos fallida " . mysql_error());
mysql_close();


//MySQL PDO
require_once 'mysql-login.php';
try {
$con = new PDO('mysql:host='.$hostname.';dbname='.$database, $username, $password);
print "Conexión exitosa!";
}
catch (PDOException $e) {
print "¡Error!: " . $e->getMessage() . "
";
die();
}
$con =null;


//MySQLi
require_once 'mysql-login.php';
$mysqli = new mysqli($hostname, $username,$password, $database);
if ($mysqli -> connect_errno) {
die( "Fallo la conexión a MySQL: (" . $mysqli -> mysqli_connect_errno() 
. ") " . $mysqli -> mysqli_connect_error());
}
else
echo "Conexión exitosa!";
$mysqli -> mysqli_close();

En la siguiente tabla se pueden ver las características para realizar la conexión en las tres apis que he descrito:

MySQL clásicaMySQLiPDO
mysql_connect(): Función para abrir la conexiónnew mysqli: Crear nuevo objeto de conexión con las cadenas de conexión.new PDO: Crear un nuevo objeto de conexión con las cadenas de conexión. La cadena “mysql”: al inicio es un estándar de conexión, así que incluyela siempre.
mysql_select_db(): Selecciona la base de datosLa base de datos es seleccionada en el constructor PDOLa base de datos es seleccionada en el constructor PDO
Usar retorno booleano de mysql_connect()Usa el atributo connect_errno para comprobar la existencia de erroresUsaremos try-catch para manejar las excepciones de tipo PDOException
mysql_close(): Función que cierra la conexiónmysqli_close(): Método de la clase mysqli para cerrar la conexión.Para cerrar la conexión asignas NULL al objeto de conexión creado.

Ejecutar comandos MySQL desde Php

Si has llegado a este punto del post, supongo que ya sabes que los comandos insert, update, delete solo modifican la base de datos, a diferencia de select que devuelve resultados estructurados en forma de tabla. Debido a esto es importante elegir correctamente la forma en tratar los datos.

En el siguiente ejemplo se verá como ejecutar los comandos que no devuelven filas. Como ejemplo actualizaremos el  nombre de un trabajador cuyo código es 5 en la base de datos de una empresa.

//MySQL clásico
$resultado = mysql_query("UPDATE PROFESOR SET NOMBRE ='Brenda' WHERE ID=2");
if(!$resultado)
die("Fallo el comando:".mysql_error());
else
echo mysql_affected_rows()."Filas afectadas";


//PDO
$count = $con->exec("UPDATE PROFESOR SET NOMBRE ='Brenda' WHERE ID=2");
print($count." Filas afectadas");


//MySQLi
if ($mysqli->query("UPDATE PROFESOR SET NOMBRE ='Brenda' WHERE ID=2") === TRUE) {
printf($mysqli->affected_rows." Filas afectadas");
}
else
echo "Error al ejecutar el comando:".$mysqli->error;

La siguiente tabla muestra las características de ejecución en cada una de las API que acabamos de ver:

MySQL clásicaMySQLiPDO
mysql_query(): Función que ejecuta un comando en la base de datos.query(): Método de la clase mysqli para ejecutar un comando.exec(): Método de la clase PDO para ejecutar un comando que solo afecta la base de datos.
mysql_affected_rows(): Retorna en la cantidad de filas afectadasaffected_rows: Atributo de la clase mysqli que guarda la cantidad de filas afectadas.El retorno de exec() es la cantidad de filas afectadas por la sentencia.

Consultar base de datos MySQL desde Php

Para este caso el API MySQL clásico y MySQLi usan el mismo método anterior para tratar consultas. Por su parte, PDO emplea el método query() para obtener las filas. A continuación se puede ver como consultar la tabla COCHES del sistema de un taller.

//MySQL clásico
$query = "SELECT * FROM COCHES";
$resultado = mysql_query($query);
if(!$resultado)
die("Falló el comando:".mysql_error());
else{
print("<table>");
while($rows = mysql_fetch_array($resultado,MYSQL_ASSOC)){
print("<tr>");
print("<td>".$rows["ID"]."</td>");
print("<td>".$rows["CILINDRADA"]."</td>");
print("<td>".$rows["DESCRIPCION"]."</td>");
print("</tr>");
}
print("</table>");
}

mysql_free_result($resultado);

//PDO
$query = "SELECT * FROM COCHES";
print("<table>");
$resultado = $con->query($query); 
foreach ( $resultado as $rows) { 
print("<tr>");
print("<td>".$rows["ID"]."</td>");
print("<td>".$rows["CILINDRADA"]."</td>");
print("<td>".$rows["DESCRIPCION"]."</td>");
print("</tr>"); 
}
print("</table>");
$resultado =null;


//MySQLi
$query = "SELECT * FROM COCHES";
$resultado=$mysqli->query($query);
print("<table>");
while ($rows = $resultado->fetch_assoc()) {
print("<tr>");
print("<td>".$rows["ID"]."</td>");
print("<td>".$rows["CILINDRADA"]."</td>");
print("<td>".$rows["DESCRIPCION"]."</td>");
print("</tr>");
}
print("</table>");
$resultado->free();

Observa el resumen te las características para ejecutar consultas con las extensiones:

MySQL clásicaMySQLiPDO
mysql_fetch_array(): Función que obtiene una fila de la consulta. El parámetro indica que tipo de array será retornado.
MYSQL_NUM: Array de retorno con índices numéricos.
MYSQL_ASSOC: Array de retorno con índices asociativos.
MYSQL_BOTH: Array de retorno con ambos tipos de índices.
fetch_assoc(): Método de la clase mysqli_result que obtiene una fila de la consulta en forma de array asociativo.query(): Método de la clase PDO que retorna en un objeto PDOStatement que contiene los resultados de una consulta. Recorreremos cada elemento del objeto con un bucle foreach.fetch(): Método de la clase PDO para obtener una fila de una consulta.
mysql_free_result(): Libera la memoria hacia los resultados de la consultafree(): Libera la memoria asociadaAsigna NULL a la variable que recibió la referencia del resultado para liberar la memoria.

Sentencias preparadas en Php

Si has leído un poco acerca de las conexiones a bases de datos, en todas partes dicen que es común usar el carácter ‘?’ para indicar que un valor va a ser variable dentro de una sentencia preparada, es decir, que tomará distintos valores según los datos que nosotros le asociemos para ejecutar múltiples veces la sentencia pero con diferentes valores.

Pues bien, las APIs de MySQL para Php utilizan este mismo formato para preparar un comando.

Vamos a suponer que has creado un formulario que recibe el nombre, apellido, edad y el email de un usuario. Ahora deseas que cuando el usuario haga clic en el botón de confirmación estos campos sean guardados en tu tabla USUARIO.

Ahora veremos como hacerlo en los tres casos que nos ocupan.

//MySQL clásico
$query = 'PREPARE sentencia FROM "INSERT INTO usuario VALUES(NULL,?,?,?,?)"';
$resultado = mysql_query($query);
if(!$resultado)
die("Fallo el comando:".mysql_error());
else{
print("PREPARE exitoso!</br>");
$query ='SET @nombre = "'.$nombre.'"'.',@apellido ="'.$apellido.'"'
.',@edad ='.$edad.',@email='.$email;
if(!mysql_query($query))
die("Error en SET: ".mysql_error());
$query = 'EXECUTE sentencia USING @nombre,@apellido,@edad';
if(!mysql_query($query))
die("Error en EXECUTE:".mysql_error());
$query = 'DEALLOCATE PREPARE sentencia';
if(!mysql_query($query))
die("Error en DEALLOCATE:".mysql_error());
}


//MySQLi
if ($stmt = $mysqli->prepare("INSERT INTO usuario VALUES(NULL,?,?,?,?)") ){
/* ligar parámetros para marcadores */
$stmt->bind_param("ssds", $nombre,$apellido,$edad,$email); 
/* ejecutar la consulta */
$stmt->execute();
/* cerrar sentencia */
$stmt->close();
}
else{
echo "Error al ejecutar la sentencia preparada".$mysqli->error;
}


//PDO
$cmd = $con->prepare('INSERT INTO usuario VALUES(NULL,?,?,?,?)');
$cmd->execute(array($nombre,$apellido,$edad,$email));

A continuación se observan las características para crear una sentencia preparada en las apis de conexión:

MySQLiPDO
prepare(): Método de la clase mysqli_stmt para preparar una sentencia genérica.Los parámetros se representan con el carácter ‘?’ o con una etiqueta “:label”.prepare(): Método de la clase PDO para crear una sentencia preparada.
bind_param(): Liga los parámetros de la sentencia preparada mediante alguno de los siguientes indicadores de tipo:i: Tipo entero
d: Tipo float
s: Tipo string
b: Tipo blob
bindParam(): Liga los parámetros de una sentencia preparada.Parámetro 1: Índice del parámetro
Parámetro 2: La variable relacionada al parámetro
Parámetro 3: Tipo de dato
Parámetro 4: Longitud del dato
execute(): Ejecuta un comando preparado.execute(): Ejecuta un comando preparado. Es posible vincular los parámetros en forma de array a través de este método.
get_result(): Obtiene los resultados de una sentencia preparada, si es que la sentencia retorna filas.fetch(): Obtiene una fila de la consulta.Parámetro: Indica como se devuelven los datos.
PDO:FETCH_OBJ: retorna las filas en forma de objetos.
PDO:FETCH_ASSOC: en forma de array asociativo.

La API clásica no soporta crear sentencias preparadas, el ejemplo que vimos fue el uso de la sentencia interna PREPARE de MySQL, intentando simular el comportamiento genérico de un comando, pero esto se escapa a sus funcionalidades.

Ejecutar un Procedimiento almacenado en MySQL

Ejecutar un procedimiento con nuestras extensiones no requiere métodos nuevos, se hace exactamente con los mismo que hemos venido viendo en cada complemento. Lo único que debes tener en cuenta es si el procedimiento devuelve una tabla o solo afecta la base de datos. Dependiendo de esa situación tendrás que elegir el método más apropiado.

A continuación veremos la invocación de un procedimiento que devuelve las estadísticas de un franquicia realizado por la administración  y que se llamará sp_estadisticas_franquicia. Se debe considerar que este método recibe como parámetro de entrada el ID del establecimiento:

//PDO
$proc = $con->prepare('CALL sp_estadisticas_franquicia(?)');
$proc->bindParam(1, $ID_ESTABLECIMIENTO, PDO::PARAM_INT);
$proc->execute();
print("<table>");
while($res=$proc->fetch(PDO::FETCH_OBJ)){
print("<tr>");
print("<td>".$res->NO_EMPLEADOS."</td>");
print("<td>".$res->VENTA_MEDIA."</td>");
print("<td>".$res->MA_VENTAS"</td>");
print("<td>".$res->MI_VENTAS"</td>");
print("</tr>");
}
print("</table>");



//MySQLi
if ($stmt = $mysqli->prepare("CALL sp_estadisticas_franquicia(?)") ){
/* ligar parámetros para marcadores */
$stmt->bind_param("d", $Id_ESTABLECIMIENTO); 
/* ejecutar la consulta */
$stmt->execute();
$resultado = $stmt->get_result();
print("<table>");
while($rows=$resultado->fetch_assoc()){
print("<tr>");
print("<td>".$rows["NO_EMPLEADOS"]);
print("<td>".$rows["VENTA_MEDIA"]);
print("<td>".$rows["MA_VENTA"]);
print("<td>".$rows["MI_VENTA"]);
print("</tr>");
}
print("</table>"); 
/* cerrar sentencia */
$stmt->close();
}
else{
echo "Error al ejecutar el procedimiento".$mysqli->error;
}

Como se puede leer en el anterior código, simplemente es usar la sentencia CALL y ejecutar normalmente el procedimiento como si se tratase de un comando cualquiera.

PDO vs. MySQLi, ¿Cuál deberías elegir?

Algunos programadores con los que he hablado son muy PRO PDO y otros muy PRO MySQLi, pero desde mi humilde opinión yo te diría que depende. Lo primero es descartar el API clásica (durante mi época de estudiante me pasé dos años estudiándola y ya de aquella estaba desactualizada, así que imagino que años después de terminar esos estudios, lo único que conseguirás tarde o temprano serán problemas para tus proyectos), ya que sería una perdida de recursos para tus proyectos. Entre MySQLi y PDO también “depende” de las necesidades de tu proyecto. Te invito a que visites este link oficial del sitio de PHP para que veas un cuadro de comparación de beneficios entre las APIs, de seguro te ayudará a sacar conclusiones. Yo suelo trabajar con PDO  ya que en la mayoría de mis proyectos trabajo el polimorfismo y la verdad es que ya me he acostumbrado, pero cada cual debe encontrar el que más cómodo lo haga trabajar.

Fuente

También te puede interesar ...

Deja un comentario

* Al utilizar este formulario, aceptas que este sitio web almacene y maneje tus datos.

Adblock Detectado!!

Ayúdanos deshabilitando la extensión AdBlocker de tu navegador para visitar esta web.
Si no sabes hacerlo en Chrome, consulta el siguiente enlace. Si utilizas Firefox, puedes consultar este otro enlace.
Esto mejorará tu experiencia en este sitio web.