Artisan 命令行

690次阅读
没有评论

Artisan 命令行
简介
Tinker 命令 (REPL)
编写命令
生成命令
命令结构
闭包命令
定义输入期望
参数
选项
输入数组
输入说明
I/O 命令
检索输入
交互输入
编写输出
注册命令
以编程方式执行命令
从其他命令调用命令

简介
Artisan 是 Laravel 自带的命令行接口,他提供了许多使用的命令来帮助你构建 Laravel 应用 。要查看所有可用的 Artisan 命令的列表,可以使用 list 命令:

php artisan list
每个命令都包含了「帮助」 界面 ,它会显示和概述命令的可用参数及选项。只需要在命令前加上 help 即可查看命令帮助界面 :

php artisan help migrate

Tinker 命令 (REPL)
所有 Laravel 应用都包含了 Tinker,一个基于 PsySH 包提供支持的 REPL 。Tinker 让你可以在命令行中与你整个的 Laravel 应用进行交互 。 包括 Eloquent ORM、任务、事件等等。运行 Artisan 命令 tinker 进入 Tinker 环境:

php artisan tinker
你可以通过使用 vendor:publish 命令发布 Tinker 配置文件:

php artisan vendor:publish –provider=”Laravel\Tinker\TinkerServiceProvider”
命令白名单
Tinker 通过采用白名单的方式来确定允许哪些 Artisan 命令可以在 shell 中运行。默认情况下,你可以运行 clear-compiled 、down、env、 inspire、migrate、 optimize、和 up 命令。如果你想要添加更多的白名单命令,可以将它们添加到 tinker.php 配置文件中的 commands 数组里:

‘commands’ => [
// App\Console\Commands\ExampleCommand::class,
],
黑名单别名
通常,Tinker 会在 Tinker 中根据你的需要自动为类添加别名。然而,你可能不希望为某些类添加别名。你可以在 tinker.php 配置文件中的 dont_alias 数组里列举这些类来完成此操作:

‘dont_alias’ => [
App\User::class,
],

编写命令
除 Artisan 提供的命令外,你还可以构建自己的自定义命令。 命令通常存储在 app/Console/Commands 目录中;不过,只要你的命令可以由 Composer 加载,你就可以自由选择自己的存储位置。

生成命令
要创建一个新的命令,可以使用 Artisan 命令 make:command。这个命令会在 app/Console/Commands 目录中创建一个新的命令类。 不必担心应用中不存在这个目录,因为它会在你第一次运行 Artisan 命令 make:command 时创建。生成的命令会包括所有命令中默认存在的属性和方法:

php artisan make:command SendEmails

命令结构
命令运行后,你应该先填写 signature 和 description 属性以便你在输入 php artisan list 时能够清楚知道用法。执行命令时会调用 handle 方法,你可以在这个方法中放置命令逻辑。

Tip: 为了代码更好的复用,最好保持你的控制台代码轻量并且能够延迟到应用服务中完成。在下面的例子中,我们将注入一个服务类来完成发送邮件的重任。

来看一个简单的例子。我们可以在 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
*/
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')));
}

}

闭包命令
基于闭包的命令提供了一个用类代替定义控制台命令的方法。同理,闭包路由是控制器的一种替代方法,而闭包命令则可以认为是命令类的替代方法。在 app/Console/Kernel.php 文件的 commands 方法中,Laravel 加载了 routes/console.php file:

/**

  • 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}’;
    你也可以创建可选参数,并定义参数的默认值:

// 可选参数…
email:send {user?}

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

选项
选项,类似于参数,是用户输入的另一种格式。当命令行指定选项时,它们以两个连字符 ( — ) 作为前缀。有两种类型的选项:接收值和不接收值。不接收值的选项就像是一个布尔值的「开关」。让我们看一下这种类型的选项的例子:

/**

  • 命令行的名称及签名。
    *
  • @var string
    */
    protected $signature = ’email:send {user} {–queue}’;
    在这个例子中,可以在调用 Artisan 命令时指定 –queue 开关。如果 –queue 开关被传递,该选项的值为 true, 否则为 false :

php artisan email:send 1 –queue

带值的选项
接下来,让我们来看一个带值的选项。如果想让用户必须为选项指定一个值,则需要在选项名称末尾追加一个等号 = 作为的后缀:

/**

  • 命令行的名称及签名。
    *
  • @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

输入说明
你可以通过使用冒号来为参数和选项添加说明,并使其将他们隔开。如果你需要一点额外的空间来定义你的命令,可以随意分开在多个行里:

/**

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

Command I/O

获取输入
在命令执行时,显然你需要获取命令接收到的参数和选项的值。你可以用 argument 和 option 方法来达到目的:

/**

  • 执行命令。
    *
  • @return mixed
    */
    public function handle()
    {
    $userId = $this->argument(‘user’); //
    }
    如果你想所有的参数以 array 数组获取,可以调用 arguments 方法:

$arguments = $this->arguments();
和获取参数类似,option 方法可以非常容易的获取选项的值。要将所有的选项以数组获取,使用 options 方法:

// 获取一个指定的选项值
$queueName = $this->option(‘queue’);

