W3docs

PHP MySQLi

Aprende la extensión PHP MySQLi: conecta a MySQL, ejecuta consultas seguras con sentencias preparadas, maneja errores y compara MySQLi con PDO.

MySQLi ("MySQL Mejorado") es la extensión de PHP que se usa para conectarse a una base de datos MySQL o MariaDB, ejecutar consultas y leer los resultados. Este artículo explica qué es la extensión, cómo conectarse, cómo ejecutar consultas SELECT/INSERT/UPDATE de forma segura y cuándo usar MySQLi en lugar de PDO.

¿Qué es la extensión MySQLi?

La extensión MySQLi es la sucesora de las antiguas funciones mysql_* (que ya han sido eliminadas). Añade características que la extensión original nunca tuvo: sentencias preparadas, transacciones, múltiples sentencias y soporte adecuado para la autenticación de MySQL 4.1+. Se incluye con PHP y está habilitada por defecto en la mayoría de las instalaciones.

MySQLi expone la misma funcionalidad a través de dos interfaces:

  • Orientada a objetos — se trabaja con un objeto mysqli y se llaman métodos como $mysqli->query(). Este es el estilo que usa la mayoría del código moderno y el que sigue este artículo.
  • Procedimental — se llaman funciones como mysqli_connect() y mysqli_query() y se pasa la conexión como primer argumento.

Ambas hacen exactamente lo mismo; elige una y mantente consistente. La forma orientada a objetos es más corta y se lee de manera más natural.

Conectarse a una base de datos

Una conexión está representada por un objeto mysqli. Se crea pasando el host, el nombre de usuario, la contraseña y el nombre de la base de datos al constructor, y luego se verifica que tuvo éxito antes de hacer cualquier otra cosa:

<?php
$mysqli = new mysqli("localhost", "username", "password", "my_database");

// Always check the connection before using it.
if ($mysqli->connect_error) {
    die("Failed to connect to MySQL: " . $mysqli->connect_error);
}

// Recommended: use UTF-8 so accented characters and emoji are stored correctly.
$mysqli->set_charset("utf8mb4");

echo "Connected successfully";
?>

La propiedad connect_error contiene un mensaje legible cuando la conexión falla (o null si tiene éxito). Llamar a set_charset() justo después de conectarse evita errores de codificación sutiles más adelante. Para ver en detalle cómo abrir una conexión, consulta PHP mysqli_connect() y la referencia de connect().

Ejecutar una consulta SELECT

Una vez conectado, query() ejecuta SQL y devuelve un objeto de resultado sobre el que puedes iterar. fetch_assoc() devuelve una fila a la vez como un array asociativo, o null cuando no hay más filas:

<?php
$result = $mysqli->query("SELECT name, email FROM users");

if ($result->num_rows > 0) {
    while ($row = $result->fetch_assoc()) {
        echo "Name: " . $row["name"] . " - Email: " . $row["email"] . "<br>";
    }
} else {
    echo "No users found.";
}

$result->free();   // release the result set
$mysqli->close();  // close the connection when you are done
?>

num_rows te indica cuántas filas se devolvieron, para que puedas mostrar un mensaje amigable cuando una consulta no devuelve nada. Consulta PHP MySQL Select Data para ver más patrones de consulta.

Sentencias preparadas (la forma segura de usar entradas)

Nunca pegues la entrada del usuario directamente en una cadena de consulta — así es como ocurre la inyección SQL. Una sentencia preparada envía el SQL y los datos por separado, de modo que la base de datos trata la entrada estrictamente como un valor y nunca como SQL ejecutable.

Se escriben marcadores de posición ?, se llama a prepare() sobre la sentencia y luego se vinculan los valores reales con bind_param():

<?php
$age = 18;

$stmt = $mysqli->prepare("SELECT name, email FROM users WHERE age > ?");
$stmt->bind_param("i", $age);   // "i" = integer (s = string, d = double, b = blob)
$stmt->execute();

$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
    echo "Name: " . $row["name"] . " - Email: " . $row["email"] . "<br>";
}

$stmt->close();
?>

El primer argumento de bind_param() es una cadena de tipos: un carácter por marcador de posición — i (integer), s (string), d (double/float) o b (blob). Los argumentos restantes son los valores, en orden.

Nota: get_result() requiere el controlador mysqlnd, que es el predeterminado en PHP moderno. Si tu compilación no lo tiene, usa bind_result() para vincular columnas a variables en su lugar.

Para un recorrido dedicado, consulta PHP MySQL Prepared Statements.

Insertar y actualizar datos

El mismo patrón de sentencias preparadas funciona para escrituras. Después de un INSERT, el id auto-incrementado de la nueva fila está disponible en $mysqli->insert_id; después de un INSERT/UPDATE/DELETE, $mysqli->affected_rows te indica cuántas filas cambiaron:

<?php
$name  = "Ada Lovelace";
$email = "[email protected]";

$stmt = $mysqli->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->bind_param("ss", $name, $email);   // two strings
$stmt->execute();

echo "Inserted user #" . $mysqli->insert_id;
$stmt->close();
?>

Consulta PHP MySQL Insert Data y PHP MySQL Update Data para ver el panorama completo de CRUD.

Manejo de errores

Si una consulta falla, query() devuelve false y los detalles están en el objeto de conexión. Leer $mysqli->error después de una llamada fallida te dice qué salió mal:

<?php
if (!$mysqli->query("SELECT * FROM no_such_table")) {
    echo "Query failed (" . $mysqli->errno . "): " . $mysqli->error;
}
?>

En desarrollo puedes hacer que MySQLi lance excepciones automáticamente con mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT), que es el comportamiento predeterminado desde PHP 8.1. Lectura relacionada: PHP connect_error y PHP connect_errno.

MySQLi vs. PDO — ¿cuál debo usar?

Ambos son formas seguras y modernas de comunicarse con una base de datos. En resumen:

  • MySQLi solo funciona con MySQL/MariaDB. Expone algunas características específicas de MySQL (como consultas asíncronas) que PDO no tiene.
  • PDO (PHP Data Objects) habla con una docena de bases de datos a través de una sola API, por lo que cambiar de MySQL a PostgreSQL implica cambiar una cadena de conexión, no las consultas. También admite marcadores de posición con nombre (:name) que son más fáciles de leer.

Si sabes que solo usarás MySQL, MySQLi es perfectamente válido. Si la portabilidad importa, prefiere PDO. De cualquier forma, siempre usa sentencias preparadas.

Resumen

  • MySQLi es la extensión estándar para trabajar con MySQL/MariaDB en PHP, disponible en estilos orientado a objetos y procedimental.
  • Crea una conexión con new mysqli(...), verifica connect_error y establece el charset.
  • Usa query() + fetch_assoc() para leer datos e iterar sobre los resultados.
  • Usa sentencias preparadas (prepare()bind_param()execute()) para todo lo que involucre entrada del usuario y mantenerte seguro frente a la inyección SQL.
  • Revisa $mysqli->error / $mysqli->errno cuando una consulta falle, y prefiere PDO cuando necesites portabilidad entre bases de datos.

Práctica

Práctica
¿Cuáles son las características importantes de PHP MySQLi?
¿Cuáles son las características importantes de PHP MySQLi?
Was this page helpful?