Laravel 编写控制台命令

2023-02-26 14:02:07 浏览数 (2)

Artisan 是 Laravel 附带的命令行接口。

代码语言:javascript复制
#查看所有可用的 Artisan 命令
php artisan list

#查看命令帮助
php artisan help migrate

Tinker 命令 (REPL)

Laravel Tinker 是为 Laravel 提供的强大的 REPL(交互式解释器),由 PsySH 提供支持。

所有 Laravel 应用都默认包含了 Tinker。如果你之前已经将 Tinker 从应用中删除,可以使用 Composer 进行手动安装:

代码语言:javascript复制
composer require laravel/tinker

通过运行 Artisan 命令 tinker 进入 Tinker 环境。

代码语言:javascript复制
php artisan tinker

你可以通过 vendor:publish 命令发布 Tinker 配置文件:

代码语言:javascript复制
root@php-fpm:/var/www/laravel-demo# php artisan vendor:publish --provider="LaravelTinkerTinkerServiceProvider"
Copied File [/vendor/laravel/tinker/config/tinker.php] To [/config/tinker.php]
Publishing complete.

编写命令

即控制台应用。

除 Artisan 提供的命令外,你也可以编写自己的自定义命令。命令在多数情况下位于 app/Console/Commands 目录中。

生成命令

代码语言:javascript复制
root@php-fpm:/var/www/laravel-demo# php artisan make:command PublishArticles
Console command created successfully.

root@php-fpm:/var/www/laravel-demo# cat app/Console/Commands/PublishArticles.php 

<?php

class PublishArticles extends Command
{
    protected $signature = 'article:publish {article}';

    protected $description = '发布文章';

    public function __construct()
    {
        parent::__construct();
    }
    public function handle()
    {
        echo $this->argument('article').PHP_EOL;
    }
}

执行命令

代码语言:javascript复制
root@php-fpm:/var/www/laravel-demo# php artisan article:publish cw
cw

定义输入期望

在编写控制台命令时,通常是通过参数和选项来收集用户输入的。

参数

用户提供的所有参数和选项都用花括号括起来。

代码语言:javascript复制
#必须的参数
protected $signature = 'article:publish {article}';

#可选参数...
'article:publish {article?}'

#带有默认值的可选参数...
'article:publish {article=foo}'

选项

选项类似于参数,是用户输入的另一种形式。在命令行中指定选项的时候,它们以两个短横线 (–) 作为前缀。这有两种类型的选项:接收值和不接受值。不接收值的选项就像是一个布尔「开关」。我们来看一下这种类型的选项的示例:

代码语言:javascript复制
#不接收值的选项就像是一个布尔「开关」
protected $signature = 'article:publish {article} {--queue}';

#带值的选项。如果用户需要为一个选项指定一个值,则需要在选项名称的末尾追加一个 = 号:
protected $signature = 'article:publish {article} {--queue=}';

#在选项名称后指定其默认值
'article:publish {article} {--queue=default}'

#选项简写
'article:publish {article} {--Q|queue}'

输入数组

代码语言:javascript复制
#指定了一个数组参数的例子:
'article:publish {article*}'

root@php-fpm:/var/www/laravel-demo# php artisan article:publish cw cw2
["cw","cw2"]

#定义零个或多个参数
'article:publish {article?*}'

#选项数组
'article:publish {--id=*}'

root@php-fpm:/var/www/laravel-demo# php artisan article:publish --id=1 --id=2
["1","2"]

输入说明

代码语言:javascript复制
protected $signature = 'article:publish
                        {article : The ID of the article}
                        {--queue : Whether the job should be queued}';

命令 I/O

接收参数

代码语言:javascript复制
$articleId = $this->argument('article');
$arguments = $this->arguments();

// 检索一个指定的选项...
$queueName = $this->option('queue');

// 检索所有选项做为数组...
$options = $this->options();

交互式输入

代码语言:javascript复制
#ask 方法将询问用户指定的问题来接收用户输入,然后用户输入将会传到你的命令中:
$name = $this->ask('What is your name?');

root@php-fpm:/var/www/laravel-demo# php artisan article:publish

 What is your name?:
 > cw

cw

#请求确认
$password = $this->secret('What is the password?');
if ($this->confirm('Do you wish to continue?')) {
    //
}

#自动补全
$name = $this->anticipate('What is your name?', ['Taylor', 'Dayle']);

root@php-fpm:/var/www/laravel-demo# php artisan article:publish

 What is your name?:
 > Taylor
#根据输入词给出响应的提示
$name = $this->anticipate('What is your address?', function ($input) {
    //拿$input查数据库?
    // 返回自动完成配置...
});

#多选择问题
root@php-fpm:/var/www/laravel-demo# php artisan article:publish

 What is your name? [Taylor]:
  [0] Taylor
  [1] Dayle
 > 1

Dayle

此外, choice 方法接受第四和第五可选参数 ,用于确定选择有效响应的最大尝试次数以及是否允许多次选择:

文字输出

代码语言:javascript复制
root@php-fpm:/var/www/laravel-demo# php artisan article:publish
The command was successful!

$this->error('Something went wrong!');
$this->line('Display this on the screen');
// 输出单行空白...
$this->newLine();

// 输出三行空白...
$this->newLine(3);

#表格
root@php-fpm:/var/www/laravel-demo# php artisan article:publish
 ------ ----------- 
| Name | Email     |
 ------ ----------- 
| cw   | 1@qq.com  |
| cw2  | 11@qq.com |
 ------ ----------- 

#进度条
$articles = $this->withProgressBar(Article::all(), function ($article) {
    echo json_encode($article, JSON_UNESCAPED_UNICODE).PHP_EOL;
});

root@php-fpm:/var/www/laravel-demo# php artisan article:publish
 0/2 [░░░░░░░░░░░░░░░░░░░░░░░░░░░░]   0%{"id":1,"category_id":1,"title":"aa","content":"aaaaa","views":0,"create_time":0}
{"id":2,"category_id":1,"title":"bb","content":"bbbbb","views":0,"create_time":0}
 2/2 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

注册命令

您的所有控制台命令都在您的应用程序的 AppConsoleKernel 类中注册

代码语言:javascript复制
protected function commands()
{
    $this->load(__DIR__.'/Commands');
    $this->load(__DIR__.'/../Domain/Orders/Commands');

    // ...
}

以编程方式执行命令

从路由或控制器执行 Artisan 命令。您可以使用 Artisan 外观上的 call 方法来完成此操作

代码语言:javascript复制
use IlluminateSupportFacadesArtisan;

Route::post('/article/{article}/mail', function ($article) {
    $exitCode = Artisan::call('article:publish', [
        'article' => $article, '--queue' => 'default'
    ]);

    //
});

或者,您可以将整个 Artisan 命令作为字符串传递给 call 方法:

代码语言:javascript复制
Artisan::call('article:publish 1 --queue=default');

传递参数

代码语言:javascript复制
#传递数组值
use IlluminateSupportFacadesArtisan;

Route::post('/mail', function () {
    $exitCode = Artisan::call('article:publish', [
        '--id' => [5, 13]
    ]);
});

#传递布尔值
$exitCode = Artisan::call('migrate:refresh', [
    '--force' => true,
]);

队列 Artisan 命令

代码语言:javascript复制
use IlluminateSupportFacadesArtisan;

Route::post('/article/{article}/mail', function ($article) {
    Artisan::queue('article:publish', [
        'article' => $article, '--queue' => 'default'
    ]);

    //
});

从一个命令调用另一个命令

代码语言:javascript复制
/**
 * 执行控制台命令。
 *
 * @return mixed
 */
public function handle()
{
    $this->call('article:publish', [
        'article' => 1, '--queue' => 'default'
    ]);

    //
}

Stub 定制

Artisan 控制台的 make 命令用于创建各种类。类似模板文件,如果想修改他们,需要先发布资源

代码语言:javascript复制
php artisan stub:publish

已发布的 stub 将存放于你的应用根目录下的 stubs 目录中。

参考

https://learnku.com/docs/laravel/9.x/artisan/12222

0 人点赞