Introducción al proyecto y planificación (30 minutos)
Explicación:
El objetivo es crear una aplicación PHP simple para gestionar un registro de estudiantes, con las siguientes funcionalidades:
- Formulario: Registrar estudiantes (campos: nombre, email, curso).
- Base de datos: Almacenar y listar estudiantes en MySQL.
- Clase: Encapsular la lógica de manejo de datos (por ejemplo, guardar, listar).
- Interfaz: Mostrar los datos en una tabla HTML con estilos básicos.
Requisitos:
- Campos:
- Nombre: Texto (máximo 100 caracteres).
- Email: Correo electrónico único.
- Curso: Texto (por ejemplo, “Matemáticas”, máximo 100 caracteres).
- Funcionalidades:
- Añadir un estudiante mediante un formulario (POST).
- Listar todos los estudiantes en una tabla.
- Validar datos (campos no vacíos, email válido).
- Usar una clase para manejar operaciones de base de datos.
- Tecnologías:
- HTML/CSS: Interfaz de usuario.
- PHP: Lógica del servidor.
- MySQL: Almacenamiento.
- POO: Clase para encapsular lógica.
- Opcional: Composer para paquetes (por ejemplo, validación).
Planificación:
- Base de datos (30 min): Crear la base de datos y tabla.
- Clase Estudiante (45 min): Diseñar una clase para manejar datos.
- Formulario y lógica (1 h): Crear el formulario y procesar datos.
- Listado de estudiantes (45 min): Mostrar datos en una tabla.
- Estilos y pruebas (1 h): Aplicar CSS y probar la aplicación.
Por qué es importante:
- Este proyecto simula aplicaciones reales (como un sistema de gestión escolar) y prepara para Laravel, donde se usan modelos, vistas, y controladores para tareas similares.
Estructura sugerida:
proyecto_estudiantes/
├── config/
│ └── db.php # Configuración de la base de datos
├── src/
│ └── Estudiante.php # Clase Estudiante
├── public/
│ ├── css/
│ │ └── estilos.css
│ ├── index.php # Formulario y lista
│ └── procesar.php # Lógica del formulario
├── composer.json # Configuración de Composer
└── vendor/ # Dependencias (si se usa Composer)
Punto clave: El proyecto final integra formularios, POO, y MySQL, consolidando habilidades para aplicaciones backend.
Actividad rápida (5 minutos):
Escribe en papel los pasos principales para la aplicación (base de datos, clase, formulario, lista). Ejemplo:
- Crear tabla estudiantes.
- Definir clase Estudiante.
- Hacer formulario HTML.
- Mostrar estudiantes en tabla.
Configuración de la base de datos (30 minutos)
Explicación:
Primero, configuramos MySQL para almacenar los datos de los estudiantes.
Paso 1: Crear base de datos y tabla:
- Abre phpMyAdmin (http://localhost/phpmyadmin) con XAMPP iniciado.
- Crea una base de datos:
- Nombre: gestion_estudiantes.
- Codificación: utf8_general_ci.
- Crea la tabla estudiantes:
CREATE TABLE estudiantes ( id INT AUTO_INCREMENT PRIMARY KEY, nombre VARCHAR(100) NOT NULL, email VARCHAR(100) NOT NULL UNIQUE, curso VARCHAR(100) NOT NULL );
- id: Identificador único, autoincremental.
- nombre: Nombre del estudiante.
- email: Correo único para evitar duplicados.
- curso: Curso inscrito.
Paso 2: Archivo de configuración:
- Crea config/db.php para centralizar la conexión:
<?php
class Database {
private $servidor = "localhost";
private $usuario = "root";
private $contrasena = "";
private $base_datos = "gestion_estudiantes";
public $conexion;
public function __construct() {
$this->conexion = new mysqli($this->servidor, $this->usuario, $this->contrasena, $this->base_datos);
if ($this->conexion->connect_error) {
die("Error de conexión: " . $this->conexion->connect_error);
}
}
public function getConnection() {
return $this->conexion;
}
public function close() {
$this->conexion->close();
}
}
?>
Cómo funciona:
- Clase Database: Encapsula la conexión MySQLi.
- __construct(): Establece la conexión al instanciar.
- getConnection(): Devuelve el objeto mysqli para consultas.
- close(): Cierra la conexión (opcional).
Cómo probarlo:
- Crea un script temporal test_db.php:
<?php
require 'config/db.php';
$db = new Database();
echo "Conexión exitosa!";
$db->close();
?>
- Guarda en proyecto_estudiantes/ y accede: http://localhost/proyecto_estudiantes/test_db.php.
- Verifica: "Conexión exitosa!" o un error si falla.
- Revisa php_error.log (en XAMPP) para depurar.
Punto clave: Una base de datos bien configurada es esencial para almacenar datos dinámicos, como en Laravel con Eloquent.
Actividad rápida (5 minutos):
Escribe en papel o crea la consulta SQL para añadir un estudiante de prueba manualmente en phpMyAdmin. Solución sugerida:
INSERT INTO estudiantes (nombre, email, curso) VALUES ('Juan Pérez', 'juan@correo.com', 'Matemáticas');
Crear la clase Estudiante (45 minutos)
Explicación:
Usaremos POO para encapsular la lógica de manejo de datos en una clase Estudiante.
Diseño de la clase:
- Propiedades: $nombre, $email, $curso.
- Métodos:
- guardar(): Inserta un estudiante en la base de datos.
- listar(): Recupera todos los estudiantes.
- Dependencia: Conexión a MySQL (Database).
Código:
- Crea src/Estudiante.php:
<?php
require_once 'config/db.php';
class Estudiante {
private $db;
public $nombre;
public $email;
public $curso;
public function __construct() {
$database = new Database();
$this->db = $database->getConnection();
}
public function guardar($nombre, $email, $curso) {
$this->nombre = $this->db->real_escape_string($nombre);
$this->email = $this->db->real_escape_string($email);
$this->curso = $this->db->real_escape_string($curso);
// Validación básica
if (empty($this->nombre) || empty($this->email) || empty($this->curso)) {
return "Todos los campos son obligatorios.";
}
if (!filter_var($this->email, FILTER_VALIDATE_EMAIL)) {
return "El email no es válido.";
}
// Verificar email único
$sql = "SELECT id FROM estudiantes WHERE email='$this->email'";
$resultado = $this->db->query($sql);
if ($resultado->num_rows > 0) {
return "El email ya está registrado.";
}
// Insertar
$sql = "INSERT INTO estudiantes (nombre, email, curso) VALUES ('$this->nombre', '$this->email', '$this->curso')";
if ($this->db->query($sql) === TRUE) {
return "Estudiante guardado correctamente.";
}
return "Error al guardar: " . $this->db->error;
}
public function listar() {
$sql = "SELECT * FROM estudiantes";
$resultado = $this->db->query($sql);
$estudiantes = [];
while ($fila = $resultado->fetch_assoc()) {
$estudiantes[] = $fila;
}
return $estudiantes;
}
}
?>
Cómo funciona:
- __construct(): Inicializa la conexión usando Database.
- guardar($nombre, $email, $curso): Valida datos, verifica email único, e inserta en la base de datos.
- listar(): Recupera todos los estudiantes como un array asociativo.
- real_escape_string(): Previene inyecciones SQL.
- filter_var(): Valida el formato del email.
Cómo probarlo:
- Crea un script temporal test_estudiante.php:
<?php
require 'src/Estudiante.php';
$estudiante = new Estudiante();
echo $estudiante->guardar("Ana López", "ana@correo.com", "Física");
$lista = $estudiante->listar();
var_dump($lista);
?>
- Accede: http://localhost/proyecto_estudiantes/test_estudiante.php.
- Verifica: Mensaje de éxito y lista de estudiantes (en var_dump).
- Confirma en phpMyAdmin que el registro se añadió.
Punto clave: La clase Estudiante encapsula la lógica de datos, similar a un modelo en Laravel.
Actividad rápida (5 minutos):
Añade en papel o editor un método contar() a la clase Estudiante que devuelva el número de estudiantes. Solución sugerida:
public function contar() {
$sql = "SELECT COUNT(*) as total FROM estudiantes";
$resultado = $this->db->query($sql);
$fila = $resultado->fetch_assoc();
return $fila['total'];
}
Formulario y procesamiento (1 hora)
Explicación:
Crearemos un formulario para registrar estudiantes y procesaremos los datos usando la clase Estudiante.
Código:
- Crea public/index.php:
<!DOCTYPE html>
<html lang="es">
<head>
<title>Registro de Estudiantes</title>
<link rel="stylesheet" href="css/estilos.css">
</head>
<body>
<h1>Gestión de Estudiantes</h1>
<section class="formulario">
<h2>Registrar Estudiante</h2>
<form method="post" action="procesar.php">
<label for="nombre">Nombre:</label>
<input type="text" id="nombre" name="nombre" placeholder="Nombre completo" required>
<label for="email">Email:</label>
<input type="email" id="email" name="email" placeholder="correo@ejemplo.com" required>
<label for="curso">Curso:</label>
<input type="text" id="curso" name="curso" placeholder="Ej. Matemáticas" required>
<button type="submit">Registrar</button>
</form>
<?php
if (isset($_GET['mensaje'])) {
$mensaje = htmlspecialchars($_GET['mensaje']);
$clase = isset($_GET['error']) ? 'error' : 'exito';
echo "<p class='$clase'>$mensaje</p>";
}
?>
</section>
<section class="lista">
<h2>Lista de Estudiantes</h2>
<?php
require 'src/Estudiante.php';
$estudiante = new Estudiante();
$estudiantes = $estudiante->listar();
if (empty($estudiantes)) {
echo "<p class='sin-datos'>No hay estudiantes registrados.</p>";
} else {
echo "<table>";
echo "<tr><th>ID</th><th>Nombre</th><th>Email</th><th>Curso</th></tr>";
foreach ($estudiantes as $e) {
echo "<tr>";
echo "<td>" . htmlspecialchars($e['id']) . "</td>";
echo "<td>" . htmlspecialchars($e['nombre']) . "</td>";
echo "<td>" . htmlspecialchars($e['email']) . "</td>";
echo "<td>" . htmlspecialchars($e['curso']) . "</td>";
echo "</tr>";
}
echo "</table>";
}
?>
</section>
</body>
</html>
- Crea public/procesar.php:
<?php
require 'src/Estudiante.php';
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$nombre = $_POST['nombre'] ?? '';
$email = $_POST['email'] ?? '';
$curso = $_POST['curso'] ?? '';
$estudiante = new Estudiante();
$resultado = $estudiante->guardar($nombre, $email, $curso);
if ($resultado === "Estudiante guardado correctamente.") {
header("Location: index.php?mensaje=" . urlencode($resultado));
} else {
header("Location: index.php?mensaje=" . urlencode($resultado) . "&error=1");
}
exit;
}
?>
Cómo funciona:
- index.php:
- Formulario HTML con campos nombre, email, curso (POST a procesar.php).
- Muestra mensajes de éxito/error desde $_GET.
- Lista estudiantes usando Estudiante::listar().
- procesar.php:
- Recibe datos del formulario.
- Usa Estudiante::guardar() para validar e insertar.
- Redirige a index.php con un mensaje.
- htmlspecialchars(): Evita problemas con caracteres especiales.
Punto clave: El formulario y su procesamiento integran frontend y backend, como en las rutas y vistas de Laravel.
Actividad rápida (5 minutos):
Añade en papel o editor un campo fecha_nacimiento al formulario y actualiza la tabla estudiantes para incluirlo. Solución sugerida:
- SQL:
ALTER TABLE estudiantes ADD fecha_nacimiento DATE;
-
Formulario:
<input type="date" id="fecha_nacimiento" name="fecha_nacimiento">
Estilos y presentación (45 minutos)
Explicación:
Añadiremos estilos CSS para mejorar la interfaz de usuario.
Código:
- Crea public/css/estilos.css:
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 20px auto;
padding: 0 15px;
color: #2c3e50;
}
h1 {
text-align: center;
color: #2c3e50;
}
.formulario, .lista {
margin: 20px 0;
}
.formulario h2, .lista h2 {
color: #34495e;
}
form {
display: flex;
flex-direction: column;
gap: 10px;
max-width: 400px;
margin: 0 auto;
}
label {
font-weight: bold;
}
input {
padding: 8px;
font-size: 1rem;
border: 1px solid #ccc;
border-radius: 4px;
}
button {
background-color: #2c3e50;
color: white;
padding: 10px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 1rem;
}
button:hover {
background-color: #34495e;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
th, td {
padding: 10px;
border: 1px solid #ccc;
text-align: left;
}
th {
background-color: #2c3e50;
color: white;
}
.exito {
color: green;
font-weight: bold;
}
.error {
color: red;
font-weight: bold;
}
.sin-datos {
font-style: italic;
color: #7f8c8d;
}
Cómo funciona:
- Estilos responsivos y claros para formularios y tablas.
- Colores consistentes (#2c3e50, #34495e) para profesionalidad.
- flex y gap para alinear el formulario.
- Clases .exito, .error, .sin-datos para mensajes dinámicos.
Punto clave: Una interfaz clara mejora la experiencia del usuario, como en las vistas Blade de Laravel.
Actividad rápida (5 minutos):
Modifica estilos.css (en papel o editor) para cambiar el color de fondo de la tabla a gris claro. Solución sugerida:
table {
background-color: #f9f9f9;
}
Pruebas y mejoras (1 hora)
Explicación:
Probamos la aplicación para asegurar que cumple con el entregable: crear y listar estudiantes.
Instrucciones de prueba:
- Configuración inicial:
- Verifica que XAMPP esté ejecutando Apache y MySQL.
- Asegúrate de que la base de datos gestion_estudiantes y la tabla estudiantes existan (ver paso 2).
- Confirma la estructura de archivos:
proyecto_estudiantes/ ├── config/ │ └── db.php ├── src/ │ └── Estudiante.php ├── public/ │ ├── css/ │ │ └── estilos.css │ ├── index.php │ └── procesar.php
- Coloca proyecto_estudiantes/ en C:\xampp\htdocs.
- Acceso:
- Abre: http://localhost/proyecto_estudiantes/public/index.php.
- Pruebas de funcionalidad:
- Crear (formulario):
- Ingresa datos válidos:
- Nombre: "Juan Pérez", Email: "juan@correo.com", Curso: "Matemáticas".
- Resultado: Mensaje verde: "Estudiante registrado correctamente."
- Ingresa email duplicado:
- Nombre: "Ana López", Email: "juan@correo.com", Curso: "Física".
- Resultado: Mensaje rojo: "El email ya está registrado."
- Ingresa datos inválidos:
- Nombre: "", Email: "invalido", Curso: "Historia".
- Resultado: Mensaje rojo: "Todos los campos son obligatorios." o "El email no es válido."
- Verifica en phpMyAdmin que los registros válidos se añadan a estudiantes.
- Ingresa datos válidos:
- Listar (tabla):
- Si hay estudiantes, aparecen en una tabla con columnas ID, Nombre, Email, Curso.
- Si no hay estudiantes, muestra: "No hay estudiantes registrados."
- Confirma que los datos coinciden con phpMyAdmin.
- Crear (formulario):
- Estilos:
- Asegúrate de que el formulario sea claro y la tabla legible (prueba en móvil reduciendo la ventana).
- Verifica que los mensajes de éxito (verde) y error (rojo) sean visibles.
- Depuración:
- Si hay errores, revisa php_error.log (en C:\xampp\php\logs).
- Usa var_dump($estudiantes) en index.php para inspeccionar la lista.
- Verifica rutas de inclusión (require '../src/Estudiante.php').
Entregable final:
- Una aplicación funcional con:
- Crear: Formulario que registra estudiantes en MySQL (validando campos y unicidad del email).
- Listar: Tabla que muestra todos los estudiantes o un mensaje si está vacía.
- Archivos:
- config/db.php: Conexión a MySQL.
- src/Estudiante.php: Clase con métodos guardar() y listar().
- public/index.php: Formulario y lista.
- public/procesar.php: Procesamiento del formulario.
- public/css/estilos.css: Estilos.
- Pruebas exitosas de ambas operaciones.
Cómo entregar:
- Comprime proyecto_estudiantes/ como proyecto_estudiantes.zip.
- Opcional: Incluye capturas de pantalla de la aplicación (formulario, tabla, mensaje de éxito).
- Alternativa: Describe los archivos y resultados para que los revise.
Corrección respecto a la versión original:
- Eliminé referencias a operaciones no requeridas (editar, eliminar).
- Simplifiqué las pruebas, enfocándome en crear y listar.
- Añadí persistencia de datos en el formulario para errores.
- Aclaré rutas y depuración para evitar errores comunes.
Punto clave: Las pruebas confirman que la aplicación cumple con el entregable, similar a validar un CRUD básico en Laravel.
Actividad rápida (5 minutos):
Escribe en papel un caso de prueba para la operación crear. Ejemplo:
- Entrada: Nombre="Luis", Email="luis@correo.com", Curso="Química".
- Resultado: Mensaje verde, nuevo estudiante en la tabla.
Instrucciones finales para el estudiante
Pasos para completar el proyecto:
- Crea la carpeta proyecto_estudiantes/ en htdocs.
- Configura la base de datos (gestion_estudiantes, tabla estudiantes) en phpMyAdmin.
- Implementa los archivos:
- config/db.php
- src/Estudiante.php
- public/index.php
- public/procesar.php
- public/css/estilos.css
- Prueba:
- Accede: http://localhost/proyecto_estudiantes/public/index.php.
- Registra estudiantes y verifica la lista.
- Confirma los datos en phpMyAdmin.
- Entrega:
- Carpeta completa o descripción de los resultados.
Tiempo estimado: 4 horas (puedes dividirlo en sesiones):
- Configuración: 30 min.
- Clase: 45 min.
- Formulario: 1 h.
- Lista: 45 min.
- Estilos y pruebas: 1 h.
Consejo:
- Trabaja en orden (base de datos → clase → formulario → lista → estilos).
- Prueba cada componente antes de avanzar (por ejemplo, verifica la conexión antes de la clase).
- Usa echo o var_dump() para depurar si algo falla.