除了 Artisan 提供的系统命令之外,还可以编写自己的命令。
自定义命令通常存放在 app/Console/Commands 目录下;
当然,你也可以自己选择存放位置,只要该命令类可以被 Composer 自动加载即可。
要创建一个新命令,你可以使用 Artisan 命令 make:command,该命令会在 app/Console/Commands 目录下创建一个新的命令类。如果该目录不存在,不用担心,它将会在你首次运行 Artisan 命令 make:command 时被创建。生成的命令将会包含默认的属性设置以及所有命令都共有的方法:
php artisan make:command SendEmails
接下来,你需要在该命令可以通过Artisan CLI执行之前注册这个命令。
命令生成以后,需要填写该类的signature 和 description 属性,这两个属性在调用 list 显示命令的时候会被用到。handle 方法在命令执行时被调用,你可以将所有命令逻辑都放在这个方法里面。
注:为了更好地实现代码复用,最佳实践是保持控制台命令的轻量并让它们延迟到应用服务中完成任务。在下面的例子中,我们注入了一个服务类来完成发送邮件这样的“繁重”任务。
下面让我们来看一个例子,注意我们可以在命令类的构造函数中注入任何依赖,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
* @translator laravelacademy.org
*/
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 文件:
/**
* 为应用注册基于闭包的命令.
*
* @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}!");
});
该闭包被绑定到底层命令实例,所以你可以像在完整的命令类中一样访问所有辅助方法。
挂载到
Esinit.php
通过php artisan 查看