Customizing The Laravel Artisan Application

December 7, 2016 —John Koster

While it is simple to create custom Artisan commands there are other times where it may be necessary to customize the core console application further. The Artisan console application (Illuminate\Console\Application) extends Symfony's console application (Symfony\Component\Console\Application); this means that the same modifications that can be made to Symfony's console application should also apply to the Artisan console application. Such modifications include changing the default command, application name and application versions string.

Since we know that Laravel's console application extends Symfony's, we need to discover where exactly this is being brought in and invoked. Looking at the App\Console\Kernel (the kernel that is available to "user-land" code for registering commands and scheduling commands) we can see that it extends a framework console kernel located at Illuminate\Foundation\Console\Kernel. Performing a quick string search within the Kernel file for Illuminate\Console\Application reveals that an instance of the console application is set and returned by the getArtisan protected method. Since the method is marked as protected any inherited classes can call or override the method if they want (see the Visibility section in the PHP manual for more information related to method visibility).

It is by overriding this method that we are able to make customizations to the actual console application instance. However, we need to make sure that our modified version of getArtisan sets the $artisan instance property as well as returns the application instance.

Here is what a Kernel class might look like with the modified getArtisan method:

1<?php
2 
3namespace App\Console;
4 
5use Illuminate\Console\Scheduling\Schedule;
6use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
7 
8class Kernel extends ConsoleKernel
9{
10 
11 /**
12 * The Artisan commands provided by your application.
13 *
14 * @var array
15 */
16 protected $commands = [
17 // Commands\Inspire::class,
18 Commands\TestCommand::class
19 ];
20 
21 /**
22 * Define the application's command schedule.
23 *
24 * @param \Illuminate\Console\Scheduling\Schedule $schedule
25 * @return void
26 */
27 protected function schedule(Schedule $schedule)
28 {
29 // $schedule->command('inspire')
30 // ->hourly();
31 }
32 
33 /**
34 * Register the Closure based commands for the application.
35 *
36 * @return void
37 */
38 protected function commands()
39 {
40 // $this->command('build {project}', function ($project) {
41 // $this->info('Building project...');
42 // });
43 }
44 
45 protected function getArtisan()
46 {
47 // Check if the artisan property is null; If so
48 // we need to instantiate it by calling the
49 // getArtisan method on the base class;
50 // after this we can make any of the
51 // modifications we want before we
52 // return the app instance back.
53 if (is_null($this->artisan)) {
54 $this->artisan = parent::getArtisan();
55 
56 // Make our modifications here.
57 
58 // Rename the console application.
59 $this->artisan->setName('Laravel Artisan');
60 
61 // Change the version number.
62 $this->artisan->setVersion('1.0.0');
63 
64 }
65 
66 return $this->artisan;
67 }
68 
69}

Now, when a user invokes php artisan in the shell they would see the following output (take note of the application name and version number on the first line):

1Laravel Artisan version 1.0.0
2
3Usage:
4 command [options] [arguments]
5
6...

It is also possible to easily modify the default command that is executed when the artisan console application is invoked without specifying a command. By default the list command is executed and will list all of the registered commands. However, this can be changed within our modified getArtisan method:

1<?php
2 
3// ...
4 
5function getArtisan()
6{
7 if (is_null($this->artisan)) {
8 $this->artisan = parent::getArtisan();
9 
10 // Change the default command.
11 $this->artisan->setDefaultCommand('route:list');
12 }
13 
14 return $this->artisan;
15}
16 
17// ...

With the above modification when a user types php artisan in their shell and hits the enter key on a fresh Laravel installation they would see the following routes table instead of the command listing:

1+--------+----------+-----+------+---------+------------+
2| Domain | Method | URI | Name | Action | Middleware |
3+--------+----------+-----+------+---------+------------+
4| | GET|HEAD | / | | Closure | web |
5+--------+----------+-----+------+---------+------------+

These modifications can be useful when developing for clients that require custom branding throughout all areas of an application.

Some absolutely amazing
people

The following amazing people help support this site and my open source projects ♥️
If you're interesting in supporting my work and want to show up on this list, check out my GitHub Sponsors Profile.