DELETE en un CRUD con PHP y MySQL: eliminar empleados con confirmación y protección CSRF 🗑️
Llegamos a la última operación del CRUD clásico:
DELETE (eliminar registros)
Eliminar datos puede parecer sencillo, pero en realidad es una de las acciones más delicadas en cualquier sistema.
Un mal diseño aquí puede provocar:
- Eliminaciones accidentales.
- Ataques maliciosos.
- Pérdida de información importante.
Por eso, en este caso de estudio vamos a implementar un DELETE seguro y controlado, con:
- Confirmación en la interfaz.
- Protección contra ataques CSRF.
- Mensajes claros al usuario.
¿Qué hace la operación DELETE?
La operación DELETE se encarga de:
- Identificar un registro específico.
- Eliminarlo de la base de datos.
- Informar el resultado al usuario.
En nuestro caso, eliminaremos un empleado usando su:
codigo (clave primaria)
1) El botón de eliminar en la interfaz
En la tabla de empleados, cada fila tiene un botón:
<a class="btn btn-sm btn-outline-danger"
href="crud-caso-de-estudio.php?delete=<?= urlencode($emp['codigo']) ?>&csrf=<?= urlencode($csrf) ?>"
onclick="return confirm('¿Eliminar al empleado <?= e($emp['codigo']) ?>? Esta acción no se puede deshacer.');">
Eliminar
</a>
Este botón hace tres cosas importantes:
- Envía el
codigoa eliminar. - Incluye un token CSRF.
- Muestra una confirmación antes de ejecutar la acción.
2) Confirmación en la interfaz (UX básica pero esencial)
El atributo:
onclick="return confirm('¿Eliminar...');"
Muestra un cuadro de confirmación en el navegador.
Si el usuario:
- Hace clic en Aceptar → continúa.
- Hace clic en Cancelar → no se ejecuta la acción.
Esto evita eliminaciones accidentales.
3) ¿Qué es el token CSRF y por qué es importante?
CSRF significa:
Cross-Site Request Forgery
Es un tipo de ataque donde un sitio externo intenta ejecutar acciones en tu sistema sin permiso.
Ejemplo de ataque:
Un usuario autenticado entra a un sitio malicioso que contiene:
https://tusitio.com/crud.php?delete=EMP001
Si no hay protección, el empleado se elimina sin que el usuario lo note.
Cómo funciona la protección CSRF en tu CRUD
Primero, se genera el token:
if (empty($_SESSION['csrf'])) {
$_SESSION['csrf'] = bin2hex(random_bytes(16));
}
$csrf = $_SESSION['csrf'];
Luego se envía en el enlace de eliminación:
?delete=EMP001&csrf=TOKEN
Y finalmente se valida antes de ejecutar el DELETE.
4) Procesar la eliminación en PHP
Cuando llega el parámetro delete, tu código hace:
if (isset($_GET['delete'])) {
$codigo = trim($_GET['delete']);
Verificación del token CSRF
Antes de eliminar, se valida el token:
$token = $_GET['csrf'] ?? '';
if (!hash_equals($_SESSION['csrf'], $token)) {
flash("❌ Token inválido. Recarga la página e inténtalo de nuevo.", "danger");
header("Location: crud-caso-de-estudio.php");
exit;
}
Si el token no coincide:
- Se bloquea la acción.
- Se muestra mensaje de error.
- Se redirige al listado.
Esto evita ataques CSRF.
5) Ejecutar el DELETE con PDO
Una vez validado el token:
$stmt = $pdo->prepare("DELETE FROM empleados WHERE codigo = ?");
$stmt->execute([$codigo]);
Esto:
- Elimina el registro específico.
- Usa una consulta preparada.
- Evita inyección SQL.
Verificar si realmente se eliminó
Después del DELETE:
if ($stmt->rowCount() > 0) {
flash("🗑️ Empleado eliminado correctamente.", "warning");
} else {
flash("⚠️ No se encontró el empleado para eliminar.", "info");
}
Esto permite:
- Detectar si el empleado existía.
- Mostrar el mensaje correcto.
6) Redirección final
Después de eliminar:
header("Location: crud-caso-de-estudio.php");
exit;
Esto evita:
- Reenvíos accidentales.
- Duplicación de acciones.
- Problemas al recargar la página.
Flujo completo del DELETE
Así funciona todo el proceso:
- Usuario hace clic en “Eliminar”.
- Aparece confirmación.
- Usuario acepta.
- Se envía
?delete=CODIGO&csrf=TOKEN. - PHP valida el token.
- Se ejecuta el DELETE.
- Se guarda mensaje flash.
- Se redirige al listado.
Mensajes claros para el usuario
El CRUD usa mensajes flash como:
Eliminación exitosa
🗑️ Empleado eliminado correctamente.
Registro inexistente
⚠️ No se encontró el empleado para eliminar.
Token inválido
❌ Token inválido. Recarga la página e inténtalo de nuevo.
Esto mejora mucho la experiencia del usuario.
Errores comunes al implementar DELETE
Eliminar sin confirmación
Provoca errores humanos.
No usar CSRF
Permite ataques externos.
Eliminar sin WHERE
Error crítico:
DELETE FROM empleados;
Borra toda la tabla.
No usar consultas preparadas
Permite inyección SQL.
Mejora futura: soft delete
En lugar de eliminar el registro, puedes:
- Cambiar el campo
estadoa 0. - Mantener historial.
- Evitar pérdidas accidentales.
Ejemplo:
UPDATE empleados SET estado = 0 WHERE codigo = ?
Pero para este caso de estudio, el DELETE directo es suficiente.
Conclusión:
La operación DELETE debe implementarse con cuidado.
En este CRUD:
- Se confirma la acción en la interfaz.
- Se protege con token CSRF.
- Se usa consulta preparada.
- Se informa claramente al usuario.
Con esto, ya tenemos el CRUD completo:
- CREATE
- READ
- UPDATE
- DELETE
En el siguiente post veremos:
➡️ Seguridad mínima para CRUDs públicos: XSS, CSRF, validación y control básico