// 获取所有的选项值
$options = $this->options();
如果参数或选项不存在,则返回 null 。

交互式输入
除了显示输出外,你还可以要求用户在命令执行时提供输入。 ask 方法将提示用户输入并接收,然后用户的输入将会传入你的命令:

/**

  • 执行命令。
    *
  • @return mixed
    */
    public function handle()
    {
    $name = $this->ask(‘What is your name?’);
    }
    secret 方法和 ask 方法类似,但当用户在控制台输入时他们的输入内容是不可见的。这个方法适用于需要用户输入像密码这样的敏感信息的时候:

$password = $this->secret(‘What is the password?’);
请求确认
如果你想要寻求用户确认一些简单的信息,你可以使用 confirm 方法。默认情况下,该方法将返回 false 。但如果用户在回复中输入 y 或者 yes 则会返回 true 。

if ($this->confirm(‘Do you wish to continue?’)) {
//
}
自动补全
anticipate 方法可用于为可能的选择提供自动补全功能。用户仍然可以忽略自动补全的提示,作任意回答:

$name = $this->anticipate(‘What is your name?’, [‘Taylor’, ‘Dayle’]);
多重选择
如果你要给用户提供一些预设的选择,可以使用 choice 方法。你也可以设置默认值的索引,用以应对用户没有选择的情景:

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

编写输出
可以使用 line 、 info 、 comment 、 question 和 error 方法来将输出发送到终端。每个方法都使用适当的 ANSI 颜色表明其目的。例如,让我们向用户显示一些普通信息,通常来说,最好使用 info 方法,它会在控制台将输出的内容显示为绿色:

/**

  • 执行命令。
    *
  • @return mixed
    */
    public function handle()
    {
    $this->info(‘Display this on the screen’);
    }
    显示错误信息, 使用 error 方法。 错误信息则会显示为红色:

$this->error(‘Something went wrong!’);
如果你想在控制台显示无颜色设置的输出,请使用 line 方法:

$this->line(‘Display this on the screen’);
表格布局
对于多行列数据的格式化输出,table 方法处理起来更轻松。基于传入的表头和行数据,它会动态计算宽高:

$headers = [‘Name’, ‘Email’];

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

$this->table($headers, $users);
进度条
对于耗时任务,提示进度非常有必要。使用 output 对象就可以创建、加载以及停止进度条。首先,定义好任务总步数,然后,在每次任务执行时加载进度条:

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

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

$bar->start();

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

$bar->advance();

}

$bar->finish();
参阅 Symfony Progress Bar component documentati… 获取更多高级用法。

注册命令
app/Console/Commands 目录下的命令都会被注册,这是由于控制台内核的 commands 方法调用了 load。实际上,可随意调用 load 来扫描其他目录下的 Artisan 命令:

/**

  • 注册应用的命令
    *
  • @return void
    */
    protected function commands()
    {
    $this->load(DIR.’/Commands’);
    $this->load(DIR.’/MoreCommands’); // …
    }
    也可以在 app/Console/Kernel.php 文件的 $commands 属性中手动注册命令的类名。Artisan 启动时,这个属性列出的命令都将由 服务容器 解析并通过 Artisan 进行注册:

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

程序调用命令
有时需要在 CLI 之外执行 Artisan 命令,例如,在路由或控制器里触发 Artisan 命令。要实现调用,可以使用 Artisan 门面的 call 方法。call 方法的第一个参数接受命令名,第二个参数接受数组形式的命令参数。退出码将返回:

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

//

});
另外,你可以将整个 Artisan 命令作为字符串传递给 call 方法:

Artisan::call(’email:send 1 –queue=default’);
Artisan 门面的 queue 方法可以将 Artisan 命令队列化,交由 队列工作进程 进行后台处理。使用此方法之前,务必配置好队列以及运行队列监听器:

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

//

});
你也可以指定 Artisan 命令派发的连接或任务:

Artisan::queue(’email:send’, [
‘user’ => 1, ‘–queue’ => ‘default’
])->onConnection(‘redis’)->onQueue(‘commands’);
传递数组值
如果定义了接受数组的选项,可以直接传递数组到该选项:

Route::get(‘/foo’, function () {
$exitCode = Artisan::call(’email:send’, [
‘user’ => 1, ‘–id’ => [5, 13]
]);
});
传递布尔值
需要指定没有选项值的选项时,例如,migrate:refresh 命令的 –force 选项,就可以传入 true 或 false:

$exitCode = Artisan::call(‘migrate:refresh’, [
‘–force’ => true,
]);

命令的互相调用
call 方法可以实现调用其它 Artisan 命令。call 方法接受命令名和数组形式的选项:

/**

  • 执行控制台命令
    *
  • @return mixed
    */
    public function handle()
    {
    $this->call(’email:send’, [
    ‘user’ => 1, ‘–queue’ => ‘default’
    ]); //
    }
    如果要抑制控制台命令的所有输出,可以使用 callSilent 方法。callSilent 的使用方法同 call :

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

正文完
可以使用微信扫码关注公众号(ID:xzluomor)
post-qrcode
 
评论(没有评论)