Skip to content

Estructura del proyecto ​

Un proyecto Laravel recién creado tiene muchas carpetas y archivos. En esta lección aprenderás qué hay en cada una, cuáles vas a tocar todos los días y cuáles casi nunca. También conocerás artisan, el archivo .env y bootstrap/app.php, el corazón de la configuración en Laravel 11/12.

Concepto ​

Piensa en el proyecto como un restaurante:

  • public/ es la puerta principal: lo único a lo que entran los clientes.
  • routes/ es el mesero que recibe el pedido y lo lleva a la cocina correcta.
  • app/ es la cocina: donde se prepara todo (controladores, modelos, lógica).
  • resources/views/ es el emplatado: cómo se presenta el platillo (HTML).
  • database/ es la despensa: estructura y datos iniciales.
  • config/ y .env son el manual de operaciones del restaurante.
  • storage/ es la bodega: archivos subidos, logs, caché.
  • vendor/ son los proveedores: código de terceros que no tocas.

El mapa completo ​

txt
mi-app/
├── app/
│   ├── Http/
│   │   └── Controllers/        ← tus controladores
│   ├── Models/                 ← tus modelos Eloquent (User.php ya existe)
│   └── Providers/
│       └── AppServiceProvider.php  ← configuración al arrancar la app
├── bootstrap/
│   ├── app.php                 ← configura rutas, middleware y excepciones
│   └── providers.php           ← lista de service providers
├── config/                     ← archivos de configuración (app, database, mail...)
├── database/
│   ├── factories/              ← generadores de datos falsos
│   ├── migrations/             ← "control de versiones" de tus tablas
│   ├── seeders/                ← datos iniciales
│   └── database.sqlite         ← la BD si usas SQLite
├── public/
│   ├── index.php               ← punto de entrada de TODAS las peticiones
│   └── build/                  ← CSS/JS compilados por Vite (npm run build)
├── resources/
│   ├── css/app.css
│   ├── js/app.js
│   └── views/                  ← plantillas Blade (.blade.php)
├── routes/
│   ├── web.php                 ← rutas de páginas web
│   └── console.php             ← comandos y tareas programadas
├── storage/
│   ├── app/                    ← archivos subidos (public/ y private/)
│   ├── framework/              ← caché, sesiones, vistas compiladas
│   └── logs/laravel.log        ← ¡aquí ves los errores!
├── tests/                      ← pruebas automáticas
├── vendor/                     ← dependencias de Composer (NO se edita ni se sube a Git)
├── .env                        ← variables de entorno (NO se sube a Git)
├── .env.example                ← plantilla del .env (SÍ se sube)
├── artisan                     ← la consola de Laravel
├── composer.json               ← dependencias de PHP
├── package.json                ← dependencias de JS
└── vite.config.js              ← configuración de Vite

¿Dónde está routes/api.php?

En Laravel 11/12 no viene por defecto. Se crea cuando lo necesitas con php artisan install:api (lo verás en APIs con Sanctum). Lo mismo pasa con routes/channels.php (php artisan install:broadcasting).

El archivo .env ​

Contiene la configuración que cambia según el entorno (tu PC, el servidor de pruebas, producción) y los secretos (contraseñas, claves de API).

env
APP_NAME="Mi App"
APP_ENV=local            # local | production
APP_KEY=base64:xxxxxxxx  # clave de cifrado (php artisan key:generate)
APP_DEBUG=true           # true en local, SIEMPRE false en producción
APP_URL=http://mi-app.test

APP_LOCALE=es            # idioma por defecto
APP_FALLBACK_LOCALE=en

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=mi_app
DB_USERNAME=root
DB_PASSWORD=

SESSION_DRIVER=database
QUEUE_CONNECTION=database
CACHE_STORE=database

MAIL_MAILER=log          # en local, los correos se escriben en el log

Los archivos de config/ leen esas variables con env(). Por ejemplo, config/app.php:

php
<?php

return [
    // Si APP_NAME no existe en .env, usa 'Laravel'
    'name' => env('APP_NAME', 'Laravel'),
    'debug' => (bool) env('APP_DEBUG', false),
    // ...
];

Y en tu código usas config(), nunca env() directamente:

php
// ✅ Correcto: lee la configuración (funciona con la caché de config)
$nombre = config('app.name');

// ❌ Incorrecto fuera de config/: con "php artisan config:cache" devuelve null
$nombre = env('APP_NAME');

Nunca subas el .env a Git

El .env tiene contraseñas de la base de datos, claves de correo y de pasarelas de pago. Laravel ya lo incluye en .gitignore; no lo quites. Revisa la lección de gestión de secretos.

bootstrap/app.php: el centro de control ​

En versiones anteriores la configuración estaba repartida en Kernel.php, RouteServiceProvider.php y Handler.php. Desde Laravel 11 todo vive aquí:

