Saltar al contenido
Portada » Lenguajes » 15. Proyecto Final

15. Proyecto Final

Proyecto Final. Después de haber recorrido todos los fundamentos y conceptos avanzados de PHP —desde los primeros pasos con el lenguaje hasta la integración con bases de datos, seguridad, y uso de frameworks—, en este capítulo llevaremos a la práctica todo lo aprendido mediante el desarrollo de una aplicación web completa.

El objetivo principal de este proyecto final es que consolides tus conocimientos y habilidades enfrentándote a un flujo completo de desarrollo: desde la planificación inicial, pasando por el diseño estructurado del código, hasta llegar a la implementación técnica y la prueba del sistema.

Este capítulo se divide en tres partes clave:

  1. Descripción del proyecto, donde se explicará la idea de la aplicación a construir, sus funcionalidades y requerimientos.
  2. Planificación y estructura del código, en la que aprenderás cómo dividir el proyecto en módulos, gestionar rutas y organizar los archivos de forma escalable y mantenible.
  3. Desarrollo e implementación, donde te guiaré paso a paso en la creación de la aplicación, integrando formularios, sesiones, conexión a bases de datos, seguridad y estilos visuales.

Al terminar este proyecto, no solo tendrás una aplicación web PHP funcional, sino también una base sólida para construir proyectos personales o profesionales más complejos.

15.1 Descripción del Proyecto

Aplicación Web de Gestión de Tareas Personales (ToDo App)

Idea Principal

Vamos a construir una aplicación web de gestión de tareas personales, también conocida como una ToDo List. El objetivo de este proyecto es que los usuarios puedan registrarse, iniciar sesión y gestionar sus tareas diarias (crear, editar, marcar como completadas, y eliminar tareas). Esta aplicación combina todos los aspectos esenciales del desarrollo web moderno con PHP.

Funcionalidades Clave

  1. Registro de usuario: Formulario de registro con validación de datos, control de usuarios duplicados y almacenamiento seguro de contraseñas (bcrypt).
  2. Inicio de sesión: Mecanismo de autenticación usando sesiones y protección contra accesos no autorizados.
  3. Gestión de tareas (CRUD):
    • Crear tareas nuevas (formulario).
    • Visualizar tareas pendientes y completadas.
    • Editar nombre o estado de una tarea.
    • Eliminar tareas.
  4. Seguridad:
    • Validación y saneamiento de entradas de usuario.
    • Protección contra ataques XSS y CSRF.
    • Hashing de contraseñas con password_hash() y verificación con password_verify().
  5. Interfaz amigable y responsive, utilizando HTML5, CSS y algo de JavaScript opcional (para mejorar experiencia).

Tecnología y herramientas

  • Lenguaje principal: PHP (en su versión más reciente estable)
  • Base de datos: MySQL
  • Conexión a la BBDD: PDO
  • Estructura del proyecto: Basado en el patrón MVC simple (Modelo-Vista-Controlador) sin framework
  • Diseño: HTML y CSS puros, con posibilidad de integrar Bootstrap si se desea

Objetivos didácticos

  • Consolidar el uso de PHP con HTML y formularios.
  • Utilizar sentencias preparadas con PDO para evitar inyecciones SQL.
  • Aplicar el manejo de sesiones, cookies y validación de usuarios.
  • Dominar el proceso de CRUD sobre una base de datos real.
  • Estructurar un proyecto PHP completo, limpio y escalable.

Resultado esperado

Al finalizar este proyecto, tendrás una aplicación web funcional donde cada usuario puede:

  • Registrarse e iniciar sesión.
  • Crear y gestionar su lista de tareas personales.
  • Navegar en un entorno privado y seguro.
  • Desconectarse y mantener sus datos guardados.

15.2 Planificación y Estructura del Código

Antes de comenzar a programar, es crucial tener una visión clara de la arquitectura del proyecto, dividir las funcionalidades, y estructurar correctamente carpetas, archivos y responsabilidades. Esto garantiza un código limpio, mantenible y escalable.

1. Objetivo de esta fase

