Base de Datos en PHP con PDO

CRUD interactivo (Crear, Leer, Eliminar) con consultas preparadas

🎯 Demo en Vivo (tabla simulada para no requerir tu propia BD)

Añadir producto

IDNombrePrecio
1 Ratón inalámbrico 19.99 €
2 Monitor 24" 129.00 €

📖 El mismo CRUD con PDO real (MySQL)

Conexión

$pdo = new PDO(
    'mysql:host=localhost;dbname=mi_tienda;charset=utf8mb4',
    'usuario',
    'contraseña',
    [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);

📝 INSERT con consulta preparada

$stmt = $pdo->prepare(
    "INSERT INTO productos (nombre, precio) VALUES (:nombre, :precio)"
);
$stmt->execute([
    'nombre' => $_POST['nombre'],
    'precio' => $_POST['precio']
]);
💡 Concepto: Consultas preparadas

Los marcadores :nombre y :precio se envían por separado del SQL. Así, aunque el usuario escriba algo como '; DROP TABLE productos; --, PDO lo trata como un simple texto, no como código SQL — esto evita la inyección SQL.

📝 SELECT (leer todos)

$stmt = $pdo->query("SELECT id, nombre, precio FROM productos");
$productos = $stmt->fetchAll(PDO::FETCH_ASSOC);

📝 DELETE con parámetro

$stmt = $pdo->prepare("DELETE FROM productos WHERE id = :id");
$stmt->execute(['id' => $_POST['id']]);

🎯 Conceptos Clave

PDO

  • Capa única para MySQL, SQLite, PostgreSQL…
  • Lanza excepciones con ERRMODE_EXCEPTION

Prepared statements

  • Separan el SQL de los datos del usuario
  • Previenen inyección SQL

fetchAll / execute

  • fetchAll(PDO::FETCH_ASSOC) para arrays asociativos
  • execute([...]) para pasar los parámetros

💪 Ejercicio Práctico

Completa el CRUD

  1. Añade una acción "editar" que actualice nombre y precio con un UPDATE ... WHERE id = :id.
  2. Envuelve la conexión en un try/catch capturando PDOException.
  3. Añade paginación con LIMIT :inicio, :cantidad.

Solución 1

$stmt = $pdo->prepare(
    "UPDATE productos SET nombre = :nombre, precio = :precio WHERE id = :id"
);
$stmt->execute(['nombre' => $nombre, 'precio' => $precio, 'id' => $id]);

Solución 2

try {
    $pdo = new PDO($dsn, $usuario, $clave, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
} catch (PDOException $e) {
    die(t('Error de conexión: ') . $e->getMessage());
}

Solución 3

$stmt = $pdo->prepare("SELECT * FROM productos LIMIT :inicio, :cantidad");
$stmt->bindValue(':inicio', $inicio, PDO::PARAM_INT);
$stmt->bindValue(':cantidad', $cantidad, PDO::PARAM_INT);
$stmt->execute();