php
<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    // 1. Qué archivos de rutas se cargan
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',               // ruta de "salud" para monitoreo
    )
    // 2. Registro y configuración de middleware
    ->withMiddleware(function (Middleware $middleware) {
        // Aquí agregarás alias de middleware, por ejemplo:
        // $middleware->alias(['admin' => \App\Http\Middleware\EsAdmin::class]);
    })
    // 3. Cómo se reportan y muestran los errores
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

Volverás a este archivo en las lecciones de middleware y APIs.

Artisan: tu asistente en la terminal ​

artisan es un script PHP que genera código y ejecuta tareas. Comandos que usarás a diario:

powershell
php artisan list                         # ver todos los comandos
php artisan help make:model              # ayuda de un comando

# Generadores (make:*)
php artisan make:controller ProductoController
php artisan make:model Producto -mfs     # modelo + migración + factory + seeder
php artisan make:request GuardarProductoRequest
php artisan make:middleware EsAdmin
php artisan make:policy ProductoPolicy --model=Producto

# Base de datos
php artisan migrate                      # ejecuta migraciones pendientes
php artisan migrate:fresh --seed         # borra todo, migra y siembra (solo en local)
php artisan db:seed

# Utilidades
php artisan route:list                   # ver todas las rutas registradas
php artisan tinker                       # consola interactiva con tu app cargada
php artisan optimize:clear               # limpia todas las cachés
php artisan storage:link                 # enlace público a storage/app/public

Tinker: experimenta sin crear rutas ​

powershell
php artisan tinker
php
> App\Models\User::count();
= 0
> config('app.name');
= "Mi App"
> now()->format('d/m/Y');
= "18/10/2026"
> exit

Archivos que tocarás (y los que no) ​

Tocas a diarioTocas a vecesNo tocas
routes/web.phpbootstrap/app.phpvendor/
app/Http/Controllers/config/*.phpstorage/framework/
app/Models/app/Providers/AppServiceProvider.phppublic/index.php
resources/views/.envbootstrap/cache/
database/migrations/composer.json, package.jsonpublic/build/ (lo genera Vite)

Buena práctica

Cuando algo falle y la pantalla no diga mucho, abre storage/logs/laravel.log. Ahí Laravel guarda el error completo con el archivo y la línea exacta. Es el primer lugar donde mirar, sobre todo en producción.

Error común

"The stream or file storage/logs/laravel.log could not be opened: Permission denied" en servidores Linux. Laravel necesita escribir en storage/ y bootstrap/cache/. Solución en el servidor:

bash
sudo chown -R www-data:www-data storage bootstrap/cache
sudo chmod -R 775 storage bootstrap/cache

Error común

Cambias el .env y "no pasa nada". Probablemente la configuración está cacheada. Ejecuta php artisan config:clear (o optimize:clear).

Ejercicios ​

  1. Abre tu proyecto y localiza: el archivo de rutas web, el modelo User, la vista de bienvenida y el archivo de log.
  2. Cambia APP_NAME en .env a "Mi Primera App" y crea una ruta /nombre que muestre ese valor usando config().
  3. Usa php artisan route:list y anota cuántas rutas tiene tu proyecto y cuál es la ruta /up.
  4. Con Tinker, crea un usuario y cuéntalos.
Ver solución
  1. Ubicaciones:
txt
routes/web.php
app/Models/User.php
resources/views/welcome.blade.php
storage/logs/laravel.log
  1. En .env:
env
APP_NAME="Mi Primera App"

En routes/web.php:

php
Route::get('/nombre', function () {
    return 'Esta app se llama: ' . config('app.name');
});

Si no ves el cambio, ejecuta php artisan config:clear.

  1. php artisan route:list muestra algo como:
txt
  GET|HEAD  / ........................................
  GET|HEAD  nombre ...................................
  GET|HEAD  up .......................................
  GET|HEAD  storage/{path} ........... storage.local

/up es la ruta de salud configurada en bootstrap/app.php (health: '/up'): devuelve 200 si la app funciona, útil para servicios de monitoreo.

  1. En Tinker:
php
> App\Models\User::create(['name' => 'Ana', 'email' => 'ana@correo.com', 'password' => 'secreto123']);
> App\Models\User::count();
= 1

(El modelo User aplica hash a la contraseña automáticamente gracias al cast 'password' => 'hashed'.)

Resumen ​

  • app/ tiene tu lógica (controladores y modelos); resources/views/ tus plantillas; routes/web.php tus rutas.
  • public/ es lo único accesible desde internet; vendor/ y .env nunca se suben a Git.
  • .env guarda configuración por entorno y secretos; en tu código usa config(), no env().
  • bootstrap/app.php centraliza rutas, middleware y manejo de excepciones en Laravel 11/12.
  • php artisan genera código (make:*), migra la BD, lista rutas y abre Tinker.
  • Los errores se registran en storage/logs/laravel.log.

Academia Web — aprende, copia y construye.