La planificación y estructuración del proyecto nos permitirá:

  • Organizar correctamente el código PHP, HTML, CSS y SQL.
  • Separar la lógica de negocio, las vistas (interfaces de usuario) y la interacción con la base de datos.
  • Reutilizar componentes y evitar duplicidad de código.
  • Facilitar futuras ampliaciones del proyecto (como incluir categorías de tareas o APIs).

2. Estructura de carpetas del proyecto

A continuación, se detalla una posible estructura para el proyecto siguiendo un patrón MVC simple:

todo-app/

├── index.php ← Punto de entrada principal
├── config/
│ └── config.php ← Configuración general (DB, constantes)

├── controllers/
│ ├── AuthController.php ← Controlador de autenticación
│ ├── TaskController.php ← Controlador de tareas

├── models/
│ ├── User.php ← Modelo para la tabla usuarios
│ └── Task.php ← Modelo para la tabla tareas

├── views/
│ ├── auth/
│ │ ├── login.php ← Vista para el login
│ │ └── register.php ← Vista de registro
│ ├── tasks/
│ │ ├── list.php ← Vista principal (lista de tareas)
│ │ ├── create.php ← Formulario para nueva tarea
│ │ └── edit.php ← Formulario para editar tarea
│ └── layout/
│ ├── header.php ← Cabecera HTML común
│ └── footer.php ← Pie de página común

├── public/
│ ├── css/
│ │ └── style.css ← Estilos CSS
│ └── js/
│ └── scripts.js ← JavaScript opcional

├── database/
│ └── init.sql ← Script para crear las tablas necesarias

└── utils/
└── functions.php ← Funciones auxiliares comunes

3. Archivos clave y sus responsabilidades

Archivo/CarpetaDescripción
index.phpPunto central de entrada. Redirige a controladores según las rutas definidas (de forma básica, sin usar router).
config/config.phpContiene los datos de conexión a la base de datos y otras constantes de configuración.
controllers/Gestiona la lógica de negocio. Recoge datos del usuario, interactúa con los modelos y pasa datos a las vistas.
models/Accede a la base de datos y representa las entidades (User, Task). Utiliza PDO y sentencias preparadas.
views/Contiene las páginas HTML y los formularios. Presenta los datos que el controlador le pasa.
public/css/Contiene los estilos CSS personalizados.
database/init.sqlScript SQL que crea las tablas necesarias para el proyecto (users y tasks).
utils/functions.phpFunciones reutilizables, como comprobaciones de sesión, redirecciones, sanitización, validaciones comunes, etc.

4. Base de datos: Tablas necesarias

Base de datos: todo_app

CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE tasks (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
title VARCHAR(255) NOT NULL,
description TEXT,
status ENUM('pendiente', 'completada') DEFAULT 'pendiente',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);

5. Flujo general de trabajo

Usuario no autenticado:

  1. Accede a index.php → redirección al formulario de login o registro.
  2. Se registra (valida entrada, se guarda con contraseña hasheada).
  3. Se loguea → se inicia sesión y se redirige a TaskController.

Usuario autenticado:

  1. Llega a la vista principal (list.php) donde ve sus tareas.
  2. Puede:
    • Crear una nueva tarea (create.php)
    • Marcar como completada / editar (edit.php)
    • Eliminar una tarea
  3. Se desloguea (destruye la sesión).

– Raíz

/todo-app/index.php

<?php
// Iniciar sesión
session_start();

// Cargar configuración de la base de datos
require_once 'config/config.php';

// Cargar funciones auxiliares
require_once 'utils/functions.php';

// Cargar controladores
require_once 'controllers/AuthController.php';
require_once 'controllers/TaskController.php';

// Determinar la página a mostrar
$page = $_GET['page'] ?? 'home';

// Ruteo básico según valor de $_GET['page']
switch ($page) {
case 'login':
login();
break;

case 'register':
register();
break;

case 'logout':
session_destroy();
header('Location: index.php?page=login');
exit;
break;

case 'dashboard':
showTasks();
break;

case 'add-task':
addTask();
break;

// Aquí podrías añadir editar y eliminar tareas
// case 'edit-task':
// editTask();
// break;
// case 'delete-task':
// deleteTask();
// break;

case 'home':
default:
if (isAuthenticated()) {
header('Location: index.php?page=dashboard');
exit;
} else {
header('Location: index.php?page=login');
exit;
}
break;
}

– Config

todo-app/config/config.php

<?php
$host = 'localhost';
$dbname = 'todo_app';
$user = 'root';
$pass = '';

try {
    $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $user, $pass);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    die("Error de conexión: " . $e->getMessage());
}
?>

– Controllers

/todo-app/controllers/AuthController.php:

<?php
require_once 'models/User.php';

function login() {
global $pdo;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$user = User::login($pdo, $_POST['email'], $_POST['password']);
if ($user) {
session_start();
$_SESSION['user_id'] = $user['id'];
header('Location: index.php?page=dashboard');
exit;
} else {
$error = "Credenciales incorrectas";
}
}
include 'views/auth/login.php';
}

function register() {
global $pdo;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
User::register($pdo, $_POST['username'], $_POST['email'], $_POST['password']);
header('Location: index.php?page=login');
exit;
}
include 'views/auth/register.php';
}

/todo-app/controllers/TaskController.php:

<?php
require_once 'models/Task.php';

function showTasks() {
global $pdo;
session_start();
requireLogin();
$tasks = Task::getAllByUser($pdo, $_SESSION['user_id']);
include 'views/tasks/list.php';
}

function addTask() {
global $pdo;
session_start();
requireLogin();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
Task::create($pdo, $_SESSION['user_id'], $_POST['title'], $_POST['description']);
header('Location: index.php?page=dashboard');
exit;
}
include 'views/tasks/create.php';
}

– Models

/todo-app/models/User.php:

