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 array15 */16 protected $commands = [17 // Commands\Inspire::class,18 Commands\TestCommand::class19 ];20 21 /**22 * Define the application's command schedule.23 *24 * @param \Illuminate\Console\Scheduling\Schedule $schedule25 * @return void26 */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 void37 */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 so48 // we need to instantiate it by calling the49 // getArtisan method on the base class;50 // after this we can make any of the51 // modifications we want before we52 // 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.023Usage:4 command [options] [arguments]56...
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.
∎
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.