Tutorial 10: Conectando PHP con la Base de Datos MySQL
Tutorial 10: Conectando PHP con la Base de Datos MySQL
¡Hola y bienvenido de nuevo!
En esta lección vamos a crear una clase PHP que nos permita conectar con nuestra base de datos MySQL. Esta conexión es fundamental para poder guardar y recuperar la información de los archivos que subamos. ¡Vamos a ello!
📋 Contenido del Tutorial
¿Qué es PDO y por qué usarlo?
Creando la clase DB
El método connect
Manejando errores con try-catch
El constructor en Whisper
Probando la conexión
Código completo
Explicación detallada
Próximos pasos
🔌 1. ¿Qué es PDO y por qué usarlo?
¿Qué es PDO?
PDO (PHP Data Objects) es una extensión de PHP que proporciona una interfaz consistente para acceder a diferentes bases de datos.
Beneficios de PDO
| Beneficio | Explicación |
|---|---|
| Seguridad | Previene inyecciones SQL mediante prepared statements |
| Portabilidad | Funciona con MySQL, PostgreSQL, SQLite, etc. |
| Orientado a objetos | Usa clases y métodos, no funciones sueltas |
| Manejo de errores | Mejor gestión de excepciones |
| Prepared statements | Consultas más seguras y eficientes |
Comparación con otras opciones
| Opción | Ventajas | Desventajas |
|---|---|---|
| PDO | Seguro, portable, orientado a objetos | Curva de aprendizaje |
| MySQLi | Soporte nativo para MySQL | Solo funciona con MySQL |
| mysql_* | Simple | Obsoleto, inseguro |
📁 2. Creando la clase DB
Estructura del archivo
Creamos un nuevo archivo en backend/classes/DB.php:
whisper/ ├── backend/ │ ├── init.php │ └── classes/ │ ├── DB.php # ¡Nuevo archivo! │ └── Whisper.php ├── files/ ├── frontend/ └── index.php
Clase DB básica
<?php class DB { public function connect() { // Código de conexión } } ?>
🔗 3. El método connect
Sintaxis de conexión PDO
new PDO('mysql:host=localhost;dbname=MyWhisper', 'root', '');
Desglose de la conexión
| Parte | Descripción | Ejemplo |
|---|---|---|
mysql: | Tipo de base de datos | MySQL |
host=localhost | Servidor de la base de datos | localhost |
dbname=MyWhisper | Nombre de la base de datos | MyWhisper |
'root' | Usuario de la base de datos | root |
'' | Contraseña (vacía por defecto en XAMPP) | (sin contraseña) |
El método connect completo
public function connect() { try { $db = new PDO('mysql:host=localhost;dbname=MyWhisper', 'root', ''); return $db; } catch(PDOException $error) { echo 'Connection Failed: ' . $error; } }
🛡️ 4. Manejando errores con try-catch
¿Qué es try-catch?
try-catch es una estructura de control que nos permite manejar errores de forma elegante:
try { // Código que puede generar un error $db = new PDO(...); } catch(PDOException $error) { // Código que se ejecuta si hay un error echo 'Connection Failed: ' . $error; }
Flujo de try-catch
1. Se ejecuta el código dentro de try ↓ 2. Si ocurre un error → Se salta a catch ↓ 3. catch captura el error y lo maneja ↓ 4. El programa continúa (no se detiene)
Posibles errores de conexión
| Error | Causa | Solución |
|---|---|---|
Unknown database | La base de datos no existe | Crear la base de datos |
Access denied | Usuario o contraseña incorrectos | Verificar credenciales |
Can't connect | MySQL no está corriendo | Iniciar MySQL en XAMPP |
🏗️ 5. El constructor en Whisper
¿Qué es un constructor?
Un constructor es un método especial que se ejecuta automáticamente cuando se crea un objeto de la clase.
class MiClase { public function __construct() { echo "¡El objeto ha sido creado!"; } } $obj = new MiClase(); // Muestra: "¡El objeto ha sido creado!"
¿Por qué usar un constructor?
✅ Inicializar propiedades
✅ Conectar a la base de datos
✅ Configurar el objeto
✅ Cargar configuraciones
El constructor en Whisper
class Whisper { private $DB; // Propiedad privada para la conexión public function __construct() { $db = new DB(); $this->DB = $db->connect(); } }
Explicación paso a paso
// 1. Crear una instancia de la clase DB $db = new DB(); // 2. Llamar al método connect() $connection = $db->connect(); // 3. Almacenar la conexión en la propiedad privada $this->DB = $connection;
Propiedad privada
private $DB;
privatesignifica que solo se puede acceder desde dentro de la claseEs una buena práctica para proteger datos sensibles
$DBalmacena la conexión a la base de datos
🧪 6. Probando la conexión
Prueba 1: Conexión exitosa
Escenario: La base de datos MyWhisper existe
Resultado esperado:
Connected
Código de prueba:
class Whisper { public function __construct() { $db = new DB(); $this->DB = $db->connect(); echo "Connected"; // Solo para prueba } }
Prueba 2: Error de conexión
Escenario: La base de datos no existe
Resultado esperado:
Connection Failed: SQLSTATE[HY000] [1049] Unknown database 'MyWhisper'
Causa: Cambiamos el nombre de la base de datos a uno que no existe
Prueba 3: Error de credenciales
Escenario: Usuario o contraseña incorrectos
Resultado esperado:
Connection Failed: SQLSTATE[HY000] [1045] Access denied for user
💻 7. Código completo
Archivo: backend/classes/DB.php
<?php /** * Clase DB - Conexión a la base de datos * * Esta clase maneja la conexión a MySQL usando PDO */ class DB { /** * Conecta a la base de datos MySQL * * @return PDO|false Objeto PDO con la conexión o false en caso de error */ public function connect() { try { // Configuración de la conexión $host = 'localhost'; $dbname = 'MyWhisper'; $username = 'root'; $password = ''; // Crear la conexión PDO $db = new PDO("mysql:host=$host;dbname=$dbname", $username, $password); // Configurar el modo de errores $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Configurar el charset $db->exec("SET NAMES utf8mb4"); return $db; } catch(PDOException $error) { // Mostrar el error de conexión echo 'Connection Failed: ' . $error->getMessage(); return false; } } } ?>
Archivo: backend/init.php
<?php /** * Archivo de inicialización de la aplicación * Carga todas las clases necesarias */ // Cargar las clases require 'classes/DB.php'; require 'classes/Whisper.php'; // Crear la instancia de Whisper $whisperObj = new Whisper(); // La conexión a la base de datos se establece automáticamente // en el constructor de Whisper ?>
Archivo: backend/classes/Whisper.php
<?php /** * Clase Whisper * * Maneja la subida y procesamiento de archivos */ class Whisper { /** * @var string Mensajes de error */ public $error; /** * @var PDO Conexión a la base de datos */ private $DB; /** * Constructor - Se ejecuta al crear el objeto * Establece la conexión a la base de datos */ public function __construct() { // Crear una instancia de la clase DB $db = new DB(); // Conectar a la base de datos $this->DB = $db->connect(); // (Opcional) Verificar la conexión if ($this->DB) { // echo "Conexión exitosa a la base de datos"; } } /** * Sube un archivo al servidor * * @param array $file Arreglo $_FILES * @return string|false Ruta del archivo o false en caso de error */ public function upload($file) { // 1. Extraer información del archivo $fileTmp = $file['tmp_name']; $filename = basename($file['name']); $fileSize = $file['size']; $errors = $file['error']; $mime = $file['type']; // 2. Obtener la extensión del archivo $ext = pathinfo($filename, PATHINFO_EXTENSION); $ext = strtolower($ext); // 3. Obtener el directorio raíz del proyecto $parentDirectory = dirname(dirname(dirname(__FILE__))); // 4. Definir los tipos de archivo permitidos $allowedMedia = [ 'video/mp4', 'video/mpeg', 'audio/mpeg', 'audio/mpeg3', 'audio/wav' ]; // 5. Validar el tipo de archivo if (!in_array($mime, $allowedMedia)) { $this->error = "Formato de archivo inválido"; return false; } // 6. Validar el tamaño del archivo (máximo 20 MB) if ($fileSize > 20000000) { $this->error = "El archivo es demasiado grande (máximo 20 MB)"; return false; } // 7. Crear nombre único y subir el archivo $folder = 'files/'; $uniqueName = md5(time() . mt_rand()); $file = $folder . $uniqueName . '.' . $ext; // 8. Mover el archivo if (move_uploaded_file($fileTmp, $parentDirectory . '/' . $file)) { return $file; // Éxito } else { $this->error = "Error al mover el archivo"; return false; } } /** * Guarda la información del archivo en la base de datos * * @param string $fileUrl Ruta del archivo * @param string $type Tipo de archivo (audio/video) * @return int|false ID del registro insertado o false en caso de error */ public function saveFileInfo($fileUrl, $type) { try { // Preparar la consulta SQL $sql = "INSERT INTO files (fileUrl, type) VALUES (:fileUrl, :type)"; $stmt = $this->DB->prepare($sql); // Ejecutar la consulta con los parámetros $stmt->execute([ ':fileUrl' => $fileUrl, ':type' => $type ]); // Retornar el ID del registro insertado return $this->DB->lastInsertId(); } catch(PDOException $error) { $this->error = "Error al guardar en la base de datos: " . $error->getMessage(); return false; } } } ?>
Archivo: index.php (sección PHP actualizada)
<?php // Cargar la configuración inicial include 'backend/init.php'; // Variables para mensajes $error = null; $success = null; // Verificar si la solicitud es POST if ($_SERVER['REQUEST_METHOD'] === "POST") { // Verificar si el archivo está presente if (isset($_FILES['file'])) { // Verificar que no esté vacío if (!empty($_FILES['file']['name'])) { // Procesar el archivo con la clase Whisper $file = $whisperObj->upload($_FILES['file']); if ($file) { // Determinar el tipo de archivo $mime = $_FILES['file']['type']; $type = strpos($mime, 'video/') === 0 ? 'video' : 'audio'; // Guardar en la base de datos $id = $whisperObj->saveFileInfo($file, $type); if ($id) { $success = "¡Archivo subido correctamente! ID: " . $id; // Redirigir a la vista // header("Location: view.php?id=" . $id); // exit; } else { $error = $whisperObj->error; } } else { // Error: obtener el mensaje de error $error = $whisperObj->error; } } else { $error = "Por favor selecciona un archivo para convertir a texto"; } } else { $error = "Por favor selecciona un archivo para convertir a texto"; } } ?>
📖 8. Explicación detallada
Flujo de la conexión
1. index.php incluye backend/init.php ↓ 2. init.php requiere DB.php y Whisper.php ↓ 3. init.php crea $whisperObj = new Whisper() ↓ 4. El constructor de Whisper se ejecuta automáticamente ↓ 5. Constructor crea $db = new DB() ↓ 6. Constructor llama a $db->connect() ↓ 7. connect() intenta conectar con PDO ↓ 8. Si funciona → Retorna el objeto PDO ↓ 9. Si falla → Muestra error y retorna false ↓ 10. La conexión queda almacenada en $this->DB
Configuración adicional de PDO
// Modo de errores: lanzar excepciones $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Configurar charset $db->exec("SET NAMES utf8mb4");
| Configuración | Propósito |
|---|---|
ATTR_ERRMODE | Cómo manejar los errores de PDO |
ERRMODE_EXCEPTION | Lanzar excepciones para cada error |
SET NAMES utf8mb4 | Usar codificación UTF-8 completa |
Métodos PDO importantes
| Método | Propósito | Ejemplo |
|---|---|---|
prepare() | Prepara una consulta SQL | $stmt = $db->prepare("SELECT ...") |
execute() | Ejecuta una consulta preparada | $stmt->execute([':id' => 1]) |
fetch() | Obtiene una fila de resultados | $row = $stmt->fetch() |
fetchAll() | Obtiene todas las filas | $rows = $stmt->fetchAll() |
lastInsertId() | Obtiene el último ID insertado | $id = $db->lastInsertId() |
🧪 9. Probando la conexión
Paso 1: Verificar MySQL en XAMPP
Abre el Panel de Control de XAMPP
Asegúrate de que MySQL esté en verde (corriendo)
Si no está corriendo, haz clic en "Start"
Paso 2: Verificar la base de datos
Ve a
http://localhost/phpmyadmin/Busca
MyWhisperen la lista de bases de datosVerifica que la tabla
filesexista
Paso 3: Probar la conexión
Abre
http://localhost/whisper/Si todo funciona, no verás mensajes de error
Si hay problemas, verás mensajes de error de conexión
Paso 4: Probar la subida con base de datos
Selecciona un archivo
El archivo se subirá a
files/La información se guardará en la base de datos
Verás un mensaje de éxito con el ID
📊 10. Mensajes de error comunes
Error: "Unknown database 'MyWhisper'"
Causa: La base de datos no existe
Solución: Crear la base de datos en phpMyAdmin
Error: "Access denied for user 'root'@'localhost'"
Causa: Contraseña incorrecta o usuario incorrecto
Solución: Verificar credenciales en la conexión
Error: "Connection Failed: SQLSTATE[HY000] [2002]"
Causa: MySQL no está corriendo
Solución: Iniciar MySQL en XAMPP
Error: "Class 'PDO' not found"
Causa: La extensión PDO no está habilitada
Solución: Habilitar PDO en php.ini
🎯 11. Próximos pasos
Lo que hemos logrado
✅ Clase DB para conectar a MySQL
✅ Uso de PDO para conexiones seguras
✅ Manejo de errores con try-catch
✅ Constructor en Whisper para conexión automática
✅ Guardado de información en la base de datos
Lo que viene en la próxima lección
En la siguiente lección vamos a:
Mostrar la lista de archivos subidos
Crear la página de vista para ver transcripciones
Recuperar datos de la base de datos
Mostrar el reproductor de audio/video
Avance del código de la próxima lección
// En Whisper.php public function getFiles() { $sql = "SELECT * FROM files ORDER BY ID DESC"; $stmt = $this->DB->prepare($sql); $stmt->execute(); return $stmt->fetchAll(); } // En view.php $files = $whisperObj->getFiles(); foreach ($files as $file) { echo '<li>' . $file['fileUrl'] . '</li>'; }
❓ Preguntas frecuentes
¿Qué es PDO y por qué usarlo en lugar de MySQLi?
PDO es una capa de abstracción que funciona con múltiples bases de datos
Es más seguro y moderno que las funciones mysql_*
¿Qué significa private $DB;?
privatesignifica que la propiedad solo es accesible dentro de la clase$DBalmacena el objeto de conexión a la base de datos
¿Por qué usamos try-catch?
Para manejar errores de forma elegante
Evita que la aplicación se detenga inesperadamente
¿Qué es __construct()?
Es un método especial que se ejecuta al crear un objeto
Se usa para inicializar propiedades o establecer conexiones
¿Cómo sé si la conexión fue exitosa?
Si
$db->connect()retorna un objeto PDO, la conexión fue exitosaSi retorna
false, hubo un error
¿Puedo cambiar las credenciales de la base de datos?
Sí, modifica las variables en
DB.php$usernamey$passwordsegún tu configuración
🎓 Ejercicio práctico
Ejercicio 1: Agregar más configuraciones de PDO
Agrega estas configuraciones a la conexión:
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
Ejercicio 2: Crear un método para obtener archivos
Agrega este método a la clase Whisper:
public function getFiles() { try { $sql = "SELECT * FROM files ORDER BY ID DESC LIMIT 10"; $stmt = $this->DB->prepare($sql); $stmt->execute(); return $stmt->fetchAll(); } catch(PDOException $error) { $this->error = $error->getMessage(); return false; } }
Ejercicio 3: Usar variables de entorno
Configura las credenciales en variables de entorno:
$host = getenv('DB_HOST') ?: 'localhost'; $dbname = getenv('DB_NAME') ?: 'MyWhisper'; $username = getenv('DB_USER') ?: 'root'; $password = getenv('DB_PASS') ?: '';
¡Excelente trabajo! Ahora tenemos una conexión funcional a la base de datos MySQL. En la próxima lección, usaremos esta conexión para mostrar los archivos subidos y sus transcripciones.
Comentarios
Publicar un comentario