Oh Dear is the all-in-one monitoring tool for your entire website. We monitor uptime, SSL certificates, broken links, scheduled tasks and more. You'll get a notifications for us when something's wrong. All that paired with a developer friendly API and kick-ass documentation. O, and you'll also be able to create a public status page under a minute. Start monitoring using our free trial now.

Improving Artisan commands

Original – by Freek Van der Herten – 3 minute read

In this small blog post, I'd like to give you a couple of tips to make your Artisan commands better.

Use the fully qualified class name to schedule commands

You probably know that you can schedule artisan commands in the console kernel like this.

// app/Console/Kernel.php

class Kernel extends ConsoleKernel
{
    protected function schedule(Schedule $schedule)
    {
        $schedule->command('email-campaigns:send-scheduled-campaigns')->everyMinute();
    }
}

Did you know that you could use the fully qualified name of a command too?

class Kernel extends ConsoleKernel
{
    protected function schedule(Schedule $schedule)
    {
        $schedule->command(SendScheduledEmailCampaigns::class)->everyMinute();
    }
}

Using the fully qualified class name has some nice benefits. Any decent IDE will allow you to click through a command. Also, when performing a name refactor on the command, decent IDEs will automatically change the name of the command everywhere, including in the kernel.

Make commands smaller

When you scaffold a command using make:command, the produced code is quite verbose. Here's an example:

class SendScheduledEmailCampaigns extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'email-campaigns:send-scheduled-campaigns';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }
    
    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        // do the work
    }
}

I like to make those commands as small as possible by removing any cruft that doesn't make the code clearer. Those comments are not necessary. Also, the $description is not mandatory, so you can lose that if the command name is already clear enough.

class SendScheduledEmailCampaigns extends Command
{
    protected $signature = 'email-campaigns:send-scheduled-campaigns';
    
    public function handle()
    {
        // do the work
    }
}

To me, this is more readable. We didn't lose any information by removing all those lines.

Use the handle method to inject dependencies

I sometimes see the constructor is used to inject dependencies.

class SendScheduledEmailCampaigns extends Command
{
    protected $signature = 'email-campaigns:send-scheduled-campaigns';
    
    /** @var MyDependency **/
    protected $myDependency;
    
    public function __construct(MyDependency $myDependency) 
    {
       $this->myDependency = $myDependency;
    }
    
    public function handle()
    {
        // do something with `$this->myDependency`
    }
}

This approach is not ideal. It was recently brought to my attention that the constructor of each registered command will get executed when artisan is invoked.

To inject dependencies is much better to use the handle method. Everything you specify there will be resolved out of the IoC container when your command executes.

class SendScheduledEmailCampaigns extends Command
{
    protected $signature = 'email-campaigns:send-scheduled-campaigns';
        
    public function handle(MyDependency $myDependency)
    {
        // do something with `$myDependency`
    }
}

Stay up to date with all things Laravel, PHP, and JavaScript.

You can follow me on these platforms:

On all these platforms, regularly share programming tips, and what I myself have learned in ongoing projects.

Every month I send out a newsletter containing lots of interesting stuff for the modern PHP developer.

Expect quick tips & tricks, interesting tutorials, opinions and packages. Because I work with Laravel every day there is an emphasis on that framework.

Rest assured that I will only use your email address to send you the newsletter and will not use it for any other purposes.

Comments

What are your thoughts on "Improving Artisan commands"?

Comments powered by Laravel Comments
Want to join the conversation? Log in or create an account to post a comment.