<?php
class User {
public static function register($pdo, $username, $email, $password) {
$hash = password_hash($password, PASSWORD_BCRYPT);
$stmt = $pdo->prepare("INSERT INTO users (username, email, password) VALUES (?, ?, ?)");
return $stmt->execute([$username, $email, $hash]);
}

public static function login($pdo, $email, $password) {
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?");
$stmt->execute([$email]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if ($user && password_verify($password, $user['password'])) {
return $user;
}
return false;
}
}

/todo-app/models/Task.php:

<?php
class Task {
public static function getAllByUser($pdo, $user_id) {
$stmt = $pdo->prepare("SELECT * FROM tasks WHERE user_id = ?");
$stmt->execute([$user_id]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}

public static function create($pdo, $user_id, $title, $description) {
$stmt = $pdo->prepare("INSERT INTO tasks (user_id, title, description) VALUES (?, ?, ?)");
return $stmt->execute([$user_id, $title, $description]);
}

public static function update($pdo, $id, $title, $description, $status) {
$stmt = $pdo->prepare("UPDATE tasks SET title = ?, description = ?, status = ? WHERE id = ?");
return $stmt->execute([$title, $description, $status, $id]);
}

public static function delete($pdo, $id) {
$stmt = $pdo->prepare("DELETE FROM tasks WHERE id = ?");
return $stmt->execute([$id]);
}
}

– Views

/todo-app/views/auth/login.php

<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Iniciar Sesión</title>
<link rel="stylesheet" href="assets/styles.css">
</head>
<body>
<h2>Iniciar Sesión</h2>

<?php if (!empty($error)): ?>
<p style="color: red;"><?php echo htmlspecialchars($error); ?></p>
<?php endif; ?>

<form method="POST" action="index.php?page=login">
<label for="email">Correo electrónico:</label><br>
<input type="email" name="email" id="email" required><br><br>

<label for="password">Contraseña:</label><br>
<input type="password" name="password" id="password" required><br><br>

<button type="submit">Entrar</button>
</form>

<p>¿No tienes una cuenta? <a href="index.php?page=register">Regístrate</a></p>
</body>
</html>

/todo-app/views/auth/register.php

<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Registro de Usuario</title>
<link rel="stylesheet" href="assets/styles.css">
</head>
<body>
<h2>Registro de Usuario</h2>

<?php if (!empty($error)): ?>
<p style="color: red;"><?php echo htmlspecialchars($error); ?></p>
<?php endif; ?>

<form method="POST" action="index.php?page=register">
<label for="name">Nombre:</label><br>
<input type="text" name="name" id="name" required><br><br>

<label for="email">Correo electrónico:</label><br>
<input type="email" name="email" id="email" required><br><br>

<label for="password">Contraseña:</label><br>
<input type="password" name="password" id="password" required><br><br>

<button type="submit">Registrarse</button>
</form>

<p>¿Ya tienes una cuenta? <a href="index.php?page=login">Inicia sesión</a></p>
</body>
</html>

– Tasks

/todo-app/views/tasks/list.php

<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Lista de Tareas</title>
<link rel="stylesheet" href="assets/styles.css">
</head>
<body>
<h2>Lista de Tareas</h2>

<p><a href="index.php?page=task_create">Crear Nueva Tarea</a> | <a href="index.php?page=logout">Cerrar Sesión</a></p>

<?php if (empty($tasks)): ?>
<p>No tienes tareas aún.</p>
<?php else: ?>
<table border="1" cellpadding="8" cellspacing="0">
<thead>
<tr>
<th>ID</th>
<th>Título</th>
<th>Descripción</th>
<th>Acciones</th>
</tr>
</thead>
<tbody>
<?php foreach ($tasks as $task): ?>
<tr>
<td><?php echo htmlspecialchars($task['id']); ?></td>
<td><?php echo htmlspecialchars($task['title']); ?></td>
<td><?php echo htmlspecialchars($task['description']); ?></td>
<td>
<a href="index.php?page=task_edit&id=<?php echo $task['id']; ?>">Editar</a> |
<a href="index.php?page=task_delete&id=<?php echo $task['id']; ?>" onclick="return confirm('¿Estás seguro de eliminar esta tarea?');">Eliminar</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</body>
</html>

/todo-app/views/tasks/create.php

<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Crear Nueva Tarea</title>
<link rel="stylesheet" href="assets/styles.css">
</head>
<body>
<h2>Crear Nueva Tarea</h2>

<?php if (!empty($error)): ?>
<p style="color: red;"><?php echo htmlspecialchars($error); ?></p>
<?php endif; ?>

<form method="POST" action="index.php?page=task_create">
<label for="title">Título:</label><br>
<input type="text" id="title" name="title" required value="<?php echo isset($title) ? htmlspecialchars($title) : ''; ?>"><br><br>

<label for="description">Descripción:</label><br>
<textarea id="description" name="description" rows="4" cols="50" required><?php echo isset($description) ? htmlspecialchars($description) : ''; ?></textarea><br><br>

<button type="submit">Crear</button>
<a href="index.php?page=task_list">Cancelar</a>
</form>
</body>
</html>

/todo-app/views/tasks/edit.php

<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Editar Tarea</title>
<link rel="stylesheet" href="assets/styles.css">
</head>
<body>
<h2>Editar Tarea</h2>

<?php if (!empty($error)): ?>
<p style="color: red;"><?php echo htmlspecialchars($error); ?></p>
<?php endif; ?>

<form method="POST" action="index.php?page=task_edit&id=<?php echo $task['id']; ?>">
<label for="title">Título:</label><br>
<input type="text" id="title" name="title" required value="<?php echo htmlspecialchars($task['title']); ?>"><br><br>

<label for="description">Descripción:</label><br>
<textarea id="description" name="description" rows="4" cols="50" required><?php echo htmlspecialchars($task['description']); ?></textarea><br><br>

<button type="submit">Guardar Cambios</button>
<a href="index.php?page=task_list">Cancelar</a>
</form>
</body>
</html>

– Layaout

/todo-app/views/layout/header.php

<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Mi Aplicación de Tareas</title>
<link rel="stylesheet" href="assets/styles.css">
</head>
<body>
<header>
<h1>Gestor de Tareas</h1>
<nav>
<a href="index.php?page=task_list">Tareas</a> |
<a href="index.php?page=task_create">Nueva Tarea</a> |
<a href="index.php?page=logout">Cerrar Sesión</a>
</nav>
<hr>
</header>

/todo-app/views/layout/footer.php

<footer>
<hr>
<p>&copy; <?php echo date('Y'); ?> Mi Aplicación de Tareas. Todos los derechos reservados.</p>
</footer>
</body>
</html>

– Public

/todo-app/public/css/style.css

/* Estilos generales */
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f2f2f2;
color: #333;
}

header, footer {
background-color: #004080;
color: white;
padding: 15px;
text-align: center;
}

nav a {
color: #fff;
margin: 0 10px;
text-decoration: none;
}

nav a:hover {
text-decoration: underline;
}

h1, h2 {
color: #004080;
}

.container {
max-width: 800px;
margin: 20px auto;
background-color: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}

form {
display: flex;
flex-direction: column;
}

form input[type="text"],
form textarea,
form input[type="password"],
form input[type="email"],
form select {
padding: 10px;
margin-bottom: 15px;
border: 1px solid #ccc;
border-radius: 4px;
}

form input[type="submit"],
form button {
background-color: #004080;
color: white;
border: none;
padding: 10px;
border-radius: 4px;
cursor: pointer;
}

form input[type="submit"]:hover,
form button:hover {
background-color: #003060;
}

table {
width: 100%;
border-collapse: collapse;
margin-bottom: 20px;
}

table, th, td {
border: 1px solid #ccc;
}

th, td {
padding: 10px;
text-align: left;
}

.alert {
padding: 10px;
background-color: #ffdddd;
border-left: 5px solid #f44336;
margin-bottom: 20px;
}

.success {
padding: 10px;
background-color: #ddffdd;
border-left: 5px solid #4CAF50;
margin-bottom: 20px;
}

/todo-app/public/js/scripts.js

/ JavaScript opcional para confirmación de borrado
function confirmarEliminacion(nombre) {
return confirm("¿Estás seguro de que deseas eliminar la tarea: '" + nombre + "'?");
}

// Asignación automática (opcional si lo usas directamente en el botón)
document.addEventListener("DOMContentLoaded", function () {
const botones = document.querySelectorAll(".btn-eliminar");
botones.forEach(boton => {
boton.addEventListener("click", function (e) {
const nombre = this.getAttribute("data-nombre");
if (!confirmarEliminacion(nombre)) {
e.preventDefault();
}
});
});
});

– Database

/todo-app/database/init.sql

-- Crear base de datos (si aún no existe)
CREATE DATABASE IF NOT EXISTS gestor_tareas DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE gestor_tareas;

-- Tabla de usuarios
CREATE TABLE IF NOT EXISTS usuarios (
id INT AUTO_INCREMENT PRIMARY KEY,
nombre VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
creado_en TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Tabla de tareas
CREATE TABLE IF NOT EXISTS tareas (
id INT AUTO_INCREMENT PRIMARY KEY,
usuario_id INT NOT NULL,
titulo VARCHAR(150) NOT NULL,
descripcion TEXT,
estado ENUM('pendiente', 'completada') DEFAULT 'pendiente',
creada_en TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
actualizada_en TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (usuario_id) REFERENCES usuarios(id) ON DELETE CASCADE
);

– Funciones

/todo-app/utils/functions.php

<?php
// Inicia la sesión si aún no está iniciada
if (session_status() === PHP_SESSION_NONE) {
session_start();
}

/**
* Verifica si el usuario está autenticado.
*
* @return bool
*/
function estaAutenticado(): bool {
return isset($_SESSION['usuario_id']);
}

/**
* Redirige al usuario a una página específica y termina el script.
*
* @param string $url
*/
function redirigir(string $url): void {
header("Location: $url");
exit;
}

/**
* Escapa una cadena para evitar XSS al imprimir en HTML.
*
* @param string|null $cadena
* @return string
*/
function escapar(?string $cadena): string {
return htmlspecialchars($cadena ?? '', ENT_QUOTES, 'UTF-8');
}

/**
* Muestra un mensaje flash y lo elimina de la sesión.
*
* @param string $tipo
* @return string
*/
function obtenerFlash(string $tipo): string {
if (isset($_SESSION['flash'][$tipo])) {
$mensaje = $_SESSION['flash'][$tipo];
unset($_SESSION['flash'][$tipo]);
return "<div class=\"alert alert-$tipo\">$mensaje</div>";
}
return '';
}

/**
* Asigna un mensaje flash a la sesión.
*
* @param string $tipo
* @param string $mensaje
*/
function establecerFlash(string $tipo, string $mensaje): void {
$_SESSION['flash'][$tipo] = $mensaje;
}

/**
* Conecta a la base de datos usando PDO.
*
* @return PDO
*/
function obtenerConexion(): PDO {
$host = 'localhost';
$db = 'gestor_tareas';
$user = 'root';
$pass = 'mypass';
$charset = 'utf8mb4';

$dsn = "mysql:host=$host;dbname=$db;charset=$charset";

try {
$pdo = new PDO($dsn, $user, $pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
]);
return $pdo;
} catch (PDOException $e) {
die("Error en la conexión: " . $e->getMessage());
}
}

Resumen Final del tutorial de PHP

Aquí termina este tutorial del lenguaje PHP, En esta guía hemos empezado desde sus fundamentos más básicos hasta el desarrollo de una aplicación web funcional explorando características avanzadas. A lo largo del camino, no solo aprendiste sintaxis y estructuras, sino también buenas prácticas y herramientas modernas para escribir código seguro, reutilizable y profesional.

¿Qué hemos aprendido?

