Artisan 命令行

    是 Laravel 的命令行接口的名称, 它提供了许多实用的命令来帮助你开发 Laravel 应用, 要查看所有的 Artisan 命令列表,可以使用 list 命令:

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

    1. php artisan help migrate

    编写命令

    除了 Artisan 提供的命令之外,还可以创建自定义命令。自定义命令默认存储在 app/Console/Commands 目录,当然,你也可以修改 composer.json 配置来指定你想要存放的目录。

    要创建一个新的命令,可以使用 make:command 命令。这个命令会创建一个命令类并存放在 app/Console/Commands 目录。 不必担心不存在这个目录,运行 make:command 命令时会首先创建这个目录。生成的命令将会包括所有默认存在的属性和方法:

    1. php artisan make:command SendEmails

    命令结构

    命令生成以后,应先填写类的 signaturedescription 属性,之后可以在使用 list 命令是显示出来。执行命令是调用 handle 方法,可以把你的命令逻辑放到这个方法中。

    让我们看这个简单的命令例子,Command 类构造器允许注入需要的依赖,Laravel 的服务容器 将会自动注入构造函数中所有带类型约束的依赖:

    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. * The name and signature of the console command.
    10. *
    11. * @var string
    12. */
    13. protected $signature = 'email:send {user}';
    14. /**
    15. * The console command description.
    16. *
    17. * @var string
    18. */
    19. protected $description = 'Send drip e-mails to a user';
    20. /**
    21. * The drip e-mail service.
    22. *
    23. * @var DripEmailer
    24. */
    25. protected $drip;
    26. /**
    27. * Create a new command instance.
    28. *
    29. * @param DripEmailer $drip
    30. * @return void
    31. */
    32. public function __construct(DripEmailer $drip)
    33. parent::__construct();
    34. $this->drip = $drip;
    35. }
    36. /**
    37. * Execute the console command.
    38. *
    39. * @return mixed
    40. */
    41. public function handle()
    42. {
    43. $this->drip->send(User::find($this->argument('user')));
    44. }
    45. }

    闭包命令

    闭包命令提供一个替代定义命令方法的类。同样的路由闭包是控制器的一种替代方法,这种命令闭包可以替换命令类。使用 app/Console/Kernel.php 文件的 commands 方法,需要 Laravel 在 routes/console.php 注册:

    1. /**
    2. * Register the Closure based commands for the application.
    3. *
    4. * @return void
    5. */
    6. protected function commands()
    7. {
    8. require base_path('routes/console.php');
    9. }

    虽然这个文件没有定义 HTTP 路由,它定义了基于控制台的入口点(路由)到你的应用中,在这个文件中,你可以使用 Artisan::command 方法定义所有基于路由的闭包,command 方法接收两个参数:和一个接收命令参数和选项的闭包:

    1. Artisan::command('build {project}', function ($project) {
    2. $this->info("Building {$project}!");
    3. });

    闭包绑定下面的命令实例,因此你可以访问所有的辅助方法,您也可以访问一个完整的命令类。

    类型提示依赖

    除了接收命令的参数和选项外,命令闭包也可以使用类型提示来指定 之外的额外依赖:

    1. use App\User;
    2. use App\DripEmailer;
    3. Artisan::command('email:send {user}', function (DripEmailer $drip, $user) {
    4. $drip->send(User::find($user));
    5. });

    闭包命令描述

    当定义一个基于命令的闭包时,你可以使用 describe 方法来为命令添加描述。这个描述将会在你执行 php artisan list 或 命令时显示:

    1. Artisan::command('build {project}', function ($project) {
    2. $this->info("Building {$project}!");
    3. })->describe('Build the project');

    在你编写控制台命令时,通常通过参数和选项收集用户输入,Laravel 使这项操作变得很方便,你可以在命令里使用 signature 属性。 signature 属性通过一个类似路由风格的语法让用户为命令定义名称,参数和选项。

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

    1. /**
    2. * The name and signature of the console command.
    3. *
    4. * @var string
    5. */
    6. protected $signature = 'email:send {user}';

    您也可以创建可选参数,并定义参数的默认值:

    1. // Optional argument...
    2. email:send {user?}
    3. // Optional argument with default value...
    4. email:send {user=foo}

    选项

    选项,和参数一样,也是用户输入的一种格式,不过当使用选项时,需要在命令前加两个连字符号 (--) 的前缀,有两种类型的选项:接收一个值和不接受值。选项不接收一个值作为布尔值的 switch 。让我们看一个选项的例子:

    1. /**
    2. * The name and signature of the console command.
    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. * The name and signature of the console command.
    3. *
    4. * @var string
    5. */
    6. protected $signature = 'email:send {user} {--queue=}';

    在这个例子中, 用户可以想下面这个例子传递一个值:

    您可以通过指定选项名称后的默认值将默认值分配给选项。如果用户没有输入一个值,将会采用默认的值:

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

    选项快捷键

    当定义一个定义选项时,可以分配一个快捷键。你可以在选项前使用一个 | 分隔符将简写和完整选项名分开:

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

    数组输入

    如果你想使用数组输入方式定义参数或选项,你可以使用 * 符号。首先,我们先看一个数组输入的实例:

    1. email:send {user*}

    调用此方法时,user 参数通过命令行输入。例如,下面这个命令将会为 user 设置 ['foo', 'bar']

    1. php artisan email:send foo bar

    在定义一个使用数组输入时,每个输入选项值的命令都要在选项名称前加前缀:

    1. email:send {user} {--id=*}
    2. php artisan email:send --id=1 --id=2

    您可以通过在使用一个冒号分离参数来分配输入参数和选项的说明。如果你需要一个小的额外的空间来定义你的命令,可以多行定义你的扩展:

    1. /**
    2. * The name and signature of the console command.
    3. *
    4. * @var string
    5. */
    6. protected $signature = 'email:send
    7. {user : The ID of the user}
    8. {--queue= : Whether the job should be queued}';

    Command I/O

    获取输入

    在命令执行的时,你可以像下面这样使用 argumentoption 方法获取参数和选项:

    1. /**
    2. * Execute the console command.
    3. *
    4. * @return mixed
    5. */
    6. public function handle()
    7. {
    8. $userId = $this->argument('user');
    9. }

    如果您需要获取所有参数作为一个 array,调用 arguments 方法:

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

    选项可以像参数一样使用 option 方法检索, 获取所有的选项作为一个 array ,调用 options 方法:

    1. // Retrieve a specific option...
    2. $queueName = $this->option('queue');
    3. // Retrieve all options...
    4. $options = $this->options();

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

    交互式输入

    1. /**
    2. * Execute the console command.
    3. *
    4. * @return mixed
    5. */
    6. public function handle()
    7. {
    8. $name = $this->ask('What is your name?');
    9. }

    secret 方法和 ask 方法类似,但是用户输入在终端中是不可以见的,这个方法在需要用户输入像密码这样的敏感信息是很有用的:

    请求确认

    如果你要用户提供的确认信息,你可以使用 confirm 方法,默认情况下,该方法返回 false,当然,如果你输入 y 这个方法将会返回 true

    1. if ($this->confirm('Do you wish to continue? [y|N]')) {
    2. //
    3. }

    自动完成

    anticipate 方法可用于为可能的选项提供自动完成功能,用户仍然可以选择,忽略这个提示:

    多重选择

    如果你要给用户一组预设选择,可以使用 choice 方法,你可以设置默认选项当用户没有选择时:

    1. $name = $this->choice('What is your name?', ['Taylor', 'Dayle'], $default);

    使用 lineinfocommentquestionerror 方法来发送输出到终端。每个方法都有适当的 ANSI 颜色来作为他们的标识。例如,要显示一条信息消息给用户,使用 info 方法。通常,在终端显示为绿色:

    1. /**
    2. * Execute the console command.
    3. *
    4. * @return mixed
    5. */
    6. public function handle()
    7. {
    8. $this->info('Display this on the screen');
    9. }

    显示错误信息, 使用 error 方法。 错误信息显示红色:

    1. $this->error('Something went wrong!');

    使用 line 方法可以像平常一样,没有颜色输出。

    1. $this->line('Display this on the screen');

    数据表布局

    table 方法使输出多行/列格式的数据变得简单,只需要将头和行传递给该方法,宽度和高度将基于给定数据自动计算:

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

    进度条

    对需要较长时间运行的任务,显示进度指示器很有用,使用该输出对象,我们可以开始、前进以及停止该进度条。在开始进度时你必须定义步数,然后每走一步进度条前进一格:

    1. $users = App\User::all();
    2. $bar = $this->output->createProgressBar(count($users));
    3. foreach ($users as $user) {
    4. $this->performTask($user);
    5. $bar->advance();
    6. }
    7. $bar->finish();

    更多信息请查阅.

    命令编写完成后,需要注册 Artisan 后才能使用。注册文件为 app/Console/Kernel.php 。在这个文件中, 你会在 commands 属性中看到一个命令列表。要注册你的命令,只需将其加到该列表中即可。当 Artisan 启动时,所有罗列在这个 属性的命令,都会被 解析并向 Artisan 注册:

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

    程序内部调用命令

    有时候你可能希望在 CLI 之外执行 Artisan 命令,例如,你可能希望在路由或控制器中触发 Artisan 命令,你可以使用 Artisan facade 上的 call 方法来完成。call 方法接收被执行的命令名称作为第一个参数,命令参数数组作为第二个参数,退出代码被返回:

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

    Artisan facade 使用 queue 方法,可以将 Artisan 命令给后台的 队列服务器 运行,在这之前,确保您已配置了您的队列,并正在运行队列:

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

    如果需要指定非接收字符串选项的值,如 migrate:refresh 命令的 --force 值,你可以传递一个 true 或者 false

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

    命令中调用其它命令

    有时候你希望从一个已存在的 Artisan 命令中调用其它命令。你可以使用 call 方法, call 方法接受命令名称和命令参数的数组:

    1. /**
    2. * Execute the console command.
    3. *
    4. * @return mixed
    5. */
    6. public function handle()
    7. {
    8. $this->call('email:send', [
    9. 'user' => 1, '--queue' => 'default'
    10. ]);
    11. //
    12. }

    如果你想要调用其它控制台命令并阻止其所有输出,可以使用 callSilent 命令。callSilentcall 方法用法一样:

    1. $this->callSilent('email:send', [
    2. ]);

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

    文档永久地址: