Artisan 命令行

介绍

Artisan 是 Laravel 的命令行接口的名称,它提供了许多实用的命令来帮助你开发 Laravel 应用,它由强大的 Symfony Console 组件所驱动。

可以使用 list 命令来列出所有可用的 Artisan 命令:

  1. php artisan list

每个命令也包含了「帮助」界面,它会显示并概述命令可使的参数及选项。只要在命令前面加上 help 即可显示帮助界面:

  1. php artisan help migrate

编写命令

除了使用 Artisan 本身所提供的命令之外,Laravel 也允许你自定义 Artisan 命令。

自定义命令默认存储在 app/Console/Commands 目录中,当然,只要在 composer.json 文件中的配置了自动加载,你可以自由选择想要放置的地方。

若要创建新的命令,你可以使用 make:console Artisan 命令生成命令文件:

  1. php artisan make:console SendEmails

上面的这个命令会生成 app/Console/Commands/SendEmails.php 类,--command 参数可以用来指定调用名称:

  1. php artisan make:console SendEmails --command=emails:send

命令结构

一旦生成这个命令,应先填写类的 signaturedescription 这两个属性,它们会被显示在 list 界面中。

命令运行时 handle 方法会被调用,请将程序逻辑放置在此方法中。

接下来讲解一个发送邮件的例子。

为了更好的代码重用性,还有可读性,建议把处理业务逻辑的代码抽到一个功能类里。

Command 类构造器允许注入需要的依赖,Laravel 的 服务容器 将会自动把功能类 DripEmailer 解析到构造器中:

  1. <?php
  2. namespace App\Console\Commands;
  3. use App\User;
  4. use App\DripEmailer;
  5. use Illuminate\Console\Command;
  6. class SendEmails extends Command
  7. {
  8. /**
  9. * 命令行的名称及用法。
  10. *
  11. * @var string
  12. */
  13. protected $signature = 'email:send {user}';
  14. /**
  15. * 命令行的概述。
  16. *
  17. * @var string
  18. */
  19. protected $description = 'Send drip e-mails to a user';
  20. /**
  21. * 滴灌电子邮件服务。
  22. *
  23. * @var DripEmailer
  24. */
  25. protected $drip;
  26. /**
  27. * 创建新的命令实例。
  28. *
  29. * @param DripEmailer $drip
  30. * @return void
  31. */
  32. public function __construct(DripEmailer $drip)
  33. {
  34. parent::__construct();
  35. $this->drip = $drip;
  36. }
  37. /**
  38. * 运行命令。
  39. *
  40. * @return mixed
  41. */
  42. public function handle()
  43. {
  44. $this->drip->send(User::find($this->argument('user')));
  45. }
  46. }

命令的输入与输出

定义预期的输入

signature 属性定义了希望从用户获得的输入格式,signature 属性可用来定义命令的名字、参数及选项,具有与路由相似的语法特性。

参数及选项都包在大括号中。如以下例子,此命令会定义一个 必须的 参数 user

  1. /**
  2. * 命令行的名称及用法。
  3. *
  4. * @var string
  5. */
  6. protected $signature = 'email:send {user}';

以下是可选参数和默认值的例子(注意括号内的符号):

  1. // 选择性的参数...
  2. email:send {user?}
  3. // 选择性的参数及默认的值...
  4. email:send {user=foo}

选项就跟参数一样,同样也是用户输入的一种格式,不过当使用选项时,需要在命令行加入两个连字符号(--),选项的定义如下:

  1. /**
  2. * 命令行的名称及用法。
  3. *
  4. * @var string
  5. */
  6. protected $signature = 'email:send {user} {--queue}';

在这个例子中,当调用 Artisan 命令时,--queue 这个选项可以被明确的指定。如果 --queue 被当成输入时,这个选项的值会是 true,如果没有指定时,这个选项的值将会是 false

  1. php artisan email:send 1 --queue

你也可以借助在这个选项后面加个 = 来为选项明确指定值:

  1. /**
  2. * 命令行的名称及用法。
  3. *
  4. * @var string
  5. */
  6. protected $signature = 'email:send {user} {--queue=}';

在这个例子中,用户可以为这个参数传入一个值:

  1. php artisan email:send 1 --queue=default

指定默认值给选项:

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

为选项定义简写方式:

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

增加概述

使用冒号 : 可以为参数和选项增加概述:

  1. /**
  2. * 命令行的名称及用法。
  3. *
  4. * @var string
  5. */
  6. protected $signature = 'email:send
  7. {user : 用户的 ID }
  8. {--queue= : 这个工作是否该进入队列}';

获取输入

代码里通过调用 argumentoption 方法来获取对应的参数和选项输入。

使用 argument 方法来获取参数的值:

  1. /**
  2. * 命令行的处理逻辑
  3. *
  4. * @return mixed
  5. */
  6. public function handle()
  7. {
  8. $userId = $this->argument('user');
  9. //
  10. }

