# Novedad en PHP: MySQLi

*¿Dejará PHP de ofrecer soporte técnico para MySQL pronto?*: esta era la pregunta que se hacía la comunidad PHP cuando, al conectarse con un servidor MySQL mediante la antigua extensión *mysql*, aparecía una aviso de error y la recomendació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 nerviosismo? 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 *deprecation*, es decir, una transición para dejar atrás *ext/mysql* y reemplazarla 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 describimos en detalle a su sucesora, MySQLi, mostrando ejemplos y explicando las diferencias concretas entre ambas extensiones.

## ¿Qué es MySQLi de PHP?

MySQLi es una extensión mejorada (la *i* final es de *improved*) de [PHP](https://www.ionos.es/digitalguide/paginas-web/creacion-de-paginas-web/tutorial-de-php-fundamentos-basicos-para-principiantes/ "Tutorial de PHP: fundamentos básicos para principiantes") para acceder a bases de datos MySQL. [MySQL](https://www.ionos.es/digitalguide/servidores/know-how/guia-para-aprender-a-utilizar-mysql/ "Guía para aprender a utilizar MySQL") es, junto con Oracle y Microsoft SQL Server, uno de los sistemas de gestión de bases de datos (es decir, un [Database Management System o DBMS](https://www.ionos.es/digitalguide/hosting/cuestiones-tecnicas/sistema-gestor-de-base-de-datos-sgbd/ "Sistema gestor de base de datos (SGBD)")) relacionales más populares a nivel mundial. Las [bases de datos relacionales](https://www.ionos.es/digitalguide/hosting/cuestiones-tecnicas/bases-de-datos-relacionales/ "Bases de datos relacionales") son un elemento central de Internet, ya que permiten procesar grandes cantidades de datos y guardarlos de forma permanente. Para hacerlo, dividen los complejos conjuntos de datos en partes y establecen luego las relaciones necesarias entre ellos.

Este *software*, desarrollado en 1994 por la compañía sueca MySQL AB, es distribuido en la actualidad por Oracle Corporation mediante un sistema dual de licencias: además de la licencia propietaria 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 oportunidad de desarrollar aplicaciones 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á considerada **desfasada o *deprecated* desde la versión PHP 5.5** y fue eliminada completamente con PHP 7. En esta última versión, la función *mysql* ya no funciona y ha sido reemplazada 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 aplicación es particularmente 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](https://www.ionos.es/digitalguide/hosting/cuestiones-tecnicas/bases-de-datos/ "Bases de datos"), se utiliza la orden *query($sql)* :

```none
<?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 predecesora, la extensión *mysqli* no solo puede usarse de forma procedural, sino también de forma **orientada a objetos**. Una ventaja de la programación orientada a objetos es que el código escrito puede corregirse y adaptarse fácilmente *a posteriori*. Esto puede ser útil, por ejemplo, para crear nuevas clases que puedan heredar el comportamiento y las propiedades de otras clases ya existentes. Así, se acorta considerablemente el tiempo de desarrollo y se facilita la adaptación del programa ante un entorno cambiante o nuevos requisitos.

Otra ventaja importante de MySQLi son los [prepared statements](https://www.ionos.es/digitalguide/paginas-web/desarrollo-web/prepared-statements/ "Prepared statements") o *consultas preparadas*. Se trata, por así decirlo, de instrucciones ya preparadas para el sistema de la base de datos. Mientras que los *statements* convencionales contienen valores de parámetros, los *prepared statements* contienen en su lugar los llamados marcadores de posición o caracteres comodín. Cuando se ejecuta en el sistema de la base de datos un *statement* con distintos parámetros varias veces (en un bucle, por ejemplo), los *prepared statements* permiten aumentar la velocidad, puesto que las órdenes en sí ya se encuentran compiladas en la base de datos y simplemente han de ser ejecutadas con los nuevos parámetros. Además, los *prepared statements* son una medida efectiva de prevención contra las [inyecciones SQL](https://www.ionos.es/digitalguide/servidores/seguridad/inyeccion-sql-principios-y-precauciones/ "Inyección SQL: principios y precauciones"), ya que el sistema de la base de datos ha de comprobar la validez de los parámetros antes de procesarlos.

***Snippet*: *prepared statements* en MySQLi**

En MySQLi, un ejemplo de *prepared statements* podría tener la siguiente forma:

```none
<?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 parámetros 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 parámetros en la consulta: el primero es de tipo *string*, el segundo también y el tercero es de tipo *intege*r. Para cifras de coma flotante existe, además, el valor *d*.

Una vez las variables han sido relacionadas con los parámetros, a estos últimos se les asignan los valores correspondientes y, mediante *$statement→execute()*, se envía el *prepared statement* a la base de datos. En comparación con la extensión PDO, sin embargo, este proceso es claramente más complicado.

## 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 desarrollar la extensión antigua, se había intentado que fuera compatible con las versiones anteriores, de forma que **el código resultaba difícil de actualizar**, puesto que databa de los inicios de PHP y MySQL y, en parte, no había sido desarrollado de la mejor manera.

Si, por ejemplo, no se indicaba ningún **recurso de conexión** explícitamente, todas las funciones intentaban 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 totalmente distinta. El identificador 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 statements,* 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 modificarse simplemente añadiendo una *i* a la función *mysql()*. No obstante, existen algunas diferencias ambas extensiones.

***Snippet*: identificador de conexión en MySQL y MySQLi**

Algunas funciones de *mysqli()* requieren un identificador 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*.

```none
<?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 identificador de conexión; la función *mysqli\_fetch\_array(*), en cambio, no.

```none
<?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 mencionada, las siguientes funciones, entre otras, también requieren un identificador de conexión:

- [*mysqli\_set\_charset()*](http://de2.php.net/manual/de/mysqli.set-charset.php)
- [*mysqli\_real\_escape\_string()*](http://de2.php.net/manual/de/mysqli.real-escape-string.php)
- [*mysqli\_insert\_id()*](http://de2.php.net/manual/de/mysqli.insert-id.php)

## 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 statements* o consultas preparadas que, además, mejoran la seguridad de la conexión al prevenir inyecciones SQL. Logran prevenirlas porque obligan al sistema de la base de datos a comprobar si los parámetros son válidos antes de procesarlos. Por si eso fuera poco, el nuevo código puede actualizarse de forma mucho más fácil gracias a la programación orientada a objetos.


This is a markdown version of: [https://www.ionos.es/digitalguide/hosting/cuestiones-tecnicas/introduccion-a-mysqli/](https://www.ionos.es/digitalguide/hosting/cuestiones-tecnicas/introduccion-a-mysqli/) for AI/LLM consumption.