How to make a custom command in Laravel

How To Make A Custom Command In Laravel

Hi guys,

We’ll look at How to Make a Custom Command In Laravel. With the help of Artisan, we can increase the speed to make laravel applications. Laravel uses a tinker package for a command-line interface. We can customize the output of our command.

Artisan is the command-line interface included with laravel. It will help you to build the laravel application. To check the all artisan commands, you can run the below command:

php artisan list

You can find a description of a particular command. You need to add the ‘help’ keyword before the actual command.

php artisan help migrate

Tinker:-

By default, Laravel includes the Tinker package. It is a powerful REPL for the laravel framework. you can also install the manual package using Composer:

composer require laravel/tinker

Tinker allows you to interact with your entire laravel application on the command line. To enter the Tinker environment, run the tinker command.

php artisan tinker

You can publish Tinker’s configuration file using the ‘vendor:publish’ command.

php artisan vendor:publish --provider="Laravel\Tinker\TinkerServiceProvider"

You can add commands to execute on its shell. We may add them inside the command array in your tinker.php configuration file.

'commands' => [
       // App\Console\Commands\ExampleCommand::class,
],

Tinker makes aliases classes automatically as you require them. You add classes in the dont_alias array of your tinker.php configuration file.

'dont_alias' => [
    App\User::class,
],

Writing commands:-

You can create a custom command for your application. It will be stored inside the app/console/commands directory.

Generating command:

You make a new custom command using the make:command Artisan command. It will create a command class in the app/console/commands directory.

php artisan make:command SendEmails

Command structure:

After executing the above command, you will see the signature and description properties of the class. The handle method will execute when your command executes. You can inject any dependencies as we need. The Laravel service container will automatically inject all dependencies that are type-hinted in this method’s signature:

<?php
namespace App\Console\Commands;

use App\DripEmailer;
use App\User;
use Illuminate\Console\Command;

class SendEmails extends Command
{
  /**
   * The name and signature of the console command.
   *
   * @var string
   */
   protected $signature = 'email:send {user}';
  
   /**
    * The console command description.
    *
    * @var string
    */
   protected $description = 'Send drip e-mails to a user';

  /**
   * Create a new command instance.
   *
   * @return void
   */
  public function __construct()
  {
      parent::__construct();
  }

  /**
   * Execute the console command.
   *
   * @param  \App\DripEmailer  $drip
   * @return mixed
   */
  public function handle(DripEmailer $drip)
  {
      $drip->send(User::find($this->argument('user')));
  }
}

Closure Commands:

Closure-based commands provide an alternative to defining console commands as classes. Laravel loads the routes/console.php file.

/**
 *  Register the Closure-based commands for the application.
 *
 * @return void
 */
protected function commands()
{
   require base_path('routes/console.php');
}

You may define all closure-based routes using the Artisan::command method.

Artisan::command('build {project}', function ($project) {
    $this->info("Building {$project}!");
});

Closures may also type-hint additional dependencies that you would like resolved out of the service container.

use App\DripEmailer;
use App\User;

Artisan::command('email:send {user}', function (DripEmailer $drip, $user) {
     $drip->send(User::find($user));
});

You may use the describe method to add a description to the command.

Artisan::command('build {project}', function ($project) {
        $this->info("Building {$project}!");
})->describe('Build the project');

Defining Input Expectations:-

You can specify the input you expect from the user using a signature property on your command.

Argument:

We wrapped all arguments in curly braces, and made arguments optional, and defined default values for the parameters.

/**
 * The name and signature of the console command.
 *
 * @var string
 */
 protected $signature = 'email:send {user}';

// Optional argument…
email:send {user?}

// Optional argument with default value…
email:send {user=foo}

Options:

Two hyphen prefix options(–) are added when they are defined in the command line. Options that don’t receive a value serve as a boolean ‘switch’.

/**
 * The name and signature of the console command.
 *
 @var string
*/
protected $signature = 'email:send {user} {--queue}';

If the –queue option passes to the command, the value will be true Otherwise, the value will be false:

php artisan email:send 1 --queue

You can also pass value to options.

/**
 * The name and signature of the console command.
 *
 * @var string
 */

protected $signature = 'email:send {user} {--queue=}';

You may assign default values to options by specifying the default value.

php artisan email:send 1 --queue=default

email:send {user} {--queue=default}

You can define a shortcut before the option name and use | delimiter to separate.

email:send {user} {--Q|queue}

Input Array:

You want to pass the array input to the command. You may use * character.

email:send {user*}
php artisan email:send foo bar

When defining that expects an array, we should prefix input each option value passed to the command with the option name:

email:send {user} {--id=*}

php artisan email:send --id=1 --id=2

Command I/O:-

Retrieving Input:

You need to access the values for arguments and options accepted by your command.

/**
 * Execute the console command.
 *
 * @return mixed
 */
