Tema 18

PHP y MySQL (Conexión, Consultas y Buenas Prácticas)

Aprende a integrar PHP con el motor de base de datos MySQL/MariaDB: conexión con PDO MySQL, codificación UTF-8 mb4, operaciones CRUD completas y control de transacciones.

La Alianza Clásica de la Web: PHP & MySQL

La combinación de PHP y MySQL (o su bifurcación comunitaria de alto rendimiento, MariaDB) impulsa más del 75% de la web mundial, desde plataformas CMS como WordPress hasta aplicaciones empresariales y sistemas SaaS.

La Cadena de Conexión DSN para MySQL:

// Conexión estándar a MySQL con PDO
$host    = '127.0.0.1'; // Mejor que 'localhost' para forzar protocolo TCP/IP rápido
$port    = '3306';
$db      = 'mi_proyecto_db';
$user    = 'usuario_app';
$pass    = 'password_seguro';
$charset = 'utf8mb4'; // ¡CRÍTICO! Admite tildes, caracteres especiales y emojis

$dsn = "mysql:host=$host;port=$port;dbname=$db;charset=$charset";

$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];

try {
    $pdo = new PDO($dsn, $user, $pass, $options);
} catch (PDOException $e) {
    // En producción, registra el error en un log privado y muestra un mensaje genérico al usuario
    error_log("Fallo de conexión a MySQL: " . $e->getMessage());
    die("Lo sentimos, ocurrió un problema al conectar con el servicio de datos.");
}

Operaciones CRUD Esenciales con PDO MySQL

Toda aplicación relacional se fundamenta en las cuatro operaciones básicas sobre datos:

1. Crear (INSERT) y Obtener el Último ID:

$sql = "INSERT INTO estudiantes (nombre, email, cohorte) VALUES (:nombre, :email, :cohorte)";
$stmt = $pdo->prepare($sql);
$stmt->execute([
    'nombre'  => 'Juan Martínez',
    'email'   => '[email protected]',
    'cohorte' => '2026-A'
]);

// Obtener el ID autoincremental generado por MySQL
$nuevoId = $pdo->lastInsertId();
echo "Estudiante matriculado con el ID #{$nuevoId}";

2. Leer (SELECT) con Filtros Seguros:

$stmt = $pdo->prepare("SELECT id, nombre, email FROM estudiantes WHERE cohorte = :cohorte ORDER BY nombre ASC");
$stmt->execute(['cohorte' => '2026-A']);
$estudiantes = $stmt->fetchAll();

foreach ($estudiantes as $estudiante) {
    echo "ID: {$estudiante['id']} - Nombre: {$estudiante['nombre']}<br>";
}

3. Actualizar (UPDATE) y Contar Filas Afectadas:

$stmt = $pdo->prepare("UPDATE estudiantes SET cohorte = :nuevaCohorte WHERE id = :id");
$stmt->execute([
    'nuevaCohorte' => '2026-B',
    'id'           => $nuevoId
]);

// $stmt->rowCount() indica cuántos registros cambiaron efectivamente
echo "Filas actualizadas: " . $stmt->rowCount();

4. Eliminar (DELETE) vs Borrado Lógico (Soft Delete):

// Borrado físico (elimina la fila de la tabla permanentemente)
$stmt = $pdo->prepare("DELETE FROM estudiantes WHERE id = :id");
$stmt->execute(['id' => $nuevoId]);

// Buena práctica moderna: Borrado lógico (Soft Delete) marcando una marca de tiempo
// UPDATE estudiantes SET deleted_at = NOW() WHERE id = :id

Transacciones Atómicas (ACID) en MySQL con PDO

Una transacción garantiza que un conjunto de operaciones SQL se ejecuten en su totalidad o no se aplique ninguna (principio de "todo o nada"). Es imprescindible en operaciones financieras, matriculaciones o transferencias:

try {
    // 1. Iniciar la transacción
    $pdo->beginTransaction();

    // 2. Descontar cupo del curso
    $stmt1 = $pdo->prepare("UPDATE cursos SET cupos = cupos - 1 WHERE id = :id AND cupos > 0");
    $stmt1->execute(['id' => 10]);

    if ($stmt1->rowCount() === 0) {
        throw new Exception("No hay cupos disponibles.");
    }

    // 3. Registrar la matrícula del usuario
    $stmt2 = $pdo->prepare("INSERT INTO matriculas (usuario_id, curso_id, creado_en) VALUES (:u, :c, NOW())");
    $stmt2->execute(['u' => 42, 'c' => 10]);

    // 4. Si todo salió bien, confirmar los cambios de forma permanente
    $pdo->commit();
    echo "¡Matrícula completada con éxito!";

} catch (Exception $e) {
    // 5. Si algo falló, revertir todas las operaciones previas
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }
    echo "Transacción cancelada: " . $e->getMessage();
}
🦉
¿Tienes dudas con este tema?
Sócrates AI puede darte analogías y explicarte este código paso a paso.

🚀 ¿Quieres dominar Manual Completo de PHP y crear proyectos reales?

Aprende arquitectura limpia, desarrollo web moderno, buenas prácticas y despliegue en producción con nuestro Bootcamp Fullstack Developer con mentorías en vivo.

🏛️ Autoría y Propiedad Intelectual: Obra educativa original de David Amador para Kilopolis Academia (Solucionáticos), estructurada sobre las especificaciones y estándares abiertos del W3C, el estándar vivo de WHATWG y la documentación oficial de código abierto. © Todos los derechos reservados.