Módulo 4: Fundamentos de PHP

Proyecto Final: Aplicación para Gestionar Datos de Estudiantes

Lección 22 de 33 del Curso Roadmap Learning Laravel

Duración: 4 horas
Nivel: Principiante (requiere conocimientos de HTML, CSS, JavaScript, y PHP: sintaxis básica, formularios, POO, MySQL, Composer)
Objetivo: Desarrollar una aplicación PHP funcional que integre formularios, conexión a MySQL, y POO para gestionar un registro de estudiantes, consolidando las habilidades del Módulo 4 y preparando para frameworks como Laravel.
Materiales necesarios:

  • Computadora con:
    • XAMPP, WAMP, o MAMP (incluye PHP y MySQL/MariaDB, descarga gratuita desde sus sitios oficiales).
    • Editor de texto (recomendado: VS Code, descarga gratuita desde code.visualstudio.com).
    • phpMyAdmin (incluido en XAMPP) o un cliente MySQL como MySQL Workbench.
    • Composer instalado (ver Lección 5).
  • Navegador web (Chrome, Firefox, etc.).
  • Acceso a internet para instalar paquetes Composer (opcional).
  • Alternativa: Entorno online con soporte PHP/MySQL (limitado, por ejemplo, Repl.it).
    Contexto: Este proyecto final aplica los conceptos del módulo en una aplicación práctica, similar a sistemas de gestión en Laravel, donde se combinan frontend (formularios), backend (PHP, POO), y bases de datos (MySQL).

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:

  1. Base de datos (30 min): Crear la base de datos y tabla.
  2. Clase Estudiante (45 min): Diseñar una clase para manejar datos.
  3. Formulario y lógica (1 h): Crear el formulario y procesar datos.
  4. Listado de estudiantes (45 min): Mostrar datos en una tabla.
  5. 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:

  1. Crear tabla estudiantes.
  2. Definir clase Estudiante.
  3. Hacer formulario HTML.
  4. 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:

  1. 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.
  2. Acceso:
    • Abre: http://localhost/proyecto_estudiantes/public/index.php.
  3. 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.
    • 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.
  4. 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.
  5. 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:

  1. Crea la carpeta proyecto_estudiantes/ en htdocs.
  2. Configura la base de datos (gestion_estudiantes, tabla estudiantes) en phpMyAdmin.
  3. Implementa los archivos:
    • config/db.php
    • src/Estudiante.php
    • public/index.php
    • public/procesar.php
    • public/css/estilos.css
  4. Prueba:
    • Accede: http://localhost/proyecto_estudiantes/public/index.php.
    • Registra estudiantes y verifica la lista.
    • Confirma los datos en phpMyAdmin.
  5. 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.

Evaluación Final: Conocimientos Clave para Crear una Aplicación PHP

¡Es momento de evaluar tus conocimientos sobre el desarrollo de aplicaciones PHP! Este examen consta de 10 preguntas con opciones múltiples que cubren temas clave como formularios, conexión a MySQL, programación orientada a objetos y manejo de datos. Contesta con atención y demuestra tu comprensión de cómo integrar todos estos elementos para crear una aplicación funcional. ¡Buena suerte!

1. ¿Cuál era el objetivo principal del proyecto final del Módulo 4?

2. ¿Qué campos debía incluir la tabla estudiantes en la base de datos?

3. ¿Qué método de la clase Estudiante se usaba para insertar un nuevo estudiante?

4. ¿Qué método PHP se usó para prevenir inyecciones SQL en la clase Estudiante?

5. ¿Qué archivo procesaba los datos enviados por el formulario?

6. ¿Qué estructura HTML se usó para mostrar la lista de estudiantes?

7. ¿Qué validación se implementó para el campo email en la clase Estudiante?

8. ¿Qué archivo contenía la configuración de la conexión a MySQL?

9. ¿Qué método de la clase Estudiante recuperaba todos los estudiantes?

10. ¿Qué técnica se usó para mostrar mensajes de éxito o error tras registrar un estudiante?

© Copyright Cursos Laravel :: 2025 Términos y condiciones