Laravel - Digging Deeper - Artisan Console (官方文件原子化翻譯)

# 前言

學習一個框架, Ray 的想法是, 在深入理解底層實作的原理之前, 應該先知道這個框架的 使用方法; 先學習怎麼使用這個前人造的輪子, 再學習怎麼樣一個輪子。
所以本篇文章重點在於細讀官方文件, 並將內容理解後以 Q&A 的方式記錄下來, 加速學習以及查詢。



# Introduction

以下的 Laravel example command 的意思是?
  • Example:
    php artisan list
  • Answer:
    列出可用的 Artisan commands
以下的 Laravel example command 的意思是?
  • Example:
    php artisan help migrate
  • Answer:
    詳述 migrate command 的用法, 將 help 至於 command 前方可列出 command 詳細用法

# Tinker (RPEL)

# Installation

以下的 Laravel example code 的意思是?
  • Example:
    composer require laravel/tinker
  • Answer:
    安裝 Laravel tinker, tinker 預設就已安裝, 但如果有手動安裝的需求, 可以執行上面 composer 指令

# Usage

以下的 Laravel example command 的意思是?
  • Example:
    php artisan tinker
  • Answer:
    進入 tinker 環境
以下的 Laravel example command 的意思是?
  • Example:
    php artisan vendor:publish --provider="Laravel\Tinker\TinkerServiceProvider"
  • Answer:
    發布 tinker 的設定檔
Laravel Tinker 中, 若要 dispatch a job or queue, 該使用哪些 method?
  • Bus::dispatch
  • Queue:push

# Command Whitelist

以下位於 tinker.php 的 Laravel example code 的意思是?
  • Example:
    <?php
    'commands' => [
    // App\Console\Commands\ExampleCommand::class,
    ],
  • Answer:
    Tinker 使用白名單來決定哪些 Artisan commands 允許在 Tinker shell 中執行, 預設可以執行 clear-compiled, down, env, inspire, migrate, optimize, up 這些 command, 如果想要允許更多 command, 可加入上面的 example commands array 中

Classes That Should Not Be Aliased

以下位於 tinker.php 的 Laravel example code 的意思是?
  • Example:
    'dont_alias' => [
    App\Models\User::class,
    ],
  • Answer:
    Tinker 預設會自動 alias class, 如果有些 class 你希望 tinker 不要 alias, 可加在以上的 example ‘dont_alias’ array 中


# Writing Command

Laravel custom command 會被置於哪個資料夾?

app/Console/Commands


# Generating Commands

以下的 Laravel example command 的意思是?
  • Example:
    <?php
    php artisan make:command SendEmails
  • Answer:
    建立一個 custom command, 並置於 app/Console/Commands

# Command Structure

以下的 Laravel example command 的意思是?
  • Example:
    <?php

    namespace App\Console\Commands;

    use App\Models\User;
    use App\Support\DripEmailer;
    use Illuminate\Console\Command;

    class SendEmails extends Command
    {
    protected $signature = 'email:send {user}';

    protected $description = 'Send drip e-mails to a user';

    public function __construct()
    {
    parent::__construct();
    }

    public function handle(DripEmailer $drip)
    {
    $drip->send(User::find($this->argument('user')));
    }
    }
  • Answer:
    <?php

    namespace App\Console\Commands;

    use App\Models\User;
    use App\Support\DripEmailer;
    use Illuminate\Console\Command;

    class SendEmails extends Command
    {
    // command 的名字
    protected $signature = 'email:send {user}';

    // command 的描述
    protected $description = 'Send drip e-mails to a user';

    public function __construct()
    {
    parent::__construct();
    }

    // handle 裡頭就是執行此 command 的邏輯, args 可以用 type hint 的方式 inject 任何 class
    public function handle(DripEmailer $drip)
    {
    $drip->send(User::find($this->argument('user')));
    }
    }

# Closure Commands

以下位於 …/routes/console.php 的 Laravel example code 的意思是?
  • Example:
    <?php
    Artisan::command('build {project}', function ($project) {
    $this->info("Building {$project}!");
    });
  • Answer:
    建立一個 closure based command
    closure based command 之於 class command, 就相當於 route closure 之於 controller
    build 為帶入的 args, 所以輸入 php artisan build hello, 就會顯示 Building hello!

# Type-Hinting Dependencies

以下位於 …/routes/console.php 的 Laravel example code 的意思是?
  • Example:
    <?php
    use App\Models\User;
    use App\Support\DripEmailer;

    Artisan::command('email:send {user}', function (DripEmailer $drip, $user) {
    $drip->send(User::find($user));
    });
  • Answer:
    建立一個 closure based command
    closure based command 之於 class command, 就相當於 route closure 之於 controller
    輸入 php artisan email:send 3, 就會執行 $drip->send(User::find($user))
    在 closure 內可以 type hint 任何有用到的 class

# Closure Command Descriptions

以下位於 …/routes/console.php 的 Laravel example code 的意思是?
  • Example:
    <?php
    Artisan::command('build {project}', function ($project) {
    $this->info("Building {$project}!");
    })->describe('Build the project');
  • Answer:
    建立一個 closure based command
    closure based command 之於 class command, 就相當於 route closure 之於 controller
    build 為帶入的 args, 所以輸入 php artisan build hello, 就會顯示 Building hello!
    describe 為該 command 的敘述, 當執行 php artisan listphp artisan help 時會顯示出來


# Defining Input Expectation

# Arguments

以下位於 custom command class 的 Laravel example code 的意思是?
  • Example:
    <?php
    protected $signature = 'email:send {user}';

    protected $signature = 'email:send {user?}';

    protected $signature = 'email:send {user=foo}';
  • Answer:
    <?php
    // 例如輸入 'php artisan email:send Ray', 那 Ray 就會等於 {user}, 這個 argument 是 required
    protected $signature = 'email:send {user}';

    // 例如輸入 'php artisan email:send Ray', 那 Ray 就會等於 {user}, 這個 argument 是 optional
    protected $signature = 'email:send {user?}';

    // 例如輸入 'php artisan email:send Ray', 那 Ray 就會等於 {user}, 這個 argument 是 optional, 且 default value 為 foo
    protected $signature = 'email:send {user=foo}';

# Options

以下位於 custom command class 的 Laravel example code 的意思是?
  • Example:
    <?php
    protected $signature = 'email:send {user} {--queue}';
  • Answer:
    定義 Artisan command 的 format
    {user} 為 argument, {–queue} 為可有可無的 options, 有帶為 true, 反之為 false
    輸入: ‘php artisan email:send 4 –queue’, 那 {user} = 4, ‘–queue’ 有帶的話, 為 true, 反之為 false

# Options With Values

以下位於 custom command class 的 Laravel example code 的意思是?
  • Example:
    <?php
    protected $signature = 'email:send {user} {--queue=}';

    protected $signature = 'email:send {user} {--queue=default}';
  • Answer:
    <?php
    // 定義 Artisan command 的 format

    // {user} 為 argument, {--queue} 為可傳入值的 options
    // 輸入: 'php artisan email:send 4 --queue=highPriority', 那 {user} = 4, '--queue'
    // 的值為 'highPriority'
    protected $signature = 'email:send {user} {--queue=}';

    // 給予 '--queue' 一個 default 值, 若沒帶則為 'default'
    protected $signature = 'email:send {user} {--queue=default}';

# Options Shortcuts

以下位於 custom command class 的 Laravel example code 的意思是?
  • Example:
    <?php
    protected $signature = 'email:send {user} {--Q|queue}';
  • Answer:
    <?php
    // 定義 Artisan command 的 format
    // {user} 為 argument, {--queue} 為可有可無的 options, 有帶為 true, 無則為 false
    // '--Q' 為 '--queue' 的縮寫, 兩者都可用
    // 輸入: 'php artisan email:send 4 --queue', 那 {user} = 4, '--queue'
    // 為 true
    protected $signature = 'email:send {user} {--Q|queue}';

# Input Arrays

以下位於 custom command class 的 Laravel example code 的意思是?
  • Example:
    <?php
    protected $signature = 'email:send {user*};
  • Answer:
    定義 Artisan command 的 format
    {user*} 為 array input
    例如輸入 ‘php artisan email:send foo bar’, 則 {user*} 的值為 [‘foo’, ‘bar’]
以下位於 custom command class 的 Laravel example code 的意思是?
  • Example:
    <?php
    email:send {user} {--id=*}
  • Answer:
    定義 Artisan command 的 format
    {user} 為單一 input
    例如輸入 ‘php artisan email:send bar –id=1 –i=2 –id=3’則 {user} 的值為 ‘bar’, 而 ‘–id’ 的值為 [‘1’, ‘2’, ‘3’]

# Input Descriptions

以下位於 custom command class 的 Laravel example code 的意思是?
  • Example:
    <?php
    protected $signature = 'email:send
    {user : The ID of the user}
    {--queue= : Whether the job should be queued}';
  • Answer:
    定義 Artisan command 的 format
    {user} 為單一 input, –queue= 為單一 input
    例如輸入 ‘php artisan email:send bar –queue=highPriority’, 則 {user} 的值為 ‘bar’, 而 ‘–queue’ 的值為 ‘highPriority’, colon 後的 string 為 args 及 options 的 description


# Command I/O

# Retrieving Input

以下位於 custom command class 的 Laravel example code 的意思是?
  • Example:
    <?php
    public function handle()
    {
    $userId = $this->argument('user');

    $arguments = $this->arguments();

    //
    }
  • Answer:
  1. 取得 command signature 中定義的 argument, 例如 signature 為 ‘email:send {user}’
  2. 取得所有 arguments, 以 array 的方式取得, 例如 signature 為 ‘email:send {user} {shop}’, 則輸出為 [‘user’ => {user}, ‘shop’ => {shop}]
以下位於 custom command class 的 Laravel example code 的意思是?
  • Example:
    <?php
    $queueName = $this->option('queue');

    $options = $this->options();
  • Answer:
  1. 取得 command signature 中定義的 option, 例如 signature 為 ‘email:send {user} {–queue=}’
  2. 取得所有 options, 以 array 的方式取得, 例如 signature 為 ‘email:send {–id=} {–wd=}, 則輸出為 [‘id’ => {id}, ‘wd’ => {wd}], 若 options 為 array, 即 {–id=*}, 則輸出為 nested array

# Prompting For Input

以下位於 custom command class 的 Laravel example code 的意思是?
  • Example:
    <?php
    public function handle()
    {
    $name = $this->ask('What is your name?');
    }
  • Answer:
    當使用者輸入 command 時會跳出詢問視窗, 讓 user 輸入
以下位於 custom command class 的 Laravel example code 的意思是?
  • Example:
    <?php
    public function handle()
    {
    $password = $this->secret('What is the password?');
    }
  • Answer:
    當使用者輸入 command 時會跳出詢問視窗, 讓 user 輸入, 與 ask() 不同之處在於 secret() 會隱藏使用者的輸入

# Asking For Confirmation

以下位於 custom command class 的 Laravel example code 的意思是?
  • Example:
    <?php
    public function handle()
    {
    if ($this->confirm('Do you wish to continue?')) {
    //
    }
    }
  • Answer:
    當使用者輸入 command 時跳出詢問視窗, 讓使用者輸入, 默認為 false, 若輸入 y or yes 則為 true

# Auto-Completion

以下位於 custom command class 的 Laravel example code 的意思是?
  • Example:
    <?php
    public function handle()
    {
    $name = $this->anticipate('What is your name?', ['Taylor', 'Dayle']);
    }
  • Answer:
    當使用者輸入 command 時會跳出詢問視窗, 讓使用者輸入, 當使用者輸入 T 會自動提示 Taylor, 輸入 D 則自動提示 Dayle, 使用者可輸入其他, arg2 只是提示功能
以下位於 custom command class 的 Laravel example code 的意思是?
  • Example:
    <?php
    public function handle()
    {
    $name = $this->anticipate('What is your name?', function() {

    });
    }
  • Answer:
    當使用者輸入 command 時會跳出詢問視窗, 讓使用者輸入, 使用者每輸入一個字, 都會 pass 到 closure, 並依照 closure 內的邏輯輸出提示詞

# Multiple Choice Questions

以下位於 custom command class 的 Laravel example code 的意思是?
  • Example:
    <?php
    public function handle()
    {
    $name = $this->choice(
    'What is your name?',
    ['Taylor', 'Dayle'],
    $defaultIndex,
    $maxAttempts = null,
    $allowMultipleSelections = false
    );
    }
  • Answer:
    當使用者輸入 command 時會跳出 arg2 的選項讓使用者輸入, 即 Taylor 或 Dayle
    可設定 default index, 當使用者沒輸入時, 會將 default 值設為指定的 index
    $maxAttempts 顧名思義, 最大嘗試次數
    $allowMultipleSelections 即可選取多個選項

# Writing Output

以下位於 custom command class 的 Laravel example code 的意思是?
  • Example:
    <?php
    public function handle()
    {
    $this->info('Display this on the screen');
    }
  • Answer:
    顯示文字到 console, 文字為綠色
以下位於 custom command class 的 Laravel example code 的意思是?
  • Example:
    <?php
    public function handle()
    {
    $this->error('Something went wrong!');
    }
  • Answer:
    顯示文字到 console, 文字為紅色
以下位於 custom command class 的 Laravel example code 的意思是?
  • Example:
    <?php
    public function handle()
    {
    $this->line('Display this on the screen');
    }
  • Answer:
    顯示文字到 console, 文字為 plain text
以下位於 custom command class 的 Laravel example code 的意思是?
  • Example:
    <?php
    public function handle()
    {
    $this->newLine();

    // Write three blank lines...
    $this->newLine(3);
    }
  • Answer:
    顯示空行
    顯示 3 個空行

# Table Layouts

以下位於 custom command class 的 Laravel example code 的意思是?
  • Example:
    <?php
    public function handle()
    {
    $headers = ['Name', 'Email'];

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

    $this->table($headers, $users);
    }
  • Answer:
    當執行 console command 時, 以 table 的方式顯示訊息在 console, 使用 table method, arg1 為欄位名稱, arg2 為欄位內容

# Progress Bars

以下位於 custom command class 的 Laravel example code 的意思是?
  • Example:
    <?php
    public function handle()
    {
    $users = App\Models\User::all();

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

    $bar->start();

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

    $bar->advance();
    }

    $bar->finish();
    }
  • Answer:
    更多 progress bar 的應用, 可以參閱
    Symfony Progress Bar component 文件
    <?php
    // 當使用者執行 console command 時, 可以用 process bar 顯示進度
    public function handle()
    {
    $users = App\Models\User::all();

    // 這邊建立了 progress bar, 並指定有幾個 steps
    $bar = $this->output->createProgressBar(count($users));

    // progress bar 開始
    $bar->start();

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

    // 每跑過一個 user, 都 advance 一次
    $bar->advance();
    }

    // progress bar 結束
    $bar->finish();
    }


# Registering Command

以下位於 …/app/console/kernel 的 Laravel example code 的意思是?
  • Example:
    <?php
    protected function commands()
    {
    $this->load(__DIR__.'/Commands');
    $this->load(__DIR__.'/MoreCommands');

    // ...
    }
  • Answer:
    預設會註冊 app/Console/Commands 資料夾內的 command, 如果 command 是寫在其他資料夾, 也可以加在 kernel class 中的 commands method 內
以下位於 …/app/console/kernel 的 Laravel example code 的意思是?
  • Example:
    <?php
    protected $commands = [
    Commands\SendEmails::class
    ];
  • Answer:
    Laravel 預設會註冊位於 Console/Commands 資料夾內的 command, 除了新增註冊的資料夾位址外, 也可以在 Kernel class 的 commands property 中註冊單一 command


# Programmatically Executing Commands

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Route::get('/foo', function () {
    $exitCode = Artisan::call('email:send', [
    'user' => 1, '--queue' => 'default'
    ]);

    //
    });
  • Answer:
    可以從 CLI 之外的地方執行 artisan command, 使用 Artisan facade 的 call method, arg1 為 command name 或 class name 都可, arg2 為帶入該 command 的 parameters
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Route::get('/foo', function () {
    $exitCode = Artisan::call('email:send 1 --queue=default');
    //
    });
  • Answer:
    可以從 CLI 之外的地方執行 artisan command, 使用 Artisan facade 的 call method, 可使用 arg2 來帶入該 command 的 parameters, 也可直接在 arg1 輸入全部 command, 就像在 CLI 輸入一樣
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Route::get('/foo', function () {
    Artisan::queue('email:send', [
    'user' => 1, '--queue' => 'default'
    ])->onConnection('redis')->onQueue('commands');
    //
    });
  • Answer:
    將 Artisan command 排入 queue, 由 queue worker 去執行, 並指定 connection 以及 queue name

# Passing Array Values

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Route::get('/foo', function () {
    $exitCode = Artisan::call('email:send', [
    'user' => 1, '--id' => [5, 13]
    ]);
    });
  • Answer:
    使用 Artisan facade 在 CLI 之外的地方執行 command
    如果該 command 定義了 array options 或 array arguments, 可使用 array 的方式帶入

# Passing Boolean Values

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    $exitCode = Artisan::call('migrate:refresh', [
    '--force' => true,
    ]);
  • Answer:
    如果 command 的 options 為 boolean 類型, 可透過 ‘options’ => ‘boolean’ 的方式帶入

Calling Commands From Other Commands

以下位於 custom command class 的 Laravel example code 的意思是?
  • Example:
    <?php
    public function handle()
    {
    $this->call('email:send', [
    'user' => 1, '--queue' => 'default'
    ]);

    //
    }
  • Answer:
    在 custom command 中, 利用 call() 執行另外一個 command
以下位於 custom command class 的 Laravel example code 的意思是?
  • Example:
    <?php
    public function handle()
    {
    $this->callSilent('email:send', [
    'user' => 1, '--queue' => 'default'
    ]);

    //
    }
  • Answer:
    在 custom command 中, 利用 call() 執行另外一個 command, 並且不顯示其輸出


# Stub Customization

以下的 Laravel example command 的意思是?
  • Example:
    <?php
    php artisan stub:publish
  • Answer:
    Artisan console make command 被用來建立不同的 class, 像是 controllers, jobs, migrations, 以及 tests, Laravel 會根據你所輸入的 input, 使用 “stub” file 來產生這些 class
    如果你希望可以對 stub 檔案做更動的話, 可使用 stub:publish


# Events

Laravel Artisan 中, 會產生哪三個 event?
  • ArtisanStarting
  • CommandStarting
  • CommandFinished
Laravel Artisan event 中, ArtisanStarting 什麼時候觸發?

當 Artisan 開始執行時

Laravel Artisan event 中, CommandStarting 什麼時候觸發?

在 command 執行之前

Laravel Artisan event 中, CommandFinished 什麼時候觸發?

當 command 結束執行時

MySQL - 官方文件原子化翻譯 - 目錄 Tree 資料結構簡介

留言

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×