Artisan command line
- Introduction
- Writing Command
- Define input expectations
- I/O command
- Register command
- Execute commands programmatically
list command:
php artisan listEach 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 migrateTinker 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 tinkerYou 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' ]);