public function handle()
{
   $userId = $this->argument('user'); //
}

To get all the arguments, call the arguments method:

$arguments = $this->arguments();

You can retrieve options using the option method. To retrieve all options as an array call options method.

// Retrieve a specific option…
$queueName = $this->option('queue');

// Retrieve all options…
$options = $this->options();

Prompting For input:

You may ask the user for the execution of your command. The ask method will prompt the user with a question.

/**
 * Execute the console command.
 *
 * @return mixed
 */
public function handle()
{
  $name = $this->ask('What is your name?');
}

Users’ input will not be visible when they type on the console.

$password = $this->secret('What is the password?');

You want to get confirmation from the user. You may use the confirm() method.

if ($this->confirm('Do you wish to continue?')) {
   //
}

The anticipate method allows you to auto-complete for possible choices.

$name = $this->anticipate('What is your name?', ['Taylor', 'Dayle']);

You can add Closure as a second argument to the anticipate() method. The Closure should accept a string parameter containing the user’s input so far and return an array of options for auto-completion:

$name = $this->anticipate('What is your name?', function ($input) {
     // Return auto-completion options…
});

If you need to give the user a predefined set of choices, you may use the choice method.

$name = $this->choice('What is your name?', ['Taylor', 'Dayle'], $defaultIndex);

You can also pass a fourth and fifth parameter to the choice method, which determines the maximum number of attempts to select a valid response, and multiple selections are permitted.

$name = $this->choice(
   'What is your name?',
   ['Taylor', 'Dayle'],
   $defaultIndex,
   $maxAttempts = null,
   $allowMultipleSelections = false
);

writing output:

You can write the output on the console using line, info, comment, question, and error methods. Each method uses ANSI colors for its purpose.

/**
 * Execute the console command.
 *
 * @return mixed
 */
public function handle()
{
   $this->info('Display this on the screen');
}

Also, you can make the table method. It dynamically calculated the width and height based on data. You should pass the header and rows.

$headers = ['Name', 'Email'];

$users = App\User::all(['name', 'email'])->toArray();

$this->table($headers, $users);

It is helpful to show the progress bar for the long-running task. We can use the start, advance, and stop methods to show a progress bar.

$users = App\User::all();

$bar = $this->output->createProgressBar(count($users));

$bar->start();

foreach ($users as $user) {
   $this->performTask($user);
   $bar->advance();
}

$bar->finish();

Registering Custom Command In Laravel:-

It automatically registers all commands with an artisan from the app/console/commands directory. You may be additional calls to the load method to scan another directory.

/**
 * Register the commands for the application.
 *
 * @return void
 */
protected function commands()
{
     $this->load(DIR.'/Commands');   
     $this->load(DIR.'/MoreCommands'); // …
}

You may manually register commands by adding their class name to the $commands property of the app/console/kernel.php file. It will automatically resolve when the artisan boots.

protected $commands = [
     Commands\SendEmails::class
];

Programmatically Executing commands:-

You may fire an Artisan command from the controller. You may use the call method on the Artisan facade. Command name or class as the first argument and an array of command parameters as the second argument. You can also pass the direct artisan command to the call method.

Route::get('/foo', function () {
   $exitCode = Artisan::call('email:send', [
       'user' => 1, '--queue' => 'default'
   ]);
 //
});

Artisan::call('email:send 1 --queue=default');

You may even queue Artisan commands, so your queue worker processes them in the background.

Route::get('/foo', function () {
    Artisan::queue('email:send', [
         'user' => 1, '--queue' => 'default'
    ]);
  //
]);

Artisan::queue('email:send', [
   'user' => 1, '--queue' => 'default'
])->onConnection('redis')->onQueue('commands');

Calling commands from other commands:

The call method accepts the command name and an array of parameters.

/**
 * Execute the console command.
 *
 * @return mixed
 */
public function handle()
{
    $this->call('email:send', [
        'user' => 1, '--queue' => 'default'
    ]); //
}

You want to call another console command and suppress its output. You can use the callSilent() method.

$this->callSilent('email:send', [
    'user' => 1, '--queue' => 'default'
]);

Stub Customization:-

They generate these classes using “stub” files that populate with values based on your input. You may sometimes wish to change files generated by the Artisan. Execute the below command to make stubs for customization.

php artisan stub:publish

The published stubs will be within a stubs directory in the root directory. It will reflect any changes you make to these stubs when you generate their corresponding classes using Artisan make commands.

I hope that this post (How to Make a Custom Command In Laravel) has helped you understand customize the output of a command, Register a command, and Programmatically execute commands. I used this site to write this post. Please leave a remark if you have any queries, and I will answer as quickly as possible.

Thank you for reading this article. Please share this article. That’s it for the day. Stay Connected!
Cheers,

Name
Email
The form has been submitted successfully!
There has been some error while submitting the form. Please verify all form fields again.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top