不加参数调用,可以获取到所有的参数 数组

  1. $arguments = $this->argument();

option 方法的使用同 argument 一样:

  1. // 获取特定的选择
  2. $queueName = $this->option('queue');
  3. // 获取所有选择
  4. $options = $this->option();

如果参数或选项不存在,将会返回 null

让用户回答

ask 方法提供的问题来提示用户,并且接受他们的输入,返回的是用户输入:

  1. /**
  2. * 命令行的处理逻辑
  3. *
  4. * @return mixed
  5. */
  6. public function handle()
  7. {
  8. $name = $this->ask('你是名字是?');
  9. }

secret 如同 ask 方法一般,但是用户的输入将不会显示在命令行。这个方法适用于要求提供如密码的敏感信息时:

  1. $password = $this->secret('密码是?');

让用户确认

confirm 方法提供询问用户确认,默认的情况下,这个方法会返回 false。如果用户对这个提示输入 y,那这个方法将会返回 true

  1. if ($this->confirm('你希望继续吗? [y|N]')) {
  2. //
  3. }

让用户做选择

anticipate 方法可被用于为可能的选择提供自动完成。用户仍可以选择任何答案而不理会这些选择。

  1. $name = $this->anticipate('你的名字是?', ['Taylor', 'Dayle']);

choice 方法让用户从给定选项里选择,用户会选择答案的索引,但是返回的是答案的值。可以设置返回默认值来防止没有任何东西被选择的情况:

  1. $name = $this->choice('你的名字是?', ['Taylor', 'Dayle'], false);

编写输出

使用 lineinfocommentquestionerror 方法来发送输出到终端。每个方法都有适当的 ANSI 颜色来表达它们的目的。

使用 info 方法来发送信息消息给用户,并在终端以绿色呈现:

  1. /**
  2. * 命令行的处理逻辑
  3. *
  4. * @return mixed
  5. */
  6. public function handle()
  7. {
  8. $this->info('把我显示在界面上');
  9. }

使用 error 方法来发送错误消息给用户,并在终端以红色呈现:

  1. $this->error('有东西出问题了!');

line 方法不会输出任何特殊的颜色:

  1. $this->line('把我显示在界面上');

数据表布局

使用 table 方法格式化输出多行与多列数据,宽跟高将会基于数据做动态计算:

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

进度条

对于需要长时间运行的任务,可以使用进度条来提示用户:

  1. $users = App\User::all();
  2. // 多少个任务
  3. $bar = $this->output->createProgressBar(count($users));
  4. foreach ($users as $user) {
  5. $this->performTask($user);
  6. // 一个任务处理完了,可以前进一点点了
  7. $bar->advance();
  8. }
  9. $bar->finish();

更多信息请查阅 Symfony Progress Bar 组件的文档

注册命令

命令编写完成后,需要注册 Artisan 后才能使用。注册文件为 app/Console/Kernel.php

在这个文件中,commands 属性是命令的清单,要注册命令,请在此清单加入类的名称即可。

当 Artisan 启动时,所有罗列在这个
属性的命令,都会被 服务容器 解析并向 Artisan 注册:

  1. protected $commands = [
  2. Commands\SendEmails::class,
  3. ];

程序内部调用命令

利用 Artisan facade 的 call 方法,可以在程序内部调用 Artisan 命令。

call 方法的第一个参数为命令的名称,第二个参数为数组型态的命令输入,退出码将会被返回:

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

Artisan facade 使用 queue 方法,可以将 Artisan 命令丢给后台的 队列服务器 运行:

  1. Route::get('/foo', function () {
  2. Artisan::queue('email:send', [
  3. 'user' => 1,
  4. '--queue' => 'default'
  5. ]);
  6. //
  7. });

如果需要指定非接收字符串选项的值,如 migrate:refresh 命令的 --force 标记,你可以传递一个 truefalse 的布尔值:

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

命令中调用其它命令

Command 类的 call 方法可以让你在命令中调用命令,call 方法接受命令名称和命令参数的数组:

  1. /**
  2. * 命令行的处理逻辑
  3. *
  4. * @return mixed
  5. */
  6. public function handle()
  7. {
  8. $this->call('email:send', [
  9. 'user' => 1,
  10. '--queue' => 'default'
  11. ]);
  12. //
  13. }

调用其它命令并忽略它所有的输出,可以使用 callSilent 命令。callSilent 方法有和 call 方法一样的用法:

  1. $this->callSilent('email:send', [
  2. 'user' => 1,
  3. '--queue' => 'default'
  4. ]);

推荐阅读


{note} 欢迎任何形式的转载,但请务必注明出处,尊重他人劳动共创开源社区。

转载请注明:本文档由 Laravel China 社区 [laravel-china.org] 组织翻译。

文档永久地址: http://d.laravel-china.org