  1. Fundamentos del Lenguaje PHP
    Comprendiste qué es PHP, cómo integrarlo con HTML y cómo ejecutarlo en un servidor local. Aprendiste a trabajar con variables, tipos de datos, operadores, estructuras de control, funciones, arrays y programación orientada a objetos (POO).
  2. Interacción con el Mundo Exterior
    Aprendiste cómo manejar formularios HTML con PHP, procesar datos enviados por GET y POST, validar entradas del usuario y generar respuestas dinámicas.
  3. Bases de Datos y Seguridad
    Te familiarizaste con MySQL y dos formas de conectarte desde PHP: MySQLi y PDO. Implementaste operaciones CRUD, usaste sentencias preparadas y conociste técnicas para protegerte contra inyecciones SQL, XSS y CSRF. También aprendiste a usar funciones como password_hash() y password_verify() para proteger contraseñas.
  4. Trabajo con APIs y Librerías Externas
    Aprendiste a consumir APIs externas desde PHP y a crear tus propias APIs REST. También exploraste cómo autenticar peticiones y cómo trabajar con herramientas como Composer para gestionar dependencias externas.
  5. Frameworks Modernos
    Conociste qué son los frameworks PHP y cómo mejoran la organización y escalabilidad de tus proyectos. Exploraste dos de los más populares: Laravel y CodeIgniter, y construiste un pequeño proyecto básico usando Laravel.
  6. Buenas Prácticas y Funcionalidades Avanzadas
    Profundizaste en el uso de sesiones y cookies, el envío de correos electrónicos, y aprendiste a organizar tu código mediante funciones auxiliares reutilizables.
  7. Proyecto Final
    Como culminación, desarrollaste una aplicación completa de gestión de tareas que incluye registro e inicio de sesión de usuarios, operaciones CRUD, autenticación, validación de formularios, sesiones, estructura modular de carpetas y una interfaz sencilla.

Próximos Pasos Recomendados

Esto no ha sido más que una introducción, te aconsejo que profundices en los siguientes campos para tener un mayor conocimiento de PHP:

  • Profundizar en Laravel u otro framework moderno.
  • Aprender testing automatizado con PHPUnit.
  • Integrar PHP con tecnologías frontend como Vue, React o HTMX.
  • Desplegar tus proyectos en servidores remotos (Apache/Nginx).
  • Explorar arquitecturas avanzadas como MVC, servicios RESTful y DDD.

Bibliografía de programación en PHP.

LogoPHP- Introducción al tutorial de PHP

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *