🎃 12 meses por 75 €

El plan anual a mitad de precio hasta el 31 de octubre.

Aprovechar la oferta

🎃 Halloween: 12 meses por 75 €

Plan anual a mitad de precio, para altas y renovaciones. Solo hasta el 31 de octubre.
Aprovechar la oferta
Saltar al contenido
Curso Actualizar un proyecto de Laravel 10 a Laravel 11
13/13 La estructura nueva de Laravel 11 Migrar a la estructura de Laravel 11: routes/console.php, configuración y cierre
Tu lectura Quedan 16 min
Lección 13 de 13 · La estructura nueva de Laravel 11

Migrar a la estructura de Laravel 11: routes/console.php, configuración y cierre

16 min de lectura Laravel 11

Hola, bienvenido. En esta última lección vamos a terminar la migración a la estructura de Laravel 11 y, con ella, el curso. En Laravel 11, las tareas programadas se definen en routes/console.php con la fachada Schedule, y los comandos de app/Console/Commands se registran solos, así que app/Console/Kernel.php sobra. Lo vamos a mover y a borrar, junto con la línea provisional que dejamos en bootstrap/app.php en la lección 11, y después vamos a repasar la configuración: el array providers de config/app.php, los archivos de config/ y el .env.example.

Es la lección con menos código de la sección, pero tiene una decisión importante, que es qué no cambiar: nuestros archivos de config/ y nuestro .env.example no son los de un proyecto nuevo de Laravel 11, y vamos a ver por qué en un proyecto que ya existe es mejor dejarlos como están.

La tarea programada, en routes/console.php

Nuestro Kernel de consola hace 2 cosas. En schedule() programa el comando tickets:close-stale cada hora, y en commands() carga los comandos de app/Console/Commands y el archivo routes/console.php. En Laravel 11, las 2 tienen otro sitio:

En app/Console/Kernel.php En Laravel 11
$schedule->command('tickets:close-stale')->hourly() en schedule() Schedule::command('tickets:close-stale')->hourly() en routes/console.php
$this->load(__DIR__.'/Commands') en commands() Lo hace Application::configure(), que registra los comandos de app/Console/Commands
require base_path('routes/console.php') en commands() El parámetro commands de withRouting()

La fachada Schedule es lo que permite definir las tareas en routes/console.php, sin una clase que las agrupe, y tiene los mismos métodos que el objeto $schedule que recibía el Kernel. Por eso el cambio es casi literal. Vamos a añadir la tarea al final de routes/console.php, con su use:

routes/console.php Modificado +3
1<?php
2
3use Illuminate\Foundation\Inspiring;
4use Illuminate\Support\Facades\Artisan;
+use Illuminate\Support\Facades\Schedule;
6
7/*
8|--------------------------------------------------------------------------
18Artisan::command('inspire', function () {
19 $this->comment(Inspiring::quote());
20})->purpose('Display an inspiring quote');
+
+Schedule::command('tickets:close-stale')->hourly();

Si prefieres que routes/console.php tenga solo comandos, la documentación de Laravel 11 ofrece una alternativa, withSchedule() en bootstrap/app.php, que recibe una función con el mismo objeto $schedule del Kernel. Aquí seguimos el esqueleto, que deja las tareas en routes/console.php.

Ahora, bootstrap/app.php. Vamos a quitar la línea que en la lección 11 registraba nuestro Kernel de consola, y con ella la variable $app, y a añadir commands a withRouting() para que Laravel cargue routes/console.php, que hasta ahora cargaba el Kernel:

bootstrap/app.php Modificado +2 −7
1<?php
2
−use App\Console\Kernel as ConsoleKernel;
3use App\Exceptions\TicketAlreadyClosedException;
−use Illuminate\Contracts\Console\Kernel as ConsoleKernelContract;
4use Illuminate\Foundation\Application;
5use Illuminate\Foundation\Configuration\Exceptions;
6use Illuminate\Foundation\Configuration\Middleware;
9use Spatie\Permission\Middleware\RoleMiddleware;
10use Spatie\Permission\Middleware\RoleOrPermissionMiddleware;
11
−$app = Application::configure(basePath: dirname(__DIR__))
+return Application::configure(basePath: dirname(__DIR__))
13 ->withRouting(
14 web: __DIR__.'/../routes/web.php',
15 api: __DIR__.'/../routes/api.php',
+ commands: __DIR__.'/../routes/console.php',
17 health: '/up',
18 )
19 ->withMiddleware(function (Middleware $middleware) {
41 });
42 })
43 ->create();
−
−$app->singleton(ConsoleKernelContract::class, ConsoleKernel::class);
−
−return $app;

Ya es el bootstrap/app.php de un proyecto de Laravel 11, con lo propio del nuestro en cada sección. Y como nadie usa ya app/Console/Kernel.php, vamos a borrarlo:

Terminal
git rm app/Console/Kernel.php
Salida
rm 'app/Console/Kernel.php'
Borramos app/Console/Kernel.php

Vamos a comprobar que la tarea sigue programada y que el comando sigue registrado:

Terminal
sail artisan schedule:list
sail artisan list tickets
Salida
0 * * * * php artisan tickets:close-stale ... Next Due: 14 minutes from now ... Available commands for the "tickets" namespace: tickets:close-stale Cierra los tickets que llevan días esperando una respuesta del cliente

Y el test que lo vigila, CloseStaleTicketsTest, que comprueba que el comando cierra los tickets y que está programado cada hora:

Terminal
sail test tests/Feature/Console
Salida
PASS Tests\Feature\Console\CloseStaleTicketsTest ✓ tickets waiting for the customer for a week are closed 1.43s ✓ the command runs every hour 0.04s Tests: 2 passed (8 assertions) Duration: 1.51s

En producción no cambia nada: el cron sigue lanzando php artisan schedule:run cada minuto, y Laravel encuentra la tarea en su sitio nuevo.

Lo que queda de esta lección
  1. 02El array providers de config/app.php
  2. 03Los archivos de config/ y config:publish
  3. 04El .env.example
  4. 05composer qa y el tag laravel-11
  5. 06Lo que hemos hecho y lo que queda
Sigue leyendo con tu suscripción El curso completo, con el certificado y el foro, está incluido en la suscripción. Ver los planes