Artisan command line


##Artisan Command Line

  • Introduction
    • Tinker Command (REPL)
  • Writing Command
    • Generate command
    • Command structure
    • Closure command
  • Define input expectations
    • Parameters
    • Options
    • Input array
    • Input description
  • I/O command
    • Retrieval input
    • Interactive input
    • Writing output
  • Register command
  • Execute commands programmatically
    • Call commands from other commands

Introduction

Artisan is Laravel's own command line interface. It provides many commands to help you build Laravel applications. To see a list of all available Artisan commands, use the

list command:

php artisan list

Each command includes a Help interface that displays and summarizes the available parameters and options for the command . Just add

help before the command to view the command help interface:

php artisan help migrate

Tinker command (REPL )

All Laravel applications include Tinker, a REPL based on the

PsySH package. Tinker lets you interact with your entire Laravel application from the command line. Includes Eloquent ORM, tasks, events, and more. Run the Artisan command tinker to enter the Tinker environment:

php artisan tinker

You can publish the Tinker configuration file by using the

vendor:publish command:

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

Command whitelist

Tinker uses a whitelist to determine which Artisan commands are allowed to run in the shell. By default, you can run clear-compiled, down, env, inspire, migrate, optimize, and up commands. If you want to add more whitelist commands, you can add them to the commands array in the tinker.php configuration file:

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

Blacklist Aliases

Normally, Tinker will automatically add aliases to classes in Tinker based on your needs. However, you may not want to add aliases to some classes. You can do this by enumerating these classes in the dont_alias array in the tinker.php configuration file:

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

Writing commands

In addition to the commands provided by Artisan, you can also build your own custom commands. Commands are typically stored in the app/Console/Commands directory; however, as long as your commands can be loaded by Composer, you are free to choose your own storage location.

Generate command

To create a new command, use the Artisan commandmake:command. This command will create a new command class in the app/Console/Commands directory. Don't worry about this directory not existing in your application, as it will be created the first time you run the Artisan command make:command. The generated command will include the properties and methods that exist by default in all commands:

php artisan make:command SendEmails

Command structure

Command run Finally, you should first fill in the signature and description attributes so that you can clearly understand the usage when entering php artisan list. The handle method will be called when executing the command. You can place the command logic in this method.

{tip} For better code reuse, it is best to keep your console code lightweight and defer completion to the application service. In the following example, we will inject a service class to complete the task of sending emails.

Let’s look at a simple example. We can inject any dependencies we need in the handle method. The Laravel service container will automatically inject all dependencies with type constraints in the constructor:

<?php
    namespace App\Console\Commands;
    use App\User;use App\DripEmailer;
    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 a way to use classes instead of defining console commands. In the same way, closure routing is an alternative to controllers, and closure commands can be thought of as an alternative to command classes. In the commands method of the app/Console/Kernel.php file, 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');
 }

Although This file does not define HTTP routes, but it does define console-based entry points (routes) into the application. In this file, you can define all closure routes using the Artisan::command method. command The method accepts two parameters: Command name and a closure that accepts command parameters and options:

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

The closure binds the underlying command instance, because you All helper methods available in the full command class are accessible.

Type-hinted dependencies

In addition to receiving command parameters and options, the command closure can also use type hints to resolve other dependencies from the service container:

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

Closure command description

When you define a closure command, you should use the describe method to add a description to the command. This description will be displayed when you run the php artisan list or php artisan help command:

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

Define output expectations

When writing console commands, user input is usually collected through parameters and options. Laravel can easily define what you expect the user to input through the signature attribute. signature Allows the definition of command names, parameters, and options using a single and highly readable, route-like syntax.

Parameters

All user-supplied parameters and options are enclosed in curly braces. In the following example, this command defines a required parameter: user:

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

You can also create optional parameters and define default values ​​for the parameters. :

// 可选参数...
email:send {user?}
// 带有默认值的可选参数...
email:send {user=foo}

Options

Options, similar to parameters, are another format for user input. When options are specified on the command line, they are prefixed with two hyphens ( -- ). There are two types of options: receiving a value and not receiving a value. An option that doesn't accept a value is like a boolean "switch". Let's look at an example of this type of option:

/**
 * 命令行的名称及签名。
 *
 * @var string
 */
 protected $signature = 'email:send {user} {--queue}';

In this example, the --queue switch can be specified when calling the Artisan command. If the --queue switch is passed, the value of this option is true, otherwise false:

php artisan email:send 1 --queue

Options with value

Next, let’s look at an option with value. If you want the user to have to specify a value for an option, you need to append an equal sign = to the end of the option name as the suffix:

/**
 * 命令行的名称及签名。
 *
 * @var string
 */
 protected $signature = 'email:send {user} {--queue=}';

In this example, the user can pass the option's value, as follows:

php artisan email:send 1 --queue=default

You can also set the default value for an option by specifying the default value after the option name. If the user does not pass an option value, the set default value will be used:

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

The option abbreviation

is to be To specify an abbreviation when defining an option, you can specify it before the option name and separate the abbreviation from the full option name with the | delimiter:

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

Input array

If you want to define parameters or options that receive array input, you can use the * notation. First, let's look at an example of an array parameter:

email:send {user*}

When calling this method, the input parameters of the user parameter can be passed to the command line in order. For example, the following command will set the value of user to ['foo', 'bar']:

php artisan email:send foo bar

When defining options that receive an array, each option value passed to the command line should be prefixed with the option name:

email:send {user} {--id=*}
php artisan email:send --id=1 --id=2

Enter description

You can specify parameters and Option to add descriptions and make them separate. If you need a little extra space to define your command, feel free to spread it out on multiple lines:

/**
 * 命令行的名称及签名。
 *
 * @var string
 */
 protected $signature = 'email:send
                 {user : The ID of the user}
                 {--queue= : Whether the job should be queued}';

Command I/ O

Get input

When the command is executed, obviously you need to get the parameters and options received by the command value. You can use the argument and option methods to achieve the goal:

/**
 * 执行命令。
 *
 * @return mixed
 */
 public function handle(){
     $userId = $this->argument('user');    
     //
 }

If you want all parameters to be obtained as an array array, you can call arguments Method:

$arguments = $this->arguments();

Similar to getting parameters, the option method can easily get the value of the option. To get all options as an array, use the options method:

// 获取一个指定的选项值
$queueName = $this->option('queue');
// 获取所有的选项值
$options = $this->options();

If the parameter or option does not exist, null is returned.

Interactive input

In addition to displaying output, you can also ask the user to provide input while the command is executed. The ask method will prompt the user for input and receive it, and then the user's input will be passed into your command:

/**
 * 执行命令。
 *
 * @return mixed
 */
 public function handle(){
     $name = $this->ask('What is your name?');
 }

secret method and ask The method is similar, but when the user types in the console their input is invisible. This method is suitable when the user needs to enter sensitive information like a password:

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

Request confirmation

If you want to ask the user to confirm some simple information, you You can use the confirm method. By default, this method will return false. But if the user enters y or yes in the reply, true will be returned.

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

Autocomplete

anticipate method can be used to provide autocompletion for possible choices. The user can still ignore the auto-complete prompt and give any answer:

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

Multiple Choice

If you want to provide the user with some preset choices, you can use choice method. You can also set the index of the default value to deal with the situation where the user has no choice:

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

Writing Output

You can use the line, info, comment, question and error methods to send output to the terminal. Each method uses the appropriate ANSI color to indicate its purpose. For example, let us display some general information to the user. Generally speaking, it is best to use the info method, which will display the output in green on the console:

/**
 * 执行命令。
 *
 * @return mixed
 */
 public function handle(){
     $this->info('Display this on the screen');
 }

Display error message , use the error method. The error message will be displayed in red:

$this->error('Something went wrong!');

If you want to display the output without color settings on the console, please use the line method:

$this->line('Display this on the screen');

Table Layout

For formatted output of multi-row and row data, the table method is easier to handle. Based on the incoming table header and row data, it will dynamically calculate the width and height:

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

Progress bar

For time-consuming tasks, it is very necessary to prompt the progress. Use the output object to create, load, and stop progress bars. First, define the total number of steps of the task, and then load the progress bar every time the task is executed:

$users = App\User::all();
$bar = $this->output->createProgressBar(count($users));
$bar->start();foreach ($users as $user) { 
   $this->performTask($user);    
   $bar->advance();
}$bar->finish();

Refer to Symfony Progress Bar component documentation for more advanced usage.

Registering commands

app/Console/Commands The commands in the directory will be registered. This is because the commands method of the console kernel calls load. In fact, you can call load at will to scan Artisan commands in other directories:

/**
 * 注册应用的命令
 *
 * @return void
 */
 protected function commands(){ 
    $this->load(__DIR__.'/Commands');    
    $this->load(__DIR__.'/MoreCommands'); 
   // ...
}

You can also in the app/Console/Kernel.php file The class name of the manually registered command in the $commands attribute. When Artisan starts, the commands listed in this attribute will be parsed by the service container and registered with Artisan:

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

Program call command

Sometimes it is necessary to execute Artisan commands outside the CLI, for example, to trigger Artisan commands in a router or controller. To implement the call, you can use the call method of the Artisan facade. call The first parameter of the method accepts the command name, and the second parameter accepts the command parameters in the form of an array. The exit code will be returned:

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

Alternatively, you can pass the entire Artisan command as a string to the call method:

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

Artisan facade queue This method can queue Artisan commands and hand them over to the queue worker process for background processing. Before using this method, be sure to configure the queue and run the queue listener:

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

You can also specify the connection or task dispatched by the Artisan command:

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

Pass an array value

If an option that accepts an array is defined, you can pass the array directly to the option:

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

Passing a Boolean value

You need to specify no option value option, for example, the --force option of the migrate:refresh command, you can pass in true or false:

$exitCode = Artisan::call('migrate:refresh', [
    '--force' => true,
  ]);

Mutual calling of commands

call method can be used to call other Artisan commands. The call method accepts the command name and options in the form of an array:

/**
 * 执行控制台命令
 *
 * @return mixed
 */
 public function handle(){ 
    $this->call('email:send', [   
         'user' => 1, 
         '--queue' => 'default' 
      ]); 
      //
 }

If you want to suppress all output of the console command, you can use the callSilent method. The usage method of callSilent is the same as call:

$this->callSilent('email:send', [ 
   'user' => 1, 
   '--queue' => 'default'
 ]);
This article was first published on the LearnKu.com website.