Ejercicio 8 PHP

Curso PHP – Ejercicio 8 (CRUD con subida de imágenes)

🛠️ Ejercicio 8: CRUD con subida de imágenes

📌 Planteamiento:

Extiende el CRUD anterior para que:

  • ✅ Cada producto pueda tener una imagen asociada.
  • ✅ Al agregar un producto, se permita subir un archivo .jpg o .png.
  • ✅ Se valide el tipo y tamaño del archivo (máx. 2 MB).
  • ✅ Se muestre la imagen en la tabla de productos.
👉 Usa PDO y guarda solo la ruta de la imagen en la base de datos (no el binario).

✅ Modelo de solución:

<?php
// 🔌 Conexión a MySQL
$dsn = "mysql:host=localhost;dbname=curso_php;charset=utf8";
$usuario = "root";
$contrasena = "";

try {
    $pdo = new PDO($dsn, $usuario, $contrasena);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    die("❌ Error de conexión: " . $e->getMessage());
}

// 📌 Crear tabla si no existe
$pdo->exec("CREATE TABLE IF NOT EXISTS productos (
  id INT AUTO_INCREMENT PRIMARY KEY,
  nombre VARCHAR(100) NOT NULL,
  precio DECIMAL(10,2) NOT NULL,
  imagen VARCHAR(255) NULL
)");

// 📥 Insertar producto con imagen
if (isset($_POST['agregar'])) {
    $nombre_img = null;

    if (isset($_FILES['imagen']) && $_FILES['imagen']['error'] === UPLOAD_ERR_OK) {
        $archivo_tmp = $_FILES['imagen']['tmp_name'];
        $nombre_original = basename($_FILES['imagen']['name']);
        $extension = strtolower(pathinfo($nombre_original, PATHINFO_EXTENSION));

        // Validar extensión y tamaño
        if (in_array($extension, ['jpg', 'jpeg', 'png']) && $_FILES['imagen']['size'] <= 2*1024*1024) {
            $carpeta = 'uploads/';
            if (!is_dir($carpeta)) {
                mkdir($carpeta, 0777, true);
            }
            $nombre_img = $carpeta . uniqid() . '.' . $extension;
            move_uploaded_file($archivo_tmp, $nombre_img);
        }
    }

    $stmt = $pdo->prepare("INSERT INTO productos (nombre, precio, imagen) VALUES (?, ?, ?)");
    $stmt->execute([$_POST['nombre'], $_POST['precio'], $nombre_img]);
}

// 🗑️ Eliminar producto
if (isset($_GET['eliminar'])) {
    $stmt = $pdo->prepare("SELECT imagen FROM productos WHERE id = ?");
    $stmt->execute([$_GET['eliminar']]);
    $img = $stmt->fetchColumn();

    if ($img && file_exists($img)) {
        unlink($img);
    }

    $stmt = $pdo->prepare("DELETE FROM productos WHERE id = ?");
    $stmt->execute([$_GET['eliminar']]);
}

// 📄 Obtener productos
$stmt = $pdo->query("SELECT * FROM productos");
$productos = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>

<h3>Agregar producto</h3>
<form method="post" enctype="multipart/form-data">
  <input type="text" name="nombre" placeholder="Nombre" required>
  <input type="number" step="0.01" name="precio" placeholder="Precio" required>
  <input type="file" name="imagen" accept="image/*">
  <button type="submit" name="agregar">Agregar</button>
</form>

<h3>Listado de productos</h3>
<table border="1" cellpadding="5">
  <tr><th>ID</th><th>Nombre</th><th>Precio</th><th>Imagen</th><th>Acciones</th></tr>
  <?php foreach ($productos as $p): ?>
    <tr>
      <td><?php echo $p['id']; ?></td>
      <td><?php echo $p['nombre']; ?></td>
      <td><?php echo $p['precio']; ?></td>
      <td>
        <?php if ($p['imagen']): ?>
          <img src="<?php echo $p['imagen']; ?>" alt="imagen">
        <?php else: ?>
          Sin imagen
        <?php endif; ?>
      </td>
      <td>
        <a href="?eliminar=<?php echo $p['id']; ?>" onclick="return confirm('¿Eliminar producto?');">Eliminar</a>
      </td>
    </tr>
  <?php endforeach; ?>
</table>
    

🎯 Claves de este ejercicio:

  • 📍 Subida de archivos usando $_FILES y move_uploaded_file().
  • 📍 Validación de extensión y tamaño para mayor seguridad.
  • 📍 Creación automática de carpeta uploads/ si no existe.
  • 📍 Eliminación de la imagen del servidor al borrar el producto.

No hay comentarios:

Publicar un comentario

Políticas de Privacidad