🛠️ 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.
✅ 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
$_FILESymove_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