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