コンソールコマンド
イントロダクション
ArtisanはLaravelに含まれているコマンドラインインターフェイスです。アプリケーション開発全体で役に立つ、数多くのコマンドを提供しています。使用可能な全Artisanコマンドを確認するには、list
コマンドを使います。
php artisan list
全てのコマンドは「ヘルプ」が用意されており、説明と使用できる引数、オプションを表示します。ヘルプを表示するにはhelp
に続いてコマンド名を入力してください。
php artisan help migrate
コマンド記述
Artisanに用意されているコマンドに加え、独自のカスタムコマンドも構築できます。コマンドは通常、app/Console/Commands
ディレクトリへ設置します。しかし、Composerによりコマンドがロードできる場所であるならば、自由に設置場所を選べます。
コマンド生成
To create a new command, use the make:command
Artisan
command. This command will create a new command class in the
app/Console/Commands
directory. Don't worry if you this
directory does not exist in your application, since it will be created
the first time you run the make:command
Artisan command.
The generated command will include the default set of properties and
methods that are present on all commands:
php artisan make:command SendEmails
コマンド構造
コマンドが生成できたら、list
スクリーンでそのコマンドが表示できるように、クラスのsignature
とdescription
プロパティを指定してください。handle
メソッドは、コマンド実行時に呼び出されます。コマンドのロジックは、このメソッドの中へ記述します。
Tip!! コンソールコマンドを軽いままにし、実行内容をアプリケーションサービスとして遅らせるのは、コードの再利用性のためのグッドプラクティスです。以下の例で、メール送信の「重荷を軽く」するために、サービスクラスを注入しているところに注目してください。
コマンドのサンプルを見てみましょう。コマンドのコンストラクタで、必要な依存を注入できるところに注意を払ってください。Laravelのサービスコンテナは、コンストラクタでタイプヒントとされた依存をすべて自動的に注入します。
<?php
namespace App\Console\Commands;
use App\User;
use App\DripEmailer;
use Illuminate\Console\Command;
class SendEmails extends Command
{
/**
* コンソールコマンドの名前と引数、オプション
*
* @var string
*/
protected $signature = 'email:send {user}';
/**
* コンソールコマンドの説明
*
* @var string
*/
protected $description = 'Send drip e-mails to a user';
/**
* drip Eメールサービス
*
* @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')));
}
}
クロージャコマンド
クロージャベースコマンドは、クラスによりコンソールコマンドを定義する方法の代替手法を提供します。ルートクロージャがコントローラの代替であるのと同じように、コマンドクロージャはコマンドクラスの代替だと考えてください。app/Console/Kernel.php
ファイルのcommands
メソッドの中で、Laravelはroutes/console.php
ファイルをロードしています。
/**
* アプリケーションのクロージャベースコマンドの登録
*
* @return void
*/
protected function commands()
{
require base_path('routes/console.php');
}
このファイルがHTTPルートを定義していないとしても、アプリケーションへのコンソールベースのエントリポイント(ルート)を定義しているのです。Artisan::command
メソッドを使い、全クロージャベースルートをこのファイル中で定義します。command
メソッドはコマンドの使い方と、コマンドの引数とオプションを受け取るクロージャを引数として受け取ります。
Artisan::command('build {project}', function ($project) {
$this->info("Building {$project}!");
});
クロージャは裏で動作するコマンドインスタンスと結合します。そのため、完全なコマンドクラス上でアクセスできる、通常のヘルパメソッドにすべてアクセスできます。
依存のタイプヒント
コマンドの引数とオプションに付け加え、コマンドクロージャはタイプヒントによる追加の依存を受け取り、それらはサービスコンテナにより依存解決されます。
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');
コマンドライン指定の定義
コンソールコマンドを書く場合、引数やオプションによりユーザから情報を入力してもらうのが一般的です。コマンドのsignature
プロパティにユーザに期待する入力を記述することにより、Laravelではとても便利に定義できます。signature
プロパティー1行でわかりやすいルート定義のような記法により、コマンドの名前と引数、オプションを定義できます。
引数
ユーザから入力してもらう引数とオプションは全て波括弧で囲みます。以下の例の場合、必須のuser
コマンド引数を定義しています。
/**
* コンソールコマンドの名前と引数、オプション
*
* @var string
*/
protected $signature = 'email:send {user}';
任意の引数やデフォルト値を指定することも可能です。
// 任意指定な引数
email:send {user?}
// デフォルト値を持つ、任意指定な引数
email:send {user=foo}
オプション
オプションも引数と同様にユーザからの入力です。コマンドラインで指定する場合、2つのハイフン(--
)を先頭に付けます。値を取るものと、取らないもの、2つのタイプのオプションがあります。値を取らないオプションは、論理的な「スイッチ」として動作します。このタイプのオプションを確認しましょう。
/**
* コンソールコマンドの名前と引数、オプション
*
* @var string
*/
protected $signature = 'email:send {user} {--queue}';
この例の場合、Artisanコマンド起動時に、--queue
スイッチを指定できるようになります。--queue
スイッチが指定されると、オプションの値はtrue
になります。そうでなければ、値はfalse
になります。
php artisan email:send 1 --queue
オプション With Values
次に、ユーザによる値の入力を基体するオプションを確認しましょう。ユーザによりオプションの値の指定が必要である場合、オプション名は=
記号ではじめます。
/**
* コンソールコマンドの名前と引数、オプション
*
* @var string
*/
protected $signature = 'email:send {user} {--queue=}';
この例では、次のようにオプションに値を指定します。
php artisan email:send 1 --queue=default
オプション名の後に値を指定することにより、オプションのデフォルト値を指定できます。ユーザにより値が指定されない場合、デフォルト値が指定されます。
email:send {user} {--queue=default}
オプションショートカット
オプション定義時にショートカットを割りつけるには、完全なオプション名の前に|で区切り、ショートカットを指定してください。
email:send {user} {--Q|queue}
入力配列
引数やオプションで、配列による入力を定義したい場合は、*
文字を使います。最初に引数の配列指定の例を、見てみましょう。
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
入力の説明
入力の引数とオプションの説明をパラメータと説明をコロンで分けることで指定できます。コマンドを定義するため、もう少し余裕が欲しければ、定義を複数行へ自由に分割してください。
/**
* コンソールコマンドの名前と引数、オプション
*
* @var string
*/
protected $signature = 'email:send
{user : The ID of the user}
{--queue= : Whether the job should be queued}';
コマンドI/O
入力の取得
コマンド実行時に指定された引数やオプションの値にアクセスする必要が明らかにあります。そのために、argument
とoption
メソッドを使用して下さい。
/**
* コンソールコマンドの実行
*
* @return mixed
*/
public function handle()
{
$userId = $this->argument('user');
//
}
全引数を「配列」で受け取りたければ、argument
を呼んでください。
$arguments = $this->arguments();
引数と同様、とても簡単にoption
メソッドでオプションを取得できます。argument
メソッドと同じように呼びだせば、全オプションを「配列」で取得できます。
// 特定オプションの取得
$queueName = $this->option('queue');
// 全オプションの取得
$options = $this->options();
引数やオプションが存在していない場合、null
が返されます。
入力のプロンプト
コマンドラインに付け加え、コマンド実行時にユーザに入力を尋ねることもできます。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
を入力すると、true
を返します。
if ($this->confirm('Do you wish to continue? [y|N]')) {
//
}
自動補完
anticipate
メソッドは可能性のある選択肢の、自動補完機能を提供するために使用します。ユーザは表示される自動補完の候補にかかわらず、どんな答えも返答できます。
$name = $this->anticipate('What is your name?', ['Taylor', 'Dayle']);
複数選択の質問
あらかじめ決められた選択肢をユーザから選んでもらいたい場合は、choice
メソッドを使用します。何も選ばれなかった場合に返ってくるデフォルト値を指定することも可能です。
$name = $this->choice('What is your name?', ['Taylor', 'Dayle'], $default);
出力の書き出し
コンソールに出力するには、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のプログレスバーコンポーネントのドキュメントで確認してください。
コマンド登録
コマンドが完成したら、Artisanに登録する必要があります。全コマンドはapp/Console/Kernel.php
ファイルの中で登録されています。このファイルのcommands
プロパティで、コマンドがリストされているのに気がつくと思います。コマンドを登録するには、ただコマンドクラス名をリストに追加するだけです。Artisanが起動した時点でこのプロパティーの全コマンドはサービスコンテナにより依存解決され、Artisanへ登録されます。
protected $commands = [
Commands\SendEmails::class
];
プログラムによるコマンド実行
ArtisanコマンドをCLI以外から実行したい場合もあるでしょう。たとえばルートやコントローラーからArtisanコマンドを起動したい場合です。Artisan
ファサードのcall
メソッドで実行できます。call
メソッドでは第1引数にコマンド名を指定します。第2引数にコマンドのパラメーターを配列で指定します。exitコードが返されます。
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
フラッグのように、文字列を受け取らないオプションの値を指定する必要がある場合は、論理値でtrue
やfalse
を指定します。
$exitCode = Artisan::call('migrate:refresh', [
'--force' => true,
]);
他のコマンドからの呼び出し
存在する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'
]);