Artisan 命令行
介绍
Artisan
是 Laravel 的命令行接口的名称, 它提供了许多实用的命令来帮助你开发 Laravel 应用, 要查看所有的 Artisan
命令列表,可以使用 list
命令:
php artisan list
每个命令也包含了「帮助」界面,它会显示并概述命令可使的参数及选项。只需要在命令前面加上 help
即可显示命令帮助界面:
php artisan help migrate
编写命令
除了 Artisan
提供的命令之外,还可以创建自定义命令。自定义命令默认存储在 app/Console/Commands
目录,当然,你也可以修改 composer.json
配置来指定你想要存放的目录。
生成命令
要创建一个新的命令,可以使用 make:command
命令。这个命令会创建一个命令类并存放在 app/Console/Commands
目录。 不必担心不存在这个目录,运行 make:command
命令时会首先创建这个目录。生成的命令将会包括所有默认存在的属性和方法:
php artisan make:command SendEmails
命令结构
命令生成以后,应先填写类的 signature
和 description
属性,之后可以在使用 list
命令是显示出来。执行命令是调用 handle
方法,可以把你的命令逻辑放到这个方法中。
大部分的代码复用,保持你的代码轻量并让它们延迟到应用服务中完成任务是个不错的实践。在下面这个例子中,我们注入了一个服务类去执行发送邮件的繁重任务。
让我们看这个简单的命令例子,Command
类构造器允许注入需要的依赖,Laravel 的服务容器 将会自动注入构造函数中所有带类型约束的依赖:
<?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';
/**
* The drip e-mail service.
*
* @var DripEmailer
*/
protected $drip;
/**
* Create a new command instance.
*
* @param DripEmailer $drip
* @return void
*/
public function __construct(DripEmailer $drip)
{
parent::__construct();
$this->drip = $drip;
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$this->drip->send(User::find($this->argument('user')));
}
}
闭包命令
闭包命令提供一个替代定义命令方法的类。同样的路由闭包是控制器的一种替代方法,这种命令闭包可以替换命令类。使用 app/Console/Kernel.php
文件的 commands
方法,需要 Laravel 在 routes/console.php
注册:
/**
* Register the Closure based commands for the application.
*
* @return void
*/
protected function commands()
{
require base_path('routes/console.php');
}
虽然这个文件没有定义 HTTP 路由,它定义了基于控制台的入口点(路由)到你的应用中,在这个文件中,你可以使用 Artisan::command
方法定义所有基于路由的闭包,command
方法接收两个参数:命令签名和一个接收命令参数和选项的闭包:
Artisan::command('build {project}', function ($project) {
$this->info("Building {$project}!");
});
闭包绑定下面的命令实例,因此你可以访问所有的辅助方法,您也可以访问一个完整的命令类。
类型提示依赖
除了接收命令的参数和选项外,命令闭包也可以使用类型提示来指定 服务 容器 之外的额外依赖:
use App\User;
use App\DripEmailer;
Artisan::command('email:send {user}', function (DripEmailer $drip, $user) {
$drip->send(User::find($user));
});
闭包命令描述
当定义一个基于命令的闭包时,你可以使用 describe
方法来为命令添加描述。这个描述将会在你执行 php artisan list
或 php artisan help
命令时显示:
Artisan::command('build {project}', function ($project) {
$this->info("Building {$project}!");
})->describe('Build the project');
定义预期的输入
在你编写控制台命令时,通常通过参数和选项收集用户输入,Laravel 使这项操作变得很方便,你可以在命令里使用 signature
属性。 signature
属性通过一个类似路由风格的语法让用户为命令定义名称,参数和选项。
参数
所有用户提供的参数及选项都包在大括号中。如以下例子,此命令会定义一个 必须 的参数: user
:
/**
* 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}
选项
选项,和参数一样,也是用户输入的一种格式,不过当使用选项时,需要在命令前加两个连字符号 (--
) 的前缀,有两种类型的选项:接收一个值和不接受值。选项不接收一个值作为布尔值的 switch
。让我们看一个选项的例子:
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'email:send {user} {--queue}';
在这个例子中,当调用 Artisan
命令时,--queue
这个选项可以被明确的指定。如果 --queue
被当成输入时,这个选项的的值为 true
,否则这个值为 false
:
php artisan email:send 1 --queue
有值的选项
接下来,我们看下有值的选项。如果用户必须为选项指定一个值,会在选项的后面加一个 =
的后缀:
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'email:send {user} {--queue=}';
在这个例子中, 用户可以想下面这个例子传递一个值:
php artisan email:send 1 --queue=default
您可以通过指定选项名称后的默认值将默认值分配给选项。如果用户没有输入一个值,将会采用默认的值:
email:send {user} {--queue=default}
选项快捷键
当定义一个定义选项时,可以分配一个快捷键。你可以在选项前使用一个 |
分隔符将简写和完整选项名分开:
email:send {user} {--Q|queue}
数组输入
如果你想使用数组输入方式定义参数或选项,你可以使用 *
符号。首先,我们先看一个数组输入的实例:
email:send {user*}
调用此方法时,user
参数通过命令行输入。例如,下面这个命令将会为 user
设置 ['foo', 'bar']
:
php artisan email:send foo bar
在定义一个使用数组输入时,每个输入选项值的命令都要在选项名称前 加前缀:
email:send {user} {--id=*}
php artisan email:send --id=1 --id=2
输入描述
您可以通过在使用一个冒号分离参数来分配输入参数和选项的说明。如果你需要一个小的额外的空间来定义你的命令,可以多行定义你的扩展:
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'email:send
{user : The ID of the user}
{--queue= : Whether the job should be queued}';