¿Dejará PHP de ofrecer soporte técnico para MySQL pronto?: esta era la pregunta que se hacía la comunidad PHP cuando, al co­ne­c­tar­se con un servidor MySQL mediante la antigua extensión mysql, aparecía una aviso de error y la re­co­me­n­da­ción de cambiarse a ext/mysqli. Este mensaje empezó a mostrarse con la versión PHP 5.5, pero la extensión mysqli ya se había lanzado con PHP 5.0, es decir, en 2004.

Y ¿por qué tanto ne­r­vio­si­s­mo? Entre otras cosas, porque el equipo encargado de PHP en Oracle se percató de que aún eran muchos los que usaban ext/mysql, entre ellos pesos pesados del sector, como WordPress. Oracle decidió entonces iniciar un lento proceso de de­pre­ca­tion, es decir, una tra­n­si­ción para dejar atrás ext/mysql y re­em­pla­zar­la por la nueva extensión. No obstante, la antigua extensión no duró mucho más: dejó de existir con la versión PHP7. En este artículo te de­s­cri­bi­mos en detalle a su sucesora, MySQLi, mostrando ejemplos y ex­pli­ca­n­do las di­fe­re­n­cias concretas entre ambas ex­te­n­sio­nes.

Private Cloud powered by VMware
Pago por uso y el más alto nivel de seguridad de los datos.

Bajo la división Arsys Cloud Solutions, diseñamos So­lu­cio­nes a tu medida.

¿Qué es MySQLi de PHP?

MySQLi es una extensión mejorada (la i final es de improved) de PHP para acceder a bases de datos MySQL. MySQL es, junto con Oracle y Microsoft SQL Server, uno de los sistemas de gestión de bases de datos (es decir, un Database Ma­na­ge­me­nt System o DBMS) re­la­cio­na­les más populares a nivel mundial. Las bases de datos re­la­cio­na­les son un elemento central de Internet, ya que permiten procesar grandes ca­n­ti­da­des de datos y gua­r­dar­los de forma pe­r­ma­ne­n­te. Para hacerlo, dividen los complejos conjuntos de datos en partes y es­ta­ble­cen luego las re­la­cio­nes ne­ce­sa­rias entre ellos.

Este software, de­sa­rro­lla­do en 1994 por la compañía sueca MySQL AB, es di­s­tri­bui­do en la ac­tua­li­dad por Oracle Co­r­po­ra­tion mediante un sistema dual de licencias: además de la licencia pro­pie­ta­ria para empresas, Oracle ofrece también una versión con licencia GPL y de código abierto. Este doble sistema de licencias da a las empresas la opo­r­tu­ni­dad de de­sa­rro­llar apli­ca­cio­nes propias basadas en MySQL sin necesidad de recurrir a una licencia open source.

¿Qué abarca la extensión mysqli?

En PHP existen tres maneras de acceder a una base de datos MySQL. La más antigua es utilizar la extensión MySQL, la cual, sin embargo, está co­n­si­de­ra­da desfasada o de­pre­ca­ted desde la versión PHP 5.5 y fue eliminada co­m­ple­ta­me­n­te con PHP 7. En esta última versión, la función mysql ya no funciona y ha sido re­em­pla­za­da por mysqli.

Además de la anticuada extensión mysql, para acceder a una base de datos MySQL, PHP también ofrece los PHP Data Objects (PDO), cuya apli­ca­ción es pa­r­ti­cu­la­r­me­n­te flexible. La tercera opción es usar la MySQL Improved Extension, es decir, la extensión mysqli, que ya desde PHP 5 permite acceder a bases de datos MySQL. El siguiente snippet o fragmento de código puede ayudarte a hacerte una idea de cómo funciona la extensión MySQLi de PHP.

Snippet: enviar una consulta SQL a la base de datos

Para enviar queries o consultas a la base de datos, se utiliza la orden query($sql) :

<?php
$mysqli = new mysqli("localhost", "user", "password", "database");
if ($mysqli->connect_errno) {
   die("error de conexión: " . $mysqli->connect_error);
}
 
$sql = "UPDATE tabla SET columna = 'Valor' WHERE id = 1";
$mysqli->query($sql);
?>

¿Qué ventajas tiene MySQLi?

Al contrario que su pre­de­ce­so­ra, la extensión mysqli no solo puede usarse de forma pro­ce­du­ral, sino también de forma orientada a objetos. Una ventaja de la pro­gra­ma­ción orientada a objetos es que el código escrito puede co­rre­gi­r­se y adaptarse fá­ci­l­me­n­te a po­s­te­rio­ri. Esto puede ser útil, por ejemplo, para crear nuevas clases que puedan heredar el co­m­po­r­ta­mie­n­to y las pro­pie­da­des de otras clases ya exi­s­te­n­tes. Así, se acorta co­n­si­de­ra­ble­me­n­te el tiempo de de­sa­rro­llo y se facilita la ada­p­ta­ción del programa ante un entorno cambiante o nuevos re­qui­si­tos.

