Proyecto: libro de visitas con PHP y MySQL

El CRUD completo (crear, leer, actualizar, borrar) con PDO y consultas preparadas. Con un simulador que muestra el SQL que se ejecuta.

CRUD son las cuatro cosas que se hacen con datos: Create, Read, Update, Delete. Casi toda aplicación web es, en el fondo, un CRUD sobre una base de datos. Aquí lo montamos con un libro de visitas.

Simulador

Envía un mensaje y borra alguno. La consola muestra la consulta SQL equivalente:

Paso 1: la tabla

CREATE TABLE visitas (
  id      INT PRIMARY KEY AUTO_INCREMENT,
  nombre  VARCHAR(80)  NOT NULL,
  mensaje VARCHAR(500) NOT NULL,
  fecha   TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Paso 2: conectar con PDO

<?php
$pdo = new PDO(
    "mysql:host=localhost;dbname=miweb;charset=utf8mb4",
    "usuario", "contraseña",
    [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);

Paso 3: Create y Read

// CREATE — consulta preparada: los datos van APARTE del SQL
if ($_SERVER["REQUEST_METHOD"] === "POST") {
    $stmt = $pdo->prepare(
        "INSERT INTO visitas (nombre, mensaje) VALUES (?, ?)"
    );
    $stmt->execute([$_POST["nombre"], $_POST["mensaje"]]);
    header("Location: libro.php");   // recargar para no reenviar al refrescar
    exit;
}

// READ
$visitas = $pdo
    ->query("SELECT id, nombre, mensaje, fecha FROM visitas ORDER BY fecha DESC")
    ->fetchAll(PDO::FETCH_ASSOC);

Paso 4: mostrar (con escape) y borrar

<?php foreach ($visitas as $v): ?>
  <article>
    <strong><?= htmlspecialchars($v["nombre"]) ?></strong>
    <p><?= htmlspecialchars($v["mensaje"]) ?></p>
    <a href="libro.php?borrar=<?= $v["id"] ?>">Borrar</a>
  </article>
<?php endforeach; ?>

<?php
// DELETE
if (isset($_GET["borrar"])) {
    $stmt = $pdo->prepare("DELETE FROM visitas WHERE id = ?");
    $stmt->execute([$_GET["borrar"]]);
    header("Location: libro.php"); exit;
}

htmlspecialchars() al mostrar evita el XSS: si alguien firma con <script>, se ve como texto.

Cómo seguir

  • UPDATE: un formulario de edición que hace UPDATE visitas SET ... WHERE id = ?.
  • Paginación con LIMIT y OFFSET.
  • Un token CSRF en el formulario para evitar envíos falsos.
  • Login de administrador para moderar los mensajes.