Bases de datos con PHP: mysqli
La inmensa mayoría de aplicaciones PHP almacenan sus datos en una base de datos relacional. PHP ofrece dos extensiones para trabajar con MySQL/MariaDB: mysqli (MySQL Improved) y PDO. Esta lección cubre mysqli con su API procedural, que es la forma más directa y la más cercana al resto del código PHP que has visto en este manual.
mysqli vs PDO
La diferencia principal: PDO soporta múltiples motores de base de datos (PostgreSQL, SQLite, etc.) usando la misma API, mientras que mysqli es exclusivo de MySQL/MariaDB. Para un proyecto que solo usará MySQL, mysqli procedural es la opción más sencilla y directa.
Conexión
mysqli_connect() abre la conexión y devuelve un identificador que pasarás al resto de funciones. Comprueba siempre que la conexión fue exitosa:
<?php
$host = "localhost";
$usuario = "mi_usuario";
$clave = "mi_contraseña";
$bd = "mi_base_de_datos";
$link = mysqli_connect($host, $usuario, $clave, $bd);
if (!$link) {
// En producción: log del error y mensaje genérico al usuario
error_log("Error de conexión: " . mysqli_connect_error());
die("No se pudo conectar a la base de datos.");
}
// Asegura UTF-8 en la conexión
mysqli_set_charset($link, "utf8mb4");
Nota: En un proyecto real, las credenciales van en un archivo de configuración fuera del web root, no escritas directamente en el script. La lección de estructura de proyecto muestra cómo organizarlo.
Consultas SELECT
mysqli_query() ejecuta la consulta y devuelve un recurso de resultado. Usa mysqli_fetch_assoc() para obtener cada fila como array asociativo:
<?php
$resultado = mysqli_query($link, "SELECT id, nombre, email FROM usuarios ORDER BY nombre");
if (!$resultado) {
error_log("Error en consulta: " . mysqli_error($link));
die("Error al obtener datos.");
}
while ($fila = mysqli_fetch_assoc($resultado)) {
echo $fila["nombre"] . " — " . $fila["email"] . "\n";
}
mysqli_free_result($resultado);
mysqli_num_rows() indica cuántas filas devolvió la consulta:
<?php
$resultado = mysqli_query($link, "SELECT id FROM usuarios WHERE activo = 1");
echo "Usuarios activos: " . mysqli_num_rows($resultado);
Si esperas una sola fila, llama a mysqli_fetch_assoc() una sola vez:
<?php
$resultado = mysqli_query($link, "SELECT * FROM usuarios WHERE id = 42");
$usuario = mysqli_fetch_assoc($resultado);
if ($usuario === null) {
echo "Usuario no encontrado.";
} else {
echo "Nombre: " . htmlspecialchars($usuario["nombre"]);
}
Nota: Nunca interpoles variables del usuario directamente en una consulta con mysqli_query(): es SQL injection. La próxima lección cubre los prepared statements, que es la forma correcta de incluir datos del usuario en consultas.
INSERT, UPDATE y DELETE simples
Para consultas que no devuelven filas, mysqli_query() devuelve true o false. mysqli_affected_rows() indica cuántas filas se vieron afectadas:
<?php
// Solo con valores que tú controlas, no con datos del usuario
$ok = mysqli_query($link, "UPDATE configuracion SET valor = 'activo' WHERE clave = 'modo'");
if (!$ok) {
error_log("Error: " . mysqli_error($link));
}
echo "Filas actualizadas: " . mysqli_affected_rows($link);
Para insertar y obtener el ID autoincremental generado:
<?php
mysqli_query($link, "INSERT INTO log (mensaje, fecha) VALUES ('inicio', NOW())");
echo "ID insertado: " . mysqli_insert_id($link);
Cerrar la conexión
PHP cierra la conexión automáticamente al final del script, pero es buena práctica cerrarla explícitamente cuando ya no la necesitas:
<?php
mysqli_close($link);
Recapitulación
- Conecta con
mysqli_connect($host, $usuario, $clave, $bd). Comprueba que el resultado no esfalse. Establece el charset conmysqli_set_charset($link, "utf8mb4"). mysqli_query($link, $sql)ejecuta la consulta. Para SELECT devuelve un recurso; para INSERT/UPDATE/DELETE devuelvetrue/false.mysqli_fetch_assoc($resultado)obtiene la siguiente fila como array. Úsalo en unwhilepara múltiples filas, o una sola vez si esperas un resultado.mysqli_num_rows()cuenta resultados de SELECT;mysqli_affected_rows()cuenta filas afectadas en escrituras;mysqli_insert_id()da el ID del último INSERT.- Nunca interpoles datos del usuario en
mysqli_query(). Usa prepared statements.
En la próxima lección: consultas preparadas con mysqli: prevención de SQL injection y operaciones de escritura seguras.