Otra ventaja im­po­r­ta­n­te de MySQLi son los prepared sta­te­me­nts o consultas pre­pa­ra­das. Se trata, por así decirlo, de in­s­tru­c­cio­nes ya pre­pa­ra­das para el sistema de la base de datos. Mientras que los sta­te­me­nts co­n­ve­n­cio­na­les contienen valores de pa­rá­me­tros, los prepared sta­te­me­nts contienen en su lugar los llamados ma­r­ca­do­res de posición o ca­ra­c­te­res comodín. Cuando se ejecuta en el sistema de la base de datos un statement con distintos pa­rá­me­tros varias veces (en un bucle, por ejemplo), los prepared sta­te­me­nts permiten aumentar la velocidad, puesto que las órdenes en sí ya se en­cue­n­tran co­m­pi­la­das en la base de datos y si­m­ple­me­n­te han de ser eje­cu­ta­das con los nuevos pa­rá­me­tros. Además, los prepared sta­te­me­nts son una medida efectiva de pre­ve­n­ción contra las in­ye­c­cio­nes SQL, ya que el sistema de la base de datos ha de comprobar la validez de los pa­rá­me­tros antes de pro­ce­sar­los.

Snippet: prepared sta­te­me­nts en MySQLi

En MySQLi, un ejemplo de prepared sta­te­me­nts podría tener la siguiente forma:

<?php
$mysqli = new mysqli("localhost", "user", "Password", "database");
if ($mysqli->connect_errno) {
    die("error de conexión: " . $mysqli->connect_error);
}
$sql = "UPDATE user SET email = ?, contraseña = ? WHERE id = ?";
$statement = $mysqli->prepare($sql);
$statement->bind_param('ssi', $email, $contraseña, $id);
//Asignar valores a las variables 
$id= 1;
$email = "un@ejemplo.es";
$contraseña = "nueva contraseña";
$statement->execute();
?>

La orden bind_param() relaciona los pa­rá­me­tros de la consulta SQL con las variables. En el ejemplo de arriba, el primer argumento de bind_param(), que tiene el valor ssi, describe los tipos de parámetro. En este caso, ssi indica que hay tres pa­rá­me­tros en la consulta: el primero es de tipo string, el segundo también y el tercero es de tipo integer. Para cifras de coma flotante existe, además, el valor d.

Una vez las variables han sido re­la­cio­na­das con los pa­rá­me­tros, a estos últimos se les asignan los valores co­rre­s­po­n­die­n­tes y, mediante $statement→execute(), se envía el prepared statement a la base de datos. En co­m­pa­ra­ción con la extensión PDO, sin embargo, este proceso es cla­ra­me­n­te más co­m­pli­ca­do.

mysqli() versus mysql(): ¿por qué se modificó la extensión de PHP?

No quedaba más remedio que cambiar a MySQLi, ya que la antigua extensión mysql había quedado anticuada. Además, al de­sa­rro­llar la extensión antigua, se había intentado que fuera co­m­pa­ti­ble con las versiones an­te­rio­res, de forma que el código resultaba difícil de ac­tua­li­zar, puesto que databa de los inicios de PHP y MySQL y, en parte, no había sido de­sa­rro­lla­do de la mejor manera.

Si, por ejemplo, no se indicaba ningún recurso de conexión ex­plí­ci­ta­me­n­te, todas las funciones in­te­n­ta­ban utilizar la última conexión que se había producido. En el peor de los casos, mysql_query() podía incluso acceder a una base de datos to­ta­l­me­n­te distinta. El ide­n­ti­fi­ca­dor de conexión era opcional en la extensión antigua, mientras que en la nueva sí debe indicarse. También se han añadido, además, prepared sta­te­me­nts, que hacen que la lectura de los datos de la base de datos sea más rápida y más segura.

Por suerte, muchas funciones pueden mo­di­fi­car­se si­m­ple­me­n­te añadiendo una i a la función mysql(). No obstante, existen algunas di­fe­re­n­cias ambas ex­te­n­sio­nes.

Snippet: ide­n­ti­fi­ca­dor de conexión en MySQL y MySQLi

Algunas funciones de mysqli() requieren un ide­n­ti­fi­ca­dor de conexión, es decir, una variable PHP generada al realizar la conexión con la base de datos. En el siguiente ejemplo, será $link.

<?php
// mysql() establecer conexión:
mysql_connect("localhost", "root", "", "test");
// mysqli() establecer conexión:
$link = mysqli_connect("localhost", "root", "", "test");
?>

Snippet: leer datos de la tabla de la base de datos

La función mysqli_query() necesita un ide­n­ti­fi­ca­dor de conexión; la función mysqli_fetch_array(), en cambio, no.

<?php
$link = mysqli_connect("localhost", "root", "", "test");
// Leer registros:
 $registros = mysqli_query($link,
 "SELECT `nombre`, `texto`, `fecha` FROM `mensajes`");
// Mostrar registros:
while (list($nombre, $texto, $fecha) = mysqli_fetch_array($registros)) {
 echo "<p>$nombre - $titel - $texto - $fecha</p>";
}
?>

Además de la función me­n­cio­na­da, las si­guie­n­tes funciones, entre otras, también requieren un ide­n­ti­fi­ca­dor de conexión:

En resumen: MySQLi es más seguro y más rápido

El cambio a MySQLi era necesario para aumentar la velocidad de acceso a las bases de datos. A la nueva extensión se le añadieron prepared sta­te­me­nts o consultas pre­pa­ra­das que, además, mejoran la seguridad de la conexión al prevenir in­ye­c­cio­nes SQL. Logran pre­ve­ni­r­las porque obligan al sistema de la base de datos a comprobar si los pa­rá­me­tros son válidos antes de pro­ce­sar­los. Por si eso fuera poco, el nuevo código puede ac­tua­li­zar­se de forma mucho más fácil gracias a la pro­gra­ma­ción orientada a objetos.

Ir al menú principal