イントロダクション

Artisan(アーティザン:職人)とはLaravelを構成しているコマンドラインインターフェイスの名前です。アプリケーション開発で役立つ数多くのコマンドを用意しています。パワフルなSymfonyコンソールコンポーネントを利用し動いています。利用可能なArtisanコマンドの全リストを確認するには、listコマンドを使用してください。

php artisan list

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

php artisan help migrate

コマンド記述

あらかじめ提供されているArtisanに付け加え、アプリケーションで動かす独自のカスタムコマンドを構築することも可能です。app/Console/Commandsディレクトリーにカスタムコマンドを保存してください。しかし、composer.jsonで設定しコマンドがオートロードされる限り、どこにでも好きな場所に置くことができます。

新しいコマンドを生成するにはArtisanコマンドのmake:consoleを使用し、開発に取り掛かるために便利なコマンドのひな形を生成してください。

php artisan make:console SendEmails

上のコマンドはapp/Console/Commands/SendEmails.phpにクラスを生成します。生成時に--commandオプションを使用すれば、コマンド名を指定することができます。

php artisan make:console SendEmails --command=emails:send

コマンド構造

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

handleメソッドがコマンド実行時に呼び出されます。このメソッドにどんなコマンドロジックも置くことができます。サンプルのコマンドを見てみましょう。

コマンドのコンストラクターで必要な依存を注入できることに注目しましょう。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')));
    }
}

コマンドI/O

入力エクスペクションの定義

コンソールコマンドを書く場合、引数やオプションによりユーザーから情報を入力してもらうのは一般的です。コマンドのsignatureプロパティにユーザーに期待する入力を記述することにより、Laravelではとても便利に定義できます。signatureプロパティー一行でわかりやすいルート定義のような記法により、コマンドの名前と引数、オプションを定義できます。

ユーザーから入力してもらう引数とオプションは全て波括弧で囲みます。以下の例の場合、必須のuserコマンド引数を定義しています。

/**
 * コンソールコマンドの名前と引数、オプション
 *
 * @var string
 */
protected $signature = 'email:send {user}';

任意の引数やデフォルト値を指定することも可能です。

// 任意の引数…
email:send {user?}

// 任意の引数とデフォルト値…
email:send {user=foo}

オプションも引数と同様にユーザーからの入力です。しかし、コマンドラインで指定する場合、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}

入力の説明

入力の引数とオプションの説明をコロンで分けて指定できます。

/**
 * コンソールコマンドの名前と引数、オプション
 *
 * @var string
 */
protected $signature = 'email:send
                        {user : The ID of the user}
                        {--queue= : Whether the job should be queued}';

入力の取得

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

引数の値を取得するには、argumentを使用します。

/**
 * コンソールコマンドの実行
 *
 * @return mixed
 */
public function handle()
{
    $userId = $this->argument('user');

    //
}

全引数を「配列」で受け取りたければ、引数を付けずにargumentを呼んでください。

$arguments = $this->argument();

引数と同様、とても簡単にoptionメソッドでオプションを取得できます。argumentメソッドと同じように引数を付けずに呼びだせば、全オプションを「配列」で取得できます。

// 特定のオプションの取得…
$queueName = $this->option('queue');

// 全オプションの取得…
$options = $this->option();

引数やオプションが存在していない場合、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'], false);

出力の書き出し

コンソールに出力するには、lineinfocommentquestionerrorメソッドを使います。その名前が表す目的で使用し、それぞれ適当なANSIカラーが表示に使われます。

ユーザーにメッセージを知らせる場合は、infoメソッドを使用します。通常、これにより緑のテキストがコンソールに表示されます。

/**
 * コンソールコマンドの実行
 *
 * @return mixed
 */
public function handle()
{
    $this->info('これがスクリーンに表示される');
}

エラーメッセージを表示する場合は、errorメソッドです。エラーメッセージは通常赤で表示されます。

$this->error('何かがおかしい!');

プレーンなコンソール出力を行いたい場合は、lineメソッドを使います。lineメソッドは表示に特定の色を利用しません。

$this->line('これがスクリーンに表示される');

テーブルレイアウト

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