イントロダクション

ArtisanはLaravelに含まれているコマンドラインインターフェイスです。アプリケーション開発全体で役に立つ、数多くのコマンドを提供しています。使用可能な全Artisanコマンドを確認するには、listコマンドを使います。

php artisan list

全てのコマンドは「ヘルプ」が用意されており、説明と使用できる引数、オプションを表示します。ヘルプを表示するにはhelpに続いてコマンド名を入力してください。

php artisan help migrate

コマンド記述

Artisanに用意されているコマンドに加え、独自のカスタムコマンドも構築できます。コマンドは通常、app/Console/Commandsディレクトリへ設置します。しかし、Composerによりコマンドがロードできる場所であるならば、自由に設置場所を選べます。

コマンド生成

新しいコマンドを作成するには、make:command Artisanコマンドを使います。このコマンドは、app/Console/Commandsディレクトリへ新しいコマンドクラスを設置します。アプリケーションにこのディレクトリがなくても心配ありません。最初に、make:command Artisanコマンドを実行するときに作成されます。生成されたコマンドには、すべてのコマンドで必要な、プロパティとメソッドがデフォルトで一揃い用意されています。

php artisan make:command SendEmails

Artisan CLIにより実行する前に、コマンド登録を続けて行う必要があります。

コマンド構造

コマンドが生成できたら、listスクリーンでそのコマンドが表示できるように、クラスのsignaturedescriptionプロパティを指定してください。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 listphp 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

値を取るオプション

次に、ユーザによる値の入力を基体するオプションを確認しましょう。ユーザによりオプションの値の指定が必要である場合、オプション名は=記号ではじめます。

/**
 * コンソールコマンドの名前と引数、オプション
 *
 * @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

入力の取得

コマンド実行時に指定された引数やオプションの値にアクセスする必要が明らかにあります。そのために、argumentoptionメソッドを使用して下さい。

/**
 * コンソールコマンドの実行
 *
 * @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を返します。プロンプトに対してyyesが入力されると、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);

出力の書き出し

コンソールに出力するには、lineinfocommentquestionerrorメソッドを使います。その名前が表す目的で使用し、それぞれ適当な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フラッグのように、文字列を受け取らないオプションの値を指定する必要がある場合は、論理値でtruefalseを指定します。

$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'
]);