Ir al contenido principal

Lección 7 · MVC y organización del proyecto

Por qué organizar

Un proyecto que empieza con cuatro archivos sueltos y crece hasta veinte se vuelve difícil de tocar: cada archivo mezcla consultas a la base, reglas del negocio y HTML. Cambiar el color de un botón obliga a abrir un archivo que también inserta ventas, y un error en una línea rompe todo.

La solución no es «escribir más ordenado»: es separar responsabilidades. Cada parte hace una cosa y no conoce los detalles de las demás. Eso es lo que MVC propone.

MVC significa Modelo, Vista, Controlador: el modelo sabe de datos, la vista sabe de presentación y el controlador coordina.

Separar responsabilidades

Parte Qué hace En la tienda
ModeloConsulta y guarda datos; conoce la base y las reglas.Producto, Venta: buscar, listar, insertar.
VistaMuestra; no decide ni consulta.El HTML del catálogo con los productos ya listos.
ControladorRecibe la petición, pide datos al modelo y elige la vista.«Mostrar el catálogo»: pide los productos y entrega la vista.

La regla que hace la diferencia: la vista no consulta la base y el modelo no imprime HTML. Cuando se respeta, cambiar la presentación no toca la lógica, y al revés.

El ruteador

Todas las peticiones entran por un solo archivo —index.php— que mira la dirección pedida y decide qué controlador la atiende. Ese archivo se llama front controller o punto de entrada único.

$ruta = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

match ($ruta) {
    '/', '/productos' => (new ProductoController())->listar(),
    '/productos/crear' => (new ProductoController())->crear(),
    '/ventas' => (new VentaController())->listar(),
    default => http_response_code(404) . print('No encontrado'),
};

Con esto, agregar una página es agregar una línea al ruteador y el método en su controlador. Ya no hay un archivo suelto por pantalla, y todas las peticiones pasan por el mismo lugar: ahí se puede registrar, autenticar y aplicar cabeceras de seguridad una sola vez.

El punto de entrada

El index.php de la raíz hace tres cosas, en orden: cargar la configuración, armar el ruteador y despachar la petición.

<?php

declare(strict_types=1);

require __DIR__ . '/config/autoload.php';
require __DIR__ . '/config/conexion.php';

$ruta = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

// ... ruteador ...

Que todo entre por acá también simplifica la seguridad: si hay que exigir sesión en el área privada, se hace en el punto de entrada, no en cada archivo.

La estructura

tienda/
├── index.php            ← punto de entrada único
├── config/
│   ├── conexion.php
│   └── autoload.php
├── src/
│   ├── Modelo/
│   │   ├── Producto.php
│   │   └── Venta.php
│   ├── Controlador/
│   │   ├── ProductoController.php
│   │   └── VentaController.php
│   └── Vista/
│       ├── productos.php
│       └── ventas.php
└── public/
    ├── css/
    └── js/

La carpeta public/ es la única que debe quedar expuesta al servidor: ahí van CSS, JS e imágenes. El código PHP queda fuera de la carpeta pública, así una dirección mal escrita no puede pedir un archivo de código.

Resumen

  • Separar responsabilidades evita el archivo que hace todo y no se puede tocar.
  • Modelo = datos y reglas; Vista = presentación; Controlador = coordina.
  • La vista no consulta la base; el modelo no imprime HTML.
  • Un ruteador decide qué controlador atiende cada dirección.
  • Un punto de entrada único centraliza configuración y seguridad.
  • Solo public/ se expone; el código queda afuera.

En la próxima lección, lo que protege el sistema: permisos por rol, contraseñas, inyección SQL, XSS y CSRF.

Autoevaluación de la lección 7

Licencia. El material de esta página es elaboración propia de Prof Mauro Bobyk —a partir de las fuentes que detalla el pie del sitio— y se publica bajo una licencia Creative Commons BY-NC-SA 4.0.