Defining console commands via closure in Laravel 5.3

Posted on January 30, 2017 | By Matt Stauffer

Before Laravel 5.3, defining an Artisan console command—something like php artisan sync:dates—required you to create a new class for that command and register it in the Console Kernel. This is fine, but sometimes it feels like overkill for what might end up just being a single line of functional code.

As of Laravel 5.3, you'll notice that there's a new method in the Console/Kernel.php file named commands(), and it loads a new file at routes/console.php. This new "console routes" file allows us to define Artisan console commands with a single Closure instead the prior "define a class then register it in the console Kernel" flow. Much faster, much easier.

So, open up routes/console.php and you'll already see a sample command:

Artisan::command('inspire', function () {
})->describe('Display an inspiring quote');

As you can see, we have a new fluent builder for defining Artisan commands. We've got the signature ("inspire"), the handle() (the closure), and the description ("Display an inspiring quote").

What if we have a parameter, or if we want to inject a dependency? It works just like it did with the old syntax.

Artisan::command('sync:conference {id}', function (JoindIn $joindin) {
})->describe('Sync a given conference from JoindIn');

But here's something else interesting you can do that you can't with traditional Artisan command definition: you can take your signature arguments as parameters in the Closure, which is much more like what you'd expect if you were new to Laravel:

Artisan::command('sync:conference {id}', function ($id, JoindIn $joindin) {
})->describe('Sync a given conference from JoindIn');

As you can see, we now have a simpler, more convenient, more fluent, and more compact way to define Artisan commands. Boom.

Comments? I'm @stauffermatt on Twitter

Tags: laravel  •  laravel 5.3  •  artisan