Cómo conectar una aplicación PHP a una base de datos MySQL: Ejemplos y buenas prácticas
Conectar una aplicación PHP a una base de datos MySQL es uno de los primeros pasos que todo desarrollador web debe dominar. Aunque parezca un proceso complejo al principio, la realidad es que con las herramientas adecuadas y siguiendo una serie de pasos lógicos, cualquier persona puede lograrlo de forma segura y eficiente.
En esta guía extensa, no solo te mostraremos ejemplos prácticos de código, sino que también explicaremos las diferencias entre las dos formas más comunes de hacerlo: MySQLi y PDO. Además, te daremos una serie de buenas prácticas para que tu código sea robusto, seguro y fácil de mantener.
Si estás empezando o necesitas refrescar conceptos, has llegado al lugar indicado. Vamos a desglosar todo el proceso, desde la creación de la base de datos hasta la ejecución de consultas complejas, con un lenguaje claro y ejemplos que puedes copiar y pegar en tu proyecto.
¿Qué necesitas para empezar?
Antes de escribir una sola línea de código PHP, es fundamental tener claro qué herramientas necesitas. No te preocupes, no necesitas nada extraordinario. Aquí tienes la lista básica:
- Un servidor web (como Apache o Nginx) con PHP instalado (versión 7.4 o superior es recomendable).
- Un servidor de base de datos MySQL (o MariaDB, que es totalmente compatible).
- Credenciales de acceso: normalmente un usuario, una contraseña, un host (generalmente
localhost) y el nombre de la base de datos. - Un editor de código (como VS Code, Sublime Text o incluso el Bloc de notas).
Si estás utilizando un panel de control como Syspanel (recuerda que el puerto de acceso es el 2106), probablemente ya tienes todo esto instalado y configurado. En ese caso, solo necesitas crear la base de datos y el usuario desde el panel, y tendrás las credenciales listas para usar.
Paso 1: Crear la base de datos y el usuario
Este paso es previo a la programación y es crucial. No puedes conectar tu aplicación PHP a una base de datos que no existe. Aunque puedes hacerlo desde la línea de comandos, lo más común es usar una herramienta gráfica como phpMyAdmin o el gestor incluido en tu panel de control.
Desde Syspanel
Si usas Syspanel, inicia sesión en el panel (puerto 2106) y busca la sección de bases de datos. Ahí podrás:
- Crear una nueva base de datos con un nombre descriptivo, por ejemplo,
mi_aplicacion_db. - Crear un usuario específico para esa base de datos, con su propia contraseña.
- Asignar los privilegios necesarios (normalmente todos los privilegios para ese usuario en esa base de datos).
[TIP] No uses el usuario
rooten tu aplicación. Es una mala práctica de seguridad. Crea siempre un usuario específico con permisos limitados a la base de datos que necesitas.
Desde phpMyAdmin
Si tu hosting no tiene Syspanel, probablemente uses cPanel o Plesk. El proceso es similar: busca el icono de "Bases de datos MySQL", crea la base, luego el usuario y finalmente asigna el usuario a la base con todos los privilegios.
Una vez que tengas los datos de conexión (host, nombre de base, usuario y contraseña), ya puedes pasar a la parte de programación.
Paso 2: Configurar la conexión con MySQLi
MySQLi (MySQL Improved) es una extensión de PHP que te permite interactuar con bases de datos MySQL. Es una de las formas más tradicionales y sigue siendo muy utilizada, especialmente en proyectos que no requieren cambiar de motor de base de datos.
Conexión básica con MySQLi
El siguiente código muestra cómo realizar una conexión simple. Lo guardaremos en un archivo llamado conexion.php para reutilizarlo en todo el proyecto.
<?php
// Datos de configuración
$servidor = "localhost";
$usuario = "mi_usuario";
$contrasena = "mi_contraseña_segura";
$base_datos = "mi_aplicacion_db";
// Crear la conexión
$conexion = new mysqli($servidor, $usuario, $contrasena, $base_datos);
// Verificar si hay errores
if ($conexion->connect_error) {
die("Error de conexión: " . $conexion->connect_error);
}
echo "Conexión exitosa";
// El resto de tu código iría aquí
$conexion->close();
?>
Explicación línea por línea:
new mysqli(...): Crea un nuevo objeto de conexión.connect_error: Propiedad que contiene el error si la conexión falla.die(...): Detiene la ejecución del script y muestra el error. En un entorno de producción, no deberías mostrar el error real, sino un mensaje genérico.
Consultas con MySQLi
Una vez conectados, podemos ejecutar consultas SQL. Aquí tienes un ejemplo de cómo obtener datos de una tabla llamada usuarios:
<?php
// Incluir la conexión
require_once 'conexion.php';
// Consulta SQL
$sql = "SELECT id, nombre, email FROM usuarios";
$resultado = $conexion->query($sql);
if ($resultado->num_rows > 0) {
// Recorrer los resultados
while ($fila = $resultado->fetch_assoc()) {
echo "ID: " . $fila["id"] . " - Nombre: " . $fila["nombre"] . " - Email: " . $fila["email"] . "<br>";
}
} else {
echo "No se encontraron usuarios.";
}
$conexion->close();
?>
[WARNING] En este ejemplo usamos
query()para una consulta SELECT. Nunca uses esta función para consultas que incluyan datos del usuario directamente (como en un login) sin prepararlas, ya que te expones a ataques de inyección SQL. Más adelante veremos cómo hacerlo correctamente.
Paso 3: Configurar la conexión con PDO
PDO (PHP Data Objects) es una interfaz más moderna y flexible. A diferencia de MySQLi, que está atado a MySQL, PDO es un adaptador de base de datos que te permite trabajar con MySQL, PostgreSQL, SQLite, etc., sin cambiar el código de conexión. Solo cambias el DSN (Data Source Name).
Conexión básica con PDO
La conexión con PDO es ligeramente diferente:
<?php
$servidor = "localhost";
$usuario = "mi_usuario";
$contrasena = "mi_contraseña_segura";
$base_datos = "mi_aplicacion_db";
try {
// Crear la conexión PDO
$conexion = new PDO("mysql:host=$servidor;dbname=$base_datos;charset=utf8mb4", $usuario, $contrasena);
// Configurar el modo de error para que lance excepciones
$conexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Conexión exitosa";
} catch (PDOException $e) {
die("Error de conexión: " . $e->getMessage());
}
?>
Diferencias clave con MySQLi:
- Usamos
try...catchpara manejar errores, lo cual es más elegante y fácil de depurar. - El
charset=utf8mb4es fundamental para soportar caracteres especiales (emojis, acentos, etc.). - La conexión se configura con atributos, como el modo de error.
Consultas con PDO
Ahora veamos cómo hacer una consulta SELECT con PDO:
<?php
require_once 'conexion_pdo.php'; // Asumiendo que guardamos la conexión aquí
$sql = "SELECT id, nombre, email FROM usuarios";
$stmt = $conexion->query($sql);
// PDO::FETCH_ASSOC devuelve un array asociativo
$usuarios = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($usuarios as $usuario) {
echo "ID: " . $usuario["id"] . " - Nombre: " . $usuario["nombre"] . " - Email: " . $usuario["email"] . "<br>";
}
?>
Paso 4: MySQLi vs PDO: ¿Cuál es mejor?
Esta es una de las preguntas más frecuentes entre los desarrolladores. No hay una respuesta única, pero podemos darte una comparativa clara para que decidas según tu proyecto.
| Característica | MySQLi | PDO |
|---|---|---|
| Soporte de bases de datos | Solo MySQL/MariaDB | Más de 12 bases de datos (MySQL, PostgreSQL, SQLite, etc.) |
| Orientación a objetos | Sí, pero también tiene versión procedural | Solo orientado a objetos |
| Consultas preparadas | Sí | Sí, y son más fáciles de usar |
| Manejo de errores | Básico (con die o if) | Excepciones avanzadas con try...catch |
| Rendimiento | Muy bueno | Muy bueno (similar) |
| Curva de aprendizaje | Baja | Media (pero más lógica a largo plazo) |
¿Cuándo usar MySQLi?
- Si tu proyecto es pequeño y sabes que nunca cambiarás de base de datos.
- Si vienes de la programación procedural y te sientes más cómodo con funciones como
mysqli_connect(). - Si estás manteniendo un código antiguo que ya usa MySQLi.
¿Cuándo usar PDO?
- Si quieres escalar tu aplicación y tener la flexibilidad de cambiar de motor de base de datos en el futuro (por ejemplo, migrar de MySQL a PostgreSQL).
- Si prefieres un código más limpio y moderno con manejo de excepciones.
- Si estás empezando un proyecto nuevo, PDO es la opción recomendada por la comunidad PHP actual.
[INFO] La mayoría de los frameworks PHP modernos (Laravel, Symfony, etc.) utilizan PDO internamente. Aprender PDO te será útil si decides dar el salto a un framework.
Paso 5: Buenas prácticas para una conexión segura y eficiente
Conectar tu aplicación a MySQL es solo el primer paso. Para que tu código sea profesional, debes seguir una serie de buenas prácticas que te ahorrarán muchos dolores de cabeza.
1. Usa consultas preparadas (Prepared Statements)
Esta es la regla de oro para evitar la inyección SQL, uno de los ataques más comunes y peligrosos. En lugar de concatenar variables directamente en la consulta SQL, usamos marcadores de posición y luego vinculamos los valores.
Con MySQLi (preparada):
<?php
require_once 'conexion.php';
$nombre_usuario = $_POST['nombre'];
$email = $_POST['email'];
$sql = "INSERT INTO usuarios (nombre, email) VALUES (?, ?)";
$stmt = $conexion->prepare($sql);
// "ss" indica que ambos parámetros son strings
$stmt->bind_param("ss", $nombre_usuario, $email);
if ($stmt->execute()) {
echo "Usuario insertado correctamente.";
} else {
echo "Error: " . $stmt->error;
}
$stmt->close();
$conexion->close();
?>
Con PDO (preparada):
<?php
require_once 'conexion_pdo.php';
$nombre_usuario = $_POST['nombre'];
$email = $_POST['email'];
$sql = "INSERT INTO usuarios (nombre, email) VALUES (:nombre, :email)";
$stmt = $conexion->prepare($sql);
$stmt->bindParam(':nombre', $nombre_usuario);
$stmt->bindParam(':email', $email);
if ($stmt->execute()) {
echo "Usuario insertado correctamente.";
} else {
echo "Error al insertar.";
}
?>
[WARNING] NUNCA hagas esto:
$sql = "SELECT * FROM usuarios WHERE nombre = '$nombre'". Es una invitación abierta a los atacantes. Un simple' OR '1'='1en el campo de nombre podría borrar tu base de datos.
2. No muestres errores reales en producción
Los errores de conexión o de SQL pueden revelar información sensible sobre tu servidor (rutas, versiones, etc.). En producción, configura tu aplicación para que los errores se registren en un archivo de log, pero que el usuario final vea un mensaje genérico como "Ha ocurrido un error. Inténtalo de nuevo más tarde."
3. Cierra la conexión cuando termines
Aunque PHP cierra las conexiones automáticamente al finalizar el script, es una buena práctica cerrarlas explícitamente si vas a hacer procesos largos o si tienes muchas conexiones abiertas.
4. Usa variables de entorno para las credenciales
No es buena idea tener las contraseñas de la base de datos en el código fuente, especialmente si vas a subir tu proyecto a un repositorio público como GitHub. Utiliza variables de entorno o archivos de configuración que estén fuera del alcance público.
Ejemplo con variables de entorno (.env):
DB_HOST=localhost
DB_USER=mi_usuario
DB_PASS=mi_contraseña_segura
DB_NAME=mi_aplicacion_db
Y en PHP:
$servidor = getenv('DB_HOST') ?: 'localhost';
$usuario = getenv('DB_USER');
$contrasena = getenv('DB_PASS');
$base_datos = getenv('DB_NAME');
5. Establece el juego de caracteres correcto
Asegúrate de que la conexión use utf8mb4 para evitar problemas con caracteres especiales. En MySQLi, lo haces así:
$conexion->set_charset("utf8mb4");
En PDO, lo añadimos al DSN como vimos anteriormente.
6. Usa índices en tus tablas
Esto no es específico de PHP, pero es crucial para el rendimiento. Si tus consultas son lentas, revisa que las columnas que usas en las cláusulas WHERE y JOIN tengan índices.
Paso 6: Ejemplo completo y práctico
Vamos a unir todo lo aprendido en un ejemplo funcional que podrías usar en un sistema de login simple. Este ejemplo usará PDO y consultas preparadas.
Archivo: conexion.php
<?php
// Configuración
$servidor = "localhost";
$usuario = "mi_usuario";
$contrasena = "mi_contraseña_segura";
$base_datos = "mi_aplicacion_db";
try {
$conexion = new PDO("mysql:host=$servidor;dbname=$base_datos;charset=utf8mb4", $usuario, $contrasena);
$conexion->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
// En producción, registra el error en un archivo de log
error_log("Error de conexión: " . $e->getMessage());
die("Lo sentimos, ha ocurrido un error en el servidor.");
}
?>
Archivo: login.php
<?php
require_once 'conexion.php';
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$email = $_POST['email'];
$contrasena = $_POST['contrasena'];
// Consulta preparada para evitar inyección SQL
$sql = "SELECT id, nombre, contrasena_hash FROM usuarios WHERE email = :email LIMIT 1";
$stmt = $conexion->prepare($sql);
$stmt->bindParam(':email', $email);
$stmt->execute();
$usuario = $stmt->fetch(PDO::FETCH_ASSOC);
if ($usuario && password_verify($contrasena, $usuario['contrasena_hash'])) {
// Contraseña correcta
session_start();
$_SESSION['usuario_id'] = $usuario['id'];
$_SESSION['usuario_nombre'] = $usuario['nombre'];
echo "¡Bienvenido, " . $usuario['nombre'] . "!";
// Redirigir a otra página
// header("Location: dashboard.php");
} else {
echo "Credenciales incorrectas.";
}
}
?>
[TIP] Usa la función
password_hash()para almacenar las contraseñas ypassword_verify()para verificarlas. Nunca almacenes contraseñas en texto plano.
Paso 7: Errores comunes y solución de problemas
Es normal encontrar errores al principio. Aquí tienes los más comunes y cómo resolverlos:
1. "Connection refused" o "Access denied for user"
- Revisa que el host sea
localhost(o127.0.0.1). - Verifica que el usuario y la contraseña sean correctos.
