Artisan行接口名稱,它為你在開發(fā)過程中提供了很多有用的命令。通過強大的Symfony?Console組件驅(qū)動。想要查看所有可用的Artisan命令,可使用list
命令:
php artisan list
每個命令都可以用help
指令顯示命令描述及命令參數(shù)和選項。想要查看幫助界面,只需要在命令前加上help
就可以了:
php artisan help migrate
除了Artisan提供的命令之外,還可以構(gòu)建自己的命令。你可以將自定義命令存放在app/Console/Commands
目錄;當(dāng)然,你可以自己選擇存放位置,只要改命令可以基于composer.json
被自動加載。
要創(chuàng)建一個新命令,你可以使用Artisan命令make:console
:
php artisan make:console SendEmails
上述命令將會生成一個類app/Console/Commands/SendEmails.php
,當(dāng)創(chuàng)建命令時,--command
選項可用于分配終端命令名(在終端調(diào)用命令時用):
php artisan make:console SendEmails --command=emails:send
命令生成以后,需要填寫該類的signature
和description
屬性,這兩個屬性在調(diào)用list
顯示命令的時候會被用到。
handle
方法在命令執(zhí)行時被調(diào)用,你可以將所有命令邏輯都放在這個方法里面,讓我們先看一個命令例子。
我們可以在命令控制器的構(gòu)造函數(shù)中注入任何依賴,Laravel服務(wù)提供者將會在構(gòu)造函數(shù)中自動注入所有依賴類型提示。要增強代碼的復(fù)用性,保持代碼輕量級并讓它們延遲到應(yīng)用服務(wù)中完成任務(wù)是個不錯的實踐:
<?php
namespace App\Console\Commands;
use App\User;
use App\DripEmailer;
use Illuminate\Console\Command;
use Illuminate\Foundation\Inspiring;
class Inspire extends Command{
/**
* 控制臺命令名稱
*
* @var string
*/
protected $signature = 'email:send {user}';
/**
* 控制臺命令描述
*
* @var string
*/
protected $description = 'Send drip e-mails to a user';
/**
* The drip e-mail service.
*
* @var DripEmailer
*/
protected $drip;
/**
* 創(chuàng)建新的命令實例
*
* @param DripEmailer $drip
* @return void
*/
public function __construct(DripEmailer $drip)
{
parent::__construct();
$this->drip = $drip;
}
/**
* 執(zhí)行控制臺命令
*
* @return mixed
*/
public function handle()
{
$this->drip->send(User::find($this->argument('user')));
}
}
編寫控制臺命令的時候,通常通過參數(shù)和選項收集用戶輸入,Laravel使這項操作變得很方便:在命令中使用signature
屬性來定義我們期望的用戶輸入。signature
屬性通過一個優(yōu)雅的、路由風(fēng)格的語法允許你定義命令的名稱、參數(shù)以及選項。所有用戶提供的參數(shù)和選項都包含在大括號里:
/**
* 控制臺命令名稱
*
* @var string
*/
protected $signature = 'email:send {user}';
在本例中,該命令定義了一個必須參數(shù):user
。你還可以讓參數(shù)可選化并定義默認(rèn)的可選參數(shù)值:
// 選項參數(shù)...
email:send {user?}
// 帶默認(rèn)值的選項參數(shù)...
email:send {user=foo}
選項,和參數(shù)一樣,也是用戶輸入的一種格式,不同之處在于選項前面有兩個短劃線(–),我們可以這樣定義選項:
/**
* 控制臺命令名稱
*
* @var string
*/
protected $signature = 'email:send {user} {--queue}';
在本例中,--queue
開關(guān)在調(diào)用Artisan命令的時候被指定。如果--queue
開關(guān)被傳遞,其值時true
,否則其值是false
:
php artisan email:send 1 --queue
你還可以指定選項值被用戶通過=來分配:
/**
* 控制臺命令名稱
*
* @var string
*/
protected $signature = 'email:send {user} {--queue=}';
在本例中,用戶可以通過這樣的方式傳值:
php artisan email:send 1 --queue=default
還可以給選項分配默認(rèn)值:
email:send {user} {--queue=default}
你可以通過:分隔參數(shù)和描述來分配描述給輸入?yún)?shù)和選項:
/**
* 控制臺命令名稱
*
* @var string
*/
protected $signature = 'email:send
{user : The ID of the user}
{--queue= : Whether the job should be queued}';
在命令被執(zhí)行的時候,很明顯,你需要訪問命令獲取的參數(shù)和選項的值。使用argument
和option
方法即可實現(xiàn):
要獲取參數(shù)的值,通過argument
方法:
/**
* 執(zhí)行控制臺命令
*
* @return mixed
*/
public function handle(){
$userId = $this->argument('user');
}
如果你需要以數(shù)組形式獲取所有參數(shù)值,使用不帶參數(shù)的argument
:
$arguments = $this->argument();
選項值和參數(shù)值的獲取一樣簡單,使用option
方法,同argument
一樣如果要獲取所有選項值,可以調(diào)用不帶參數(shù)的option
方法:
// 獲取指定選項...
$queueName = $this->option('queue');
// 獲取所有選項...
$options = $this->option();
如果參數(shù)或選項不存在,返回null。
除了顯示輸出之外,你可能還要在命令執(zhí)行期間要用戶提供輸入。ask
?方法將會使用給定問題提示用戶,接收輸入,然后返回用戶輸入到命令:
/**
* 執(zhí)行控制臺命令
*
* @return mixed
*/
public function handle(){
$name = $this->ask('What is your name?');
}
secret
方法和ask
方法類似,但用戶輸入在終端對他們而言是不可見的,這個方法在問用戶一些敏感信息如密碼時很有用:
$password = $this->secret('What is the password?');
如果你需要讓用戶確認(rèn)信息,可以使用confirm
方法,默認(rèn)情況下,該方法返回false
,如果用戶輸入y
,則該方法返回true
:
if ($this->confirm('Do you wish to continue? [y|N]')) {
//
}
anticipate
方法可用于為可能的選項提供自動完成功能,用戶仍然可以選擇答案,而不管這些選擇:
$name = $this->anticipate('What is your name?', ['Taylor', 'Dayle']);
如果你需要給用戶預(yù)定義的選擇,可以使用choice
方法。用戶選擇答案的索引,但是返回給你的是答案的值。如果用戶什么都沒選的話你可以設(shè)置默認(rèn)返回的值:
$name = $this->choice('What is your name?', ['Taylor', 'Dayle'], false);
要將輸出發(fā)送到控制臺,使用info
,?comment
,?question
?和?error
方法,每個方法都會使用相應(yīng)的ANSI顏色以作標(biāo)識。
要顯示一條信息消息給用戶,使用info
方法。通常,在終端顯示為綠色:
/**
* 執(zhí)行控制臺命令
*
* @return mixed
*/
public function handle(){
$this->info('Display this on the screen');
}
要顯示一條錯誤消息,使用error
方法。錯誤消息文本通常是紅色:
$this->error('Something went wrong!');
table
?方法使輸出多行/列格式的數(shù)據(jù)變得簡單,只需要將頭和行傳遞給該方法,寬度和高度將基于給定數(shù)據(jù)自動計算:
$headers = ['Name', 'Email'];
$users = App\User::all(['name', 'email'])->toArray();
$this->table($headers, $users);
對需要較長時間運行的任務(wù),顯示進(jìn)度指示器很有用,使用該輸出對象,我們可以開始、前進(jìn)以及停止該進(jìn)度條。在開始進(jìn)度時你必須定義定義步數(shù),然后每走一步進(jìn)度條前進(jìn)一格:
$users = App\User::all();
$this->output->progressStart(count($users));
foreach ($users as $user) {
$this->performTask($user);
$this->output->progressAdvance();
}
$this->output->progressFinish();
想要了解更多,查看Symfony進(jìn)度條組件文檔。
命令編寫完成后,需要注冊到Artisan才可以使用,這可以在app/Console/Kernel.php
文件中完成。
在該文件中,你會在commans
屬性中看到一個命令列表,要注冊你的命令,只需將加到該列表中即可。當(dāng)Artisan啟動的時候,該屬性中列出的命令將會被服務(wù)容器解析被注冊到Artisan:
protected $commands = [
'App\Console\Commands\SendEmails'
];
有時候你可能希望在CLI之外執(zhí)行Artisan命令,比如,你可能希望在路由或控制器中觸發(fā)Artisan命令,你可以使用Artisan門面上的call
方法來完成這個。call
方法接收被執(zhí)行的命令名稱作為第一個參數(shù),命令參數(shù)數(shù)組作為第二個參數(shù),退出代碼被返回:
Route::get('/foo', function () {
$exitCode = Artisan::call('email:send', [
'user' => 1, '--queue' => 'default'
]);
});
使用Artisan上的queue
方法,你甚至可以將Artisan命令放到隊列中,這樣它們就可以通過后臺的隊列工作者來處理:
Route::get('/foo', function () {
Artisan::queue('email:send', [
'user' => 1, '--queue' => 'default'
]);
});
如果你需要指定不接收字符串的選項值,例如migrate:refresh
命令上的--force
標(biāo)識,可以傳遞布爾值true
或false
:
$exitCode = Artisan::call('migrate:refresh', [
'--force' => true,
]);
有時候你希望從一個已存在的Artisan命令中調(diào)用其它命令。你可以通過使用call
方法開實現(xiàn)這一目的。call
方法接收命令名稱和數(shù)組形式的命令參數(shù):
/**
* 執(zhí)行控制臺命令
*
* @return mixed
*/
public function handle(){
$this->call('email:send', [
'user' => 1, '--queue' => 'default'
]);
}
如果你想要調(diào)用其它控制臺命令并阻止其所有輸出,可以使用callSilent
方法。callSilent
方法和call
方法用法一致:
$this->callSilent('email:send', [
'user' => 1, '--queue' => 'default'
]);
更多建議: