Introducción al proyecto final (30 minutos)
Explicación:
El proyecto final consiste en desarrollar una aplicación web para una biblioteca que gestione libros, autores, y préstamos. La aplicación permitirá:
- Listar libros: Mostrar todos los libros con sus autores (solicitud GET).
- Listar autores: Mostrar todos los autores (solicitud GET).
- Listar préstamos: Mostrar los préstamos activos (solicitud GET).
- Crear libros: Añadir un libro con su autor (formulario, solicitud POST).
- Crear autores: Añadir un autor (formulario, solicitud POST).
- Registrar préstamos: Registrar un préstamo de un libro (formulario, solicitud POST).
Requisitos:
- Frontend:
- HTML/CSS para formularios y listas (interfaces claras y responsivas).
- Opcional: JavaScript para validación en el cliente (por ejemplo, verificar campos vacíos).
- Backend:
- PHP con clases POO para manejar la lógica (por ejemplo, clases para Libro, Autor, Prestamo).
- Estructura MVC simple (Modelo, Vista, Controlador).
- Base de datos:
- MySQL con tablas relacionadas:
- autores (autor principal de un libro).
- libros (relacionados con autores).
- prestamos (relacionados con libros).
- MySQL con tablas relacionadas:
- Seguridad:
- Validar entradas (campos obligatorios, formatos correctos).
- Usar consultas preparadas para prevenir inyección SQL.
- Entorno: Desplegada en XAMPP o Laragon.
Por qué es importante:
- Integra todos los módulos del curso en una aplicación completa.
- Simula un sistema real, preparando para proyectos profesionales.
- Refuerza MVC, POO, y seguridad, fundamentales para frameworks como Laravel.
Punto clave: El proyecto final demuestra dominio de desarrollo web full-stack con PHP.
Actividad inicial (10 minutos):
Dibuja en papel un esquema de las tres tablas de la base de datos (autores, libros, prestamos) y sus relaciones.
- Ejemplo:
autores: id, nombre libros: id, titulo, id_autor (FK → autores.id) prestamos: id, id_libro (FK → libros.id), fecha_prestamo
Planificación y diseño del proyecto (1 hora)
Explicación:
Antes de codificar, planificaremos la estructura del proyecto, diseñaremos la base de datos, y definiremos las funcionalidades.
Estructura del proyecto:
/biblioteca_app
/models
AutorModel.php
LibroModel.php
PrestamoModel.php
/views
autores_listar.php
libros_listar.php
prestamos_listar.php
autor_crear.php
libro_crear.php
prestamo_crear.php
/controllers
AutorController.php
LibroController.php
PrestamoController.php
/assets
css/styles.css
js/validacion.js (opcional)
index.php
config.php
README.md
Base de datos:
- Nombre: biblioteca_db.
- Tablas:
CREATE DATABASE biblioteca_db; USE biblioteca_db; CREATE TABLE autores ( id INT AUTO_INCREMENT PRIMARY KEY, nombre VARCHAR(100) NOT NULL ); CREATE TABLE libros ( id INT AUTO_INCREMENT PRIMARY KEY, titulo VARCHAR(200) NOT NULL, id_autor INT NOT NULL, FOREIGN KEY (id_autor) REFERENCES autores(id) ); CREATE TABLE prestamos ( id INT AUTO_INCREMENT PRIMARY KEY, id_libro INT NOT NULL, fecha_prestamo DATE NOT NULL, FOREIGN KEY (id_libro) REFERENCES libros(id) ); -- Datos de prueba INSERT INTO autores (nombre) VALUES ('Gabriel García Márquez'), ('Jane Austen'); INSERT INTO libros (titulo, id_autor) VALUES ('Cien años de soledad', 1), ('Orgullo y prejuicio', 2); INSERT INTO prestamos (id_libro, fecha_prestamo) VALUES (1, '2025-04-20'), (2, '2025-04-21');
Funcionalidades:
- Listar autores: Mostrar tabla con nombres de autores (GET /index.php?controlador=autor&accion=listar).
- Listar libros: Mostrar tabla con títulos y nombres de autores (GET /index.php?controlador=libro&accion=listar).
- Listar préstamos: Mostrar tabla con libros prestados y fechas (GET /index.php?controlador=prestamo&accion=listar).
- Crear autor: Formulario para añadir un autor (nombre) (POST /index.php?controlador=autor&accion=guardar).
- Crear libro: Formulario para añadir un libro (título, autor) (POST /index.php?controlador=libro&accion=guardar).
- Crear préstamo: Formulario para registrar un préstamo (libro, fecha) (POST /index.php?controlador=prestamo&accion=guardar).
Planificación del tiempo:
- Día 1: Configurar entorno, base de datos, y estructura MVC (2-3 horas).
- Día 2: Implementar modelos y controladores (4-5 horas).
- Día 3: Crear vistas y estilos CSS (3-4 horas).
- Día 4: Añadir validación de entradas y seguridad (2-3 horas).
- Día 5: Implementar JavaScript opcional y probar (2-3 horas).
- Día 6: Documentar (README) y depurar (2-3 horas).
- Día 7: Finalizar pruebas y preparar entrega (1-2 horas).
Punto clave: Una planificación clara asegura un desarrollo organizado y eficiente.
Actividad (15 minutos):
Escribe en papel la estructura de carpetas y las funcionalidades con sus URLs.
- Ejemplo:
Estructura: /biblioteca_app /models /views /controllers /assets index.php config.php README.md Funcionalidades: - Listar autores: GET /index.php?controlador=autor&accion=listar - Crear libro: POST /index.php?controlador=libro&accion=guardar
Desarrollo del proyecto: Implementación (15-20 horas, distribuidas)
Explicación:
Implementaremos la aplicación biblioteca con MVC simple, usando PHP con POO, MySQL, HTML/CSS, y seguridad. Opcionalmente, añadiremos JavaScript para validación en el cliente.
Código del proyecto:
-
Configuración (config.php):
- Conexión a MySQL.
<?php $host = 'localhost'; $usuario = 'root'; $contrasena = ''; // Vacío en XAMPP/Laragon por defecto $base_datos = 'biblioteca_db'; $conexion = new mysqli($host, $usuario, $contrasena, $base_datos); if ($conexion->connect_error) { die("Error de conexión: " . $conexion->connect_error); } ?>
-
Modelos:
- Autor (models/AutorModel.php):
<?php class AutorModel { private $conexion; public function __construct($conexion) { $this->conexion = $conexion; } public function listar() { $query = "SELECT id, nombre FROM autores ORDER BY nombre"; $resultado = $this->conexion->query($query); return $resultado->fetch_all(MYSQLI_ASSOC); } public function crear($nombre) { $stmt = $this->conexion->prepare("INSERT INTO autores (nombre) VALUES (?)"); $stmt->bind_param("s", $nombre); return $stmt->execute(); } } ?>
- Libro (models/LibroModel.php):
<?php class LibroModel { private $conexion; public function __construct($conexion) { $this->conexion = $conexion; } public function listar() { $query = "SELECT l.id, l.titulo, a.nombre AS autor FROM libros l JOIN autores a ON l.id_autor = a.id ORDER BY l.titulo"; $resultado = $this->conexion->query($query); return $resultado->fetch_all(MYSQLI_ASSOC); } public function crear($titulo, $id_autor) { $stmt = $this->conexion->prepare("INSERT INTO libros (titulo, id_autor) VALUES (?, ?)"); $stmt->bind_param("si", $titulo, $id_autor); return $stmt->execute(); } public function getAutores() { $query = "SELECT id, nombre FROM autores ORDER BY nombre"; $resultado = $this->conexion->query($query); return $resultado->fetch_all(MYSQLI_ASSOC); } } ?>
- Préstamo (models/PrestamoModel.php):
<?php class PrestamoModel { private $conexion; public function __construct($conexion) { $this->conexion = $conexion; } public function listar() { $query = "SELECT p.id, l.titulo, p.fecha_prestamo FROM prestamos p JOIN libros l ON p.id_libro = l.id ORDER BY p.fecha_prestamo DESC"; $resultado = $this->conexion->query($query); return $resultado->fetch_all(MYSQLI_ASSOC); } public function crear($id_libro, $fecha_prestamo) { $stmt = $this->conexion->prepare("INSERT INTO prestamos (id_libro, fecha_prestamo) VALUES (?, ?)"); $stmt->bind_param("is", $id_libro, $fecha_prestamo); return $stmt->execute(); } public function getLibros() { $query = "SELECT id, titulo FROM libros ORDER BY titulo"; $resultado = $this->conexion->query($query); return $resultado->fetch_all(MYSQLI_ASSOC); } } ?>
- Autor (models/AutorModel.php):
-
Controladores:
- Autor (controllers/AutorController.php):
<?php require_once 'models/AutorModel.php'; class AutorController { private $modelo; public function __construct($conexion) { $this->modelo = new AutorModel($conexion); } public function listar() { $autores = $this->modelo->listar(); require 'views/autores_listar.php'; } public function crear() { require 'views/autor_crear.php'; } public function guardar() { $nombre = trim($_POST['nombre'] ?? ''); if (empty($nombre) || strlen($nombre) > 100) { die("Error: Nombre obligatorio, máximo 100 caracteres."); } $nombre = htmlspecialchars($nombre); if ($this->modelo->crear($nombre)) { header("Location: index.php?controlador=autor&accion=listar"); exit; } else { die("Error al crear autor."); } } } ?>
- Libro (controllers/LibroController.php):
<?php require_once 'models/LibroModel.php'; class LibroController { private $modelo; public function __construct($conexion) { $this->modelo = new LibroModel($conexion); } public function listar() { $libros = $this->modelo->listar(); require 'views/libros_listar.php'; } public function crear() { $autores = $this->modelo->getAutores(); require 'views/libro_crear.php'; } public function guardar() { $titulo = trim($_POST['titulo'] ?? ''); $id_autor = intval($_POST['id_autor'] ?? 0); if (empty($titulo) || strlen($titulo) > 200) { die("Error: Título obligatorio, máximo 200 caracteres."); } if ($id_autor <= 0) { die("Error: Autor inválido."); } $titulo = htmlspecialchars($titulo); if ($this->modelo->crear($titulo, $id_autor)) { header("Location: index.php?controlador=libro&accion=listar"); exit; } else { die("Error al crear libro."); } } } ?>
- Préstamo (controllers/PrestamoController.php):
<?php require_once 'models/PrestamoModel.php'; class PrestamoController { private $modelo; public function __construct($conexion) { $this->modelo = new PrestamoModel($conexion); } public function listar() { $prestamos = $this->modelo->listar(); require 'views/prestamos_listar.php'; } public function crear() { $libros = $this->modelo->getLibros(); require 'views/prestamo_crear.php'; } public function guardar() { $id_libro = intval($_POST['id_libro'] ?? 0); $fecha_prestamo = $_POST['fecha_prestamo'] ?? ''; if ($id_libro <= 0) { die("Error: Libro inválido."); } if (empty($fecha_prestamo) || !preg_match("/^\d{4}-\d{2}-\d{2}$/", $fecha_prestamo)) { die("Error: Fecha de préstamo inválida (YYYY-MM-DD)."); } if ($this->modelo->crear($id_libro, $fecha_prestamo)) { header("Location: index.php?controlador=prestamo&accion=listar"); exit; } else { die("Error al registrar préstamo."); } } } ?>
- Autor (controllers/AutorController.php):
-
Vistas:
- Listar autores (views/autores_listar.php):
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <title>Biblioteca - Autores</title> <link rel="stylesheet" href="assets/css/styles.css"> </head> <body> <h1>Biblioteca</h1> <nav> <a href="index.php?controlador=autor&accion=listar">Autores</a> | <a href="index.php?controlador=libro&accion=listar">Libros</a> | <a href="index.php?controlador=prestamo&accion=listar">Préstamos</a> </nav> <h2>Lista de Autores</h2> <a href="index.php?controlador=autor&accion=crear">Añadir autor</a> <table> <tr><th>ID</th><th>Nombre</th></tr> <?php foreach ($autores as $autor): ?> <tr> <td><?php echo htmlspecialchars($autor['id']); ?></td> <td><?php echo htmlspecialchars($autor['nombre']); ?></td> </tr> <?php endforeach; ?> </table> </body> </html>
- Listar libros (views/libros_listar.php):
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <title>Biblioteca - Libros</title> <link rel="stylesheet" href="assets/css/styles.css"> </head> <body> <h1>Biblioteca</h1> <nav> <a href="index.php?controlador=autor&accion=listar">Autores</a> | <a href="index.php?controlador=libro&accion=listar">Libros</a> | <a href="index.php?controlador=prestamo&accion=listar">Préstamos</a> </nav> <h2>Lista de Libros</h2> <a href="index.php?controlador=libro&accion=crear">Añadir libro</a> <table> <tr><th>ID</th><th>Título</th><th>Autor</th></tr> <?php foreach ($libros as $libro): ?> <tr> <td><?php echo htmlspecialchars($libro['id']); ?></td> <td><?php echo htmlspecialchars($libro['titulo']); ?></td> <td><?php echo htmlspecialchars($libro['autor']); ?></td> </tr> <?php endforeach; ?> </table> </body> </html>
- Listar préstamos (views/prestamos_listar.php):
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <title>Biblioteca - Préstamos</title> <link rel="stylesheet" href="assets/css/styles.css"> </head> <body> <h1>Biblioteca</h1> <nav> <a href="index.php?controlador=autor&accion=listar">Autores</a> | <a href="index.php?controlador=libro&accion=listar">Libros</a> | <a href="index.php?controlador=prestamo&accion=listar">Préstamos</a> </nav> <h2>Lista de Préstamos</h2> <a href="index.php?controlador=prestamo&accion=crear">Registrar préstamo</a> <table> <tr><th>ID</th><th>Libro</th><th>Fecha de Préstamo</th></tr> <?php foreach ($prestamos as $prestamo): ?> <tr> <td><?php echo htmlspecialchars($prestamo['id']); ?></td> <td><?php echo htmlspecialchars($prestamo['titulo']); ?></td> <td><?php echo htmlspecialchars($prestamo['fecha_prestamo']); ?></td> </tr> <?php endforeach; ?> </table> </body> </html>
- Crear autor (views/autor_crear.php):
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <title>Biblioteca - Añadir Autor</title> <link rel="stylesheet" href="assets/css/styles.css"> <script src="assets/js/validacion.js"></script> </head> <body> <h1>Biblioteca</h1> <nav> <a href="index.php?controlador=autor&accion=listar">Autores</a> | <a href="index.php?controlador=libro&accion=listar">Libros</a> | <a href="index.php?controlador=prestamo&accion=listar">Préstamos</a> </nav> <h2>Añadir Autor</h2> <form action="index.php?controlador=autor&accion=guardar" method="POST" onsubmit="return validarAutor()"> <label>Nombre: <input type="text" name="nombre" id="nombre" required></label> <button type="submit">Guardar</button> </form> </body> </html>
- Crear libro (views/libro_crear.php):
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <title>Biblioteca - Añadir Libro</title> <link rel="stylesheet" href="assets/css/styles.css"> <script src="assets/js/validacion.js"></script> </head> <body> <h1>Biblioteca</h1> <nav> <a href="index.php?controlador=autor&accion=listar">Autores</a> | <a href="index.php?controlador=libro&accion=listar">Libros</a> | <a href="index.php?controlador=prestamo&accion=listar">Préstamos</a> </nav> <h2>Añadir Libro</h2> <form action="index.php?controlador=libro&accion=guardar" method="POST" onsubmit="return validarLibro()"> <label>Título: <input type="text" name="titulo" id="titulo" required></label> <label>Autor: <select name="id_autor" id="id_autor" required> <option value="">Seleccione un autor</option> <?php foreach ($autores as $autor): ?> <option value="<?php echo $autor['id']; ?>"> <?php echo htmlspecialchars($autor['nombre']); ?> </option> <?php endforeach; ?> </select> </label> <button type="submit">Guardar</button> </form> </body> </html>
- Crear préstamo (views/prestamo_crear.php):
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <title>Biblioteca - Registrar Préstamo</title> <link rel="stylesheet" href="assets/css/styles.css"> <script src="assets/js/validacion.js"></script> </head> <body> <h1>Biblioteca</h1> <nav> <a href="index.php?controlador=autor&accion=listar">Autores</a> | <a href="index.php?controlador=libro&accion=listar">Libros</a> | <a href="index.php?controlador=prestamo&accion=listar">Préstamos</a> </nav> <h2>Registrar Préstamo</h2> <form action="index.php?controlador=prestamo&accion=guardar" method="POST" onsubmit="return validarPrestamo()"> <label>Libro: <select name="id_libro" id="id_libro" required> <option value="">Seleccione un libro</option> <?php foreach ($libros as $libro): ?> <option value="<?php echo $libro['id']; ?>"> <?php echo htmlspecialchars($libro['titulo']); ?> </option> <?php endforeach; ?> </select> </label> <label>Fecha de Préstamo: <input type="date" name="fecha_prestamo" id="fecha_prestamo" required></label> <button type="submit">Guardar</button> </form> </body> </html>
- Listar autores (views/autores_listar.php):
-
Estilos (assets/css/styles.css):
body { font-family: Arial, sans-serif; max-width: 900px; margin: 0 auto; padding: 20px; } h1 { color: #333; } nav { margin-bottom: 20px; } nav a { margin-right: 10px; color: #007BFF; text-decoration: none; } nav a:hover { text-decoration: underline; } table { width: 100%; border-collapse: collapse; margin: 20px 0; } th, td { border: 1px solid #ccc; padding: 10px; text-align: left; } th { background-color: #f2f2f2; } form { margin: 20px 0; } label { display: block; margin: 10px 0; } input, select, textarea { width: 100%; padding: 8px; margin: 5px 0; } button { padding: 10px 20px; background-color: #007BFF; color: white; border: none; cursor: pointer; } button:hover { background-color: #0056b3; }
-
JavaScript (opcional) (assets/js/validacion.js):
- Validación en el cliente para formularios.
function validarAutor() { const nombre = document.getElementById('nombre').value.trim(); if (nombre === '') { alert('El nombre es obligatorio.'); return false; } if (nombre.length > 100) { alert('El nombre no puede exceder 100 caracteres.'); return false; } return true; } function validarLibro() { const titulo = document.getElementById('titulo').value.trim(); const idAutor = document.getElementById('id_autor').value; if (titulo === '') { alert('El título es obligatorio.'); return false; } if (titulo.length > 200) { alert('El título no puede exceder 200 caracteres.'); return false; } if (idAutor === '') { alert('Seleccione un autor.'); return false; } return true; } function validarPrestamo() { const idLibro = document.getElementById('id_libro').value; const fecha = document.getElementById('fecha_prestamo').value; if (idLibro === '') { alert('Seleccione un libro.'); return false; } if (fecha === '') { alert('La fecha de préstamo es obligatoria.'); return false; } return true; }
-
Punto de entrada (index.php):
- Enruta solicitudes a los controladores.
<?php require_once 'config.php'; require_once 'controllers/AutorController.php'; require_once 'controllers/LibroController.php'; require_once 'controllers/PrestamoController.php'; $controladorNombre = $_GET['controlador'] ?? 'autor'; $accion = $_GET['accion'] ?? 'listar'; switch ($controladorNombre) { case 'autor': $controlador = new AutorController($conexion); break; case 'libro': $controlador = new LibroController($conexion); break; case 'prestamo': $controlador = new PrestamoController($conexion); break; default: $controlador = new AutorController($conexion); } switch ($accion) { case 'listar': $controlador->listar(); break; case 'crear': $controlador->crear(); break; case 'guardar': $controlador->guardar(); break; default: $controlador->listar(); } ?>
-
README (README.md):
- Instrucciones para ejecutar la aplicación.
# Biblioteca Web Aplicación web para gestionar libros, autores y préstamos en una biblioteca, desarrollada con PHP, MySQL, HTML, CSS, y JavaScript (opcional). ## Requisitos - XAMPP o Laragon instalado (Apache, MySQL, PHP). - Navegador web (Chrome, Firefox, etc.). - Editor de texto (VS Code recomendado). ## Instalación 1. Copiar la carpeta `biblioteca_app` a: - XAMPP: `C:\xampp\htdocs\biblioteca_app` - Laragon: `C:\laragon\www\biblioteca_app` 2. Iniciar Apache y MySQL en XAMPP o Laragon. 3. Crear la base de datos en phpMyAdmin (`http://localhost/phpmyadmin`): ```sql CREATE DATABASE biblioteca_db; USE biblioteca_db; CREATE TABLE autores ( id INT AUTO_INCREMENT PRIMARY KEY, nombre VARCHAR(100) NOT NULL ); CREATE TABLE libros ( id INT AUTO_INCREMENT PRIMARY KEY, titulo VARCHAR(200) NOT NULL, id_autor INT NOT NULL, FOREIGN KEY (id_autor) REFERENCES autores(id) ); CREATE TABLE prestamos ( id INT AUTO_INCREMENT PRIMARY KEY, id_libro INT NOT NULL, fecha_prestamo DATE NOT NULL, FOREIGN KEY (id_libro) REFERENCES libros(id) ); INSERT INTO autores (nombre) VALUES ('Gabriel García Márquez'), ('Jane Austen'); INSERT INTO libros (titulo, id_autor) VALUES ('Cien años de soledad', 1), ('Orgullo y prejuicio', 2); INSERT INTO prestamos (id_libro, fecha_prestamo) VALUES (1, '2025-04-20'), (2, '2025-04-21');
- Abrir en el navegador:
- XAMPP: http://localhost/biblioteca_app
- Laragon: http://biblioteca_app.test
Funcionalidades
- Listar autores, libros y préstamos.
- Añadir nuevos autores, libros y préstamos mediante formularios.
- Validación de entradas y prevención de inyección SQL.
Estructura
- /models: Clases PHP para lógica de datos (AutorModel.php, LibroModel.php, PrestamoModel.php).
- /views: Archivos HTML/PHP para la interfaz.
- /controllers: Clases PHP para manejar solicitudes.
- /assets: CSS y JavaScript (validación opcional).
- index.php: Punto de entrada.
- config.php: Conexión a MySQL.
Seguridad
- Validación de entradas: Campos obligatorios, longitud máxima, formatos.
- Consultas preparadas con mysqli para prevenir inyección SQL.
- Escaping con htmlspecialchars() para evitar XSS.
Pruebas
- Listar: Verifica que se muestren autores, libros y préstamos.
- Crear: Añade un autor, un libro, y un préstamo. Confirma redirección.
- Seguridad: Prueba entradas inválidas (vacías, largas) y posibles inyecciones SQL.
Notas
- Usa DevTools (F12, pestaña "Red") para verificar solicitudes HTTP.
- Revisa logs en C:\xampp\apache\logs o C:\laragon\logs si hay errores.
Cómo probarlo:
- Configuración:
- Asegúrate de que XAMPP o Laragon esté corriendo (Apache y MySQL).
- Crea la base de datos biblioteca_db y las tablas en phpMyAdmin.
- Inserta los datos de prueba (SQL proporcionado).
- Guarda los archivos en C:\xampp\htdocs\biblioteca_app (XAMPP) o C:\laragon\www\biblioteca_app (Laragon).
- Pruebas:
- Abre http://localhost/biblioteca_app (XAMPP) o http://biblioteca_app.test (Laragon).
- Listar:
- Autores: Verifica que se muestren “Gabriel García Márquez” y “Jane Austen”.
- Libros: Verifica “Cien años de soledad” y “Orgullo y prejuicio” con sus autores.
- Préstamos: Verifica los préstamos con fechas.
- Usa DevTools: Solicitudes GET, código 200 OK.
- Crear:
- Añade un autor (por ejemplo, “Mario Vargas Llosa”).
- Añade un libro (por ejemplo, Título: “La ciudad y los perros”, Autor: “Mario Vargas Llosa”).
- Registra un préstamo (por ejemplo, Libro: “La ciudad y los perros”, Fecha: “2025-04-22”).
- Verifica redirección a las listas tras guardar.
- Usa DevTools: Solicitudes POST, código 200 OK o 302 (redirección).
- Seguridad:
- Prueba entradas inválidas: Nombre vacío, título largo, fecha inválida → Mensajes de error.
- Intenta inyección SQL (por ejemplo, Nombre: '; DROP TABLE autores; --) → Neutralizada por consultas preparadas.
- JavaScript (opcional):
- Verifica que las alertas de validación aparezcan en el cliente si los campos están vacíos o son inválidos.
Flujo MVC:
- Listar: GET → index.php?controlador=X&accion=listar → XController::listar() → XModel::listar() → X_listar.php.
- Crear:
- GET → index.php?controlador=X&accion=crear → XController::crear() → X_crear.php.
- POST → index.php?controlador=X&accion=guardar → XController::guardar() → XModel::crear() → Redirige a listar.
Por qué es importante:
- Integra frontend (Módulo 2, 3), backend (Módulo 4), base de datos (Módulo 5), y conceptos avanzados (Módulo 6).
- Prepara para frameworks como Laravel, que usan MVC, POO, y ORM.
Punto clave: La aplicación biblioteca es una solución full-stack que demuestra habilidades completas de desarrollo web.
Documentación y entrega (2-3 horas)
Explicación:
El entregable es una aplicación funcional con un README claro y una carpeta bien organizada.
Entregable:
- Carpeta del proyecto: biblioteca_app con todos los archivos (models, views, controllers, assets, index.php, config.php, README.md).
- Base de datos: biblioteca_db con tablas y datos de prueba.
- Documento README: Explica cómo instalar y ejecutar la aplicación.
- Opcional: Capturas de pantalla de la aplicación (listas, formularios, phpMyAdmin).
Instrucciones para la entrega:
- Implementar:
- Copia el código proporcionado en las carpetas correspondientes.
- Configura la base de datos en phpMyAdmin.
- Prueba todas las funcionalidades en XAMPP o Laragon.
- Documentar:
- Usa el README.md proporcionado o crea uno propio.
- Incluye:
- Descripción del proyecto.
- Instrucciones de instalación.
- Funcionalidades implementadas.
- Notas sobre seguridad y pruebas.
- Probar exhaustivamente:
- Verifica cada funcionalidad (listar y crear para autores, libros, préstamos).
- Prueba casos límite: Entradas vacías, formatos inválidos, inyecciones SQL.
- Usa DevTools para confirmar solicitudes HTTP (GET, POST) y códigos de estado (200 OK, 302).
- Empaquetar:
- Comprime la carpeta biblioteca_app (ZIP o RAR).
- Incluye capturas de pantalla (opcional).
- Entrega el archivo comprimido y cualquier documentación adicional.
Ejemplo de entrega:
- Carpeta: biblioteca_app.zip.
- README.md: Como se mostró arriba.
- Capturas (opcional): Imágenes de la lista de libros, formulario de préstamo, y phpMyAdmin con las tablas.
Tiempo estimado:
- Desarrollo: 15-20 horas (distribuidas en la semana).
- Pruebas: 2-3 horas.
- Documentación: 2-3 horas.
Consejo:
- Divide el trabajo por días (ver planificación en la sección 2).
- Prueba cada componente (modelo, controlador, vista) antes de integrarlos.
- Usa los logs de XAMPP/Laragon para depurar errores (C:\xampp\apache\logs o C:\laragon\logs).
Punto clave: Un entregable completo y bien documentado refleja profesionalismo y dominio del curso.