# Artisan 控制臺
- [簡介](#introduction)
- [編寫命令](#writing-commands)
- [生成命令](#generating-commands)
- [命令結構](#command-structure)
- [閉包命令](#closure-commands)
- [定義輸入期望](#defining-input-expectations)
- [參數](#arguments)
- [選項](#options)
- [輸入數組](#input-arrays)
- [輸入說明](#input-descriptions)
- [I/O 命令](#command-io)
- [檢索輸入](#retrieving-input)
- [交互式輸入](#prompting-for-input)
- [編寫輸出](#writing-output)
- [注冊命令](#registering-commands)
- [以編程方式執行命令](#programmatically-executing-commands)
- [從其他命令調用命令](#calling-commands-from-other-commands)
<a name="introduction"></a>
## 簡介
Artisan 是 Laravel 自帶的命令行接口,它提供了許多實用的命令來幫助你構建 Laravel 應用。要查看所有可用的 Artisan 命令的列表,可以使用 `list` 命令:
php artisan list
每個命令包含了「幫助」界面,它會顯示并概述命令的可用參數及選項。只需要在命令前面加上 `help` 即可查看命令幫助界面:
php artisan help migrate
#### Laravel REPL
所有 Laravel 應用都包含了 Tinker,一個基于 [PsySH](https://github.com/bobthecow/psysh) 包提供支持的 REPL。 `Tinker` 讓你可以在命令行中與你整個的 Laravel 應用進行交互,包括 Eloquent ORM、任務、事件等等。運行 Artisan 命令 `tinker` 進入 Tinker 環境:
php artisan tinker
<a name="writing-commands"></a>
## 編寫命令
除 Artisan 提供的命令之外,還可以構建自己的自定義命令。命令默認存儲在 `app/Console/Commands` 目錄,你也可以修改 `composer.json` 文件來指定你想要存放的目錄。
<a name="generating-commands"></a>
### 生成命令
要創建一個新的命令,可以使用 Artisan 命令 `make:command`。這個命令會在 `app/Console/Commands` 目錄中創建一個新的命令類。 不必擔心應用中不存在這個目錄,因為它會在你第一次運行 Artisan 命令 `make:command` 時創建。生成的命令會包括所有命令中默認存在的屬性和方法:
php artisan make:command SendEmails
<a name="command-structure"></a>
### 命令結構
命令生成后,應先填寫類的 `signature` 和 `description` 屬性,這會在使用 `list` 命令的時候顯示出來。執行命令時會調用 `handle` 方法,你可以在這個方法中放置命令邏輯。
> {tip} 為了更好的代碼復用,最好保持你的控制臺代碼輕量并讓它們延遲到應用服務中完成。在下面的例子中,請注意,我們注入了一個服務類來完成發送郵件的「重任」。
讓我們看一個簡單的例子。注意,我們可以在 Command 的構造函數中注入我們需要的任何依賴項。Laravel [服務容器](/docs/{{version}}/container) 將會自動注入所有在構造函數中的帶類型約束的依賴:
<?php
namespace App\Console\Commands;
use App\User;
use App\DripEmailer;
use Illuminate\Console\Command;
class SendEmails extends Command
{
/**
* 控制臺命令 signature 的名稱。
*
* @var string
*/
protected $signature = 'email:send {user}';
/**
* 控制臺命令說明。
*
* @var string
*/
protected $description = 'Send drip e-mails to a user';
/**
* 郵件服務的 drip 屬性。
*
* @var DripEmailer
*/
protected $drip;
/**
* 創建一個新的命令實例。
*
* @param DripEmailer $drip
* @return void
*/
public function __construct(DripEmailer $drip)
{
parent::__construct();
$this->drip = $drip;
}
/**
* 執行控制臺命令。
*
* @return mixed
*/
public function handle()
{
$this->drip->send(User::find($this->argument('user')));
}
}
<a name="closure-commands"></a>
### 閉包命令
基于閉包的命令提供一個用類替代定義控制臺命令的方法。同樣的,路由閉包是控制器的一種替代方法,而命令閉包可以視為命令類的替代方法。在 `app/Console/Kernel.php` 文件的 `commands` 方法中, Laravel 加載了 `routes/console.php` 文件:
/**
* 注冊應用的基于閉包的命令。
*
* @return void
*/
protected function commands()
{
require base_path('routes/console.php');
}
雖然這個文件沒有定義 HTTP 路由,它也將基于控制臺的入口點(路由)定義到應用中。在這個文件中,你可以使用 `Artisan::command` 方法定義所有基于閉包的路由。`command` 方法接收兩個參數:[命令簽名](#defining-input-expectations) 和一個接收命令參數和選項的閉包:
Artisan::command('build {project}', function ($project) {
$this->info("Building {$project}!");
});
閉包綁定底層的命令實例,因此你可以完全訪問通常可以在完整命令類中訪問的所有輔助方法。
#### 類型提示依賴
除了接收命令的參數和選項外,命令閉包也可以使用類型提示從 [服務容器](/docs/{{version}}/container) 中解析你想要的其他依賴關系:
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');
<a name="defining-input-expectations"></a>
## 定義輸入期望
在編寫控制臺命令時,通常是通過參數和選項來收集用戶輸入。Laravel 可以非常方便地在你的命令里用 `signature` 屬性來定義你期望用戶輸入的內容。`signature` 屬性允許你使用單一且可讀性非常高的、類似路由的語法定義命令的名稱、參數和選項。
<a name="arguments"></a>
### 參數
所有用戶提供的參數及選項都被包含在花括號中。在下面的例子中,這個命令定義了一個 **必須** 的參數 `user` :
/**
* 控制臺命令 signature 的名稱。
*
* @var string
*/
protected $signature = 'email:send {user}';
你也可以創建可選參數,并定義參數的默認值:
// 可選參數...
email:send {user?}
// 帶有默認值的可選參數...
email:send {user=foo}
<a name="options"></a>
### 選項
選項,如參數,是用戶輸入的另一種格式。當命令行指定選項時,它們以兩個連字符 (`--`) 作為前綴。有兩種類型的選項:接收值和不接受值。不接收值的選項作為布爾值的 「開關」。讓我們看一下這種類型的選項的例子:
/**
* 控制臺命令 signature 的名稱。
*
* @var string
*/
protected $signature = 'email:send {user} {--queue}';
在這個例子中,可以在調用Artisan命令時指定 `--queue` 開關。如果 `--queue` 開關被傳遞,該選項的值為 `true` ,否則為 `false` :
php artisan email:send 1 --queue
<a name="options-with-values"></a>
#### 帶值的選項
接下來,我們來看一個帶值的選項。如果用戶必須為選項指定一個值,需要用一個等號 `=` 作為選項名稱的后綴:
/**
* 控制臺命令 signature 的名稱。
*
* @var string
*/
protected $signature = 'email:send {user} {--queue=}';
在這個例子中, 用戶可以傳遞該選項的值,如下所示:
php artisan email:send 1 --queue=default
你可以通過在選項名稱后面指定默認值來設定選項的默認值。如果用戶沒有傳遞選項值,將使用設定的默認值:
email:send {user} {--queue=default}
<a name="option-shortcuts"></a>
#### 選項簡寫
要在定義選項時指定簡寫,你可以在選項名稱前指定它,并且使用 `|` 分隔符將簡寫與完整選項名稱分隔開:
email:send {user} {--Q|queue}
<a name="input-arrays"></a>
### 輸入數組
如果你想定義參數或選項你可以使用 `*` 符號來期望輸入數組。首先,我們先看一個指定數組參數的實例:
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
<a name="input-descriptions"></a>
### 輸入說明
你可以通過冒號為輸入參數和選項分配說明文字。如果你需要一點額外的空間來定義你的命令,可以隨意將多個行分開:
/**
* 設置控制臺命令的 signature 屬性。
*
* @var string
*/
protected $signature = 'email:send
{user : The ID of the user}
{--queue= : Whether the job should be queued}';
<a name="command-io"></a>
## I/O 命令
<a name="retrieving-input"></a>
### 檢索輸入
在命令執行時,你可以使用 `argument` 和 `option` 方法獲取命令的參數和選項:
/**
* 執行控制臺命令。
*
* @return mixed
*/
public function handle()
{
$userId = $this->argument('user');
//
}
如果你需要將所有參數以 `array` 檢索,就調用 `arguments` 方法:
$arguments = $this->arguments();
可以使用 `option` 方法像 `arguments` 一樣容易地檢索選項。要將所有選項作為 `array` 檢索,請調用 `options` 方法:
// 檢索特定選項...
$queueName = $this->option('queue');
// 檢索所有選項...
$options = $this->options();
如果參數或選項不存在,則返回 `null` 。
<a name="prompting-for-input"></a>
### 交互式輸入
除了顯示輸出外,你還可以要求用戶在執行命令時提供輸入。`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'], $default);
<a name="writing-output"></a>
### 編寫輸出
可以使用 `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);
#### 進度條
對于長時間運行的任務,顯示進度指示符可能會很有用。使用輸出對象,我們可以啟動、推進和停止進度條。首先,定義進程將遍歷的步驟總數。然后,在處理每個項目后推進進度欄:
$users = App\User::all();
$bar = $this->output->createProgressBar(count($users));
foreach ($users as $user) {
$this->performTask($user);
$bar->advance();
}
$bar->finish();
更多信息請查閱 [Symfony 進度條組件文檔](https://symfony.com/doc/2.7/components/console/helpers/progressbar.html) 。
<a name="registering-commands"></a>
## 注冊命令
由于在控制臺內核的 `commands` 方法中調用了 `load` 方法,所以 `app/Console/Commands` 目錄下的所有命令都將自動注冊到 Artisan。 實際上,你可以自由地調用 `load` 方法來掃描 Artisan 命令的其他目錄:
/**
* 注冊應用程序的命令。
*
* @return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
$this->load(__DIR__.'/MoreCommands');
// ...
}
你還可以通過將其類名添加到 `app/Console/Kernel.php` 文件的 `$command` 屬性來手動注冊命令。當 Artisan 啟動時,該屬性中列出的所有命令將由 [服務容器](/docs/{{version}}/container) 解析并在 Artisan 注冊:
protected $commands = [
Commands\SendEmails::class
];
<a name="programmatically-executing-commands"></a>
## 以編程方式執行命令
有時你可能希望在 CLI 之外執行 Artisan 命令。例如,你可能希望從路由或控制器觸發 Artisan 命令。你可以使用 `Artisan` facade 上的 `call` 方法來完成。 `call` 方法接受命令的名稱作為第一個參數,命令參數的數組作為第二個參數。結束碼會被返回:
Route::get('/foo', function () {
$exitCode = Artisan::call('email:send', [
'user' => 1, '--queue' => 'default'
]);
//
});
在 `Artisan` facade 上使用 `queue` 方法,可以將 Artisan 命令交由 [隊列工作進程](/docs/{{version}}/queues) 在后臺進行處理。在使用此方法之前,請確保已配置隊列并運行了隊列監聽器:
Route::get('/foo', function () {
Artisan::queue('email:send', [
'user' => 1, '--queue' => 'default'
]);
//
});
如果需要指定不接受字符串值的選項的值,例如 `migrate:refresh` 命令中的 `--force` 標志,則可以傳遞 `true` 或 `false` :
$exitCode = Artisan::call('migrate:refresh', [
'--force' => true,
]);
<a name="calling-commands-from-other-commands"></a>
### 從其他命令調用命令
有時候你希望從現有的 Artisan 命令中調用其它命令。你可以使用 `call` 方法。`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'
]);
## 譯者署名
| 用戶名 | 頭像 | 職能 | 簽名 |
| --- | --- | --- | --- |
| [@laravelleon](https://laravel-china.org/users/18113) | <img class="avatar-66 rm-style" src="https://dn-phphub.qbox.me/uploads/avatars/18113_1503316311.png?imageView2/1/w/100/h/100"> | 翻譯 | You may delay , but the time will not . [@Leonzai](https://github.com/leonzai/) at Github |
---
> {note} 歡迎任何形式的轉載,但請務必注明出處,尊重他人勞動共創開源社區。
>
> 轉載請注明:本文檔由 Laravel China 社區 [laravel-china.org](https://laravel-china.org) 組織翻譯,詳見 [翻譯召集帖](https://laravel-china.org/topics/5756/laravel-55-document-translation-call-come-and-join-the-translation)。
>
> 文檔永久地址: https://d.laravel-china.org
- 說明
- 翻譯說明
- 發行說明
- 升級說明
- 貢獻導引
- 入門指南
- 安裝
- 配置信息
- 文件夾結構
- HomeStead
- Valet
- 核心架構
- 請求周期
- 服務容器
- 服務提供者
- 門面(Facades)
- Contracts
- 基礎功能
- 路由
- 中間件
- CSRF 保護
- 控制器
- 請求
- 響應
- 視圖
- 重定向
- Session
- 表單驗證
- 錯誤與日志
- 前端開發
- Blade 模板
- 本地化
- 前端指南
- 編輯資源 Mix
- 安全
- 用戶認證
- API認證
- 用戶授權
- 加密解密
- 哈希
- 重置密碼
- 綜合話題
- Artisan 命令行
- 廣播系統
- 緩存系統
- 集合
- 事件系統
- 文件存儲
- 輔助函數
- 郵件發送
- 消息通知
- 擴展包開發
- 隊列
- 任務調度
- 數據庫
- 快速入門
- 查詢構造器
- 分頁
- 數據庫遷移
- 數據填充
- Redis
- Eloquent ORM
- 快速入門
- 模型關聯
- Eloquent 集合
- 修改器
- API 資源
- 序列化
- 測試
- 快速入門
- HTTP 測試
- 瀏覽器測試 Dusk
- 數據庫測試
- 測試模擬器
- 官方擴展包
- Cashier 交易工具包
- Envoy 部署工具
- Horizon
- Passport OAuth 認證
- Scout 全文搜索
- Socialite 社交化登錄
- 交流說明