#はじめに
Artisan は Laravel に含まれるコマンドラインインターフェイスです。Artisan はアプリケーションのルートにある artisan スクリプトとして存在し、アプリケーション構築時に役立つ多くの便利なコマンドを提供します。利用可能な Artisan コマンドの一覧を表示するには、list コマンドを使います。
php artisan list
すべてのコマンドには「ヘルプ」画面があり、利用可能な引数やオプションの説明が表示されます。ヘルプ画面を表示するには、コマンド名の前に help を付けます。
php artisan help migrate
#Laravel Sail
Laravel Sail をローカル開発環境として使っている場合は、Artisan コマンドを実行する際に sail コマンドラインを使うことを忘れないでください。Sail はアプリケーションの Docker コンテナ内で Artisan コマンドを実行します。
./vendor/bin/sail artisan list
#Tinker (REPL)
Laravel Tinker は Laravel フレームワーク向けの強力な REPL で、PsySH パッケージによって動作しています。
#インストール
すべての Laravel アプリケーションにはデフォルトで Tinker が含まれています。ただし、以前にアプリケーションから削除した場合は、Composer を使って再インストールできます。
composer require laravel/tinker
Laravel アプリケーションと対話する際にホットリロードや複数行コード編集、自動補完を求めるなら、Tinkerwell を試してみてください!
#使い方
Tinker を使うと、Eloquent モデル、ジョブ、イベントなどを含む Laravel アプリケーション全体とコマンドライン上で対話できます。Tinker 環境に入るには、tinker Artisan コマンドを実行します。
php artisan tinker
vendor:publish コマンドを使って Tinker の設定ファイルを公開できます。
php artisan vendor:publish --provider="Laravel\Tinker\TinkerServiceProvider"
dispatch ヘルパ関数と Dispatchable クラスの dispatch メソッドは、ジョブをキューに登録するためにガベージコレクションに依存しています。そのため、tinker 使用時は Bus::dispatch または Queue::push を使ってジョブをディスパッチしてください。
#許可されたコマンド一覧
Tinker は「許可」リストを使って、シェル内で実行可能な Artisan コマンドを制御します。デフォルトでは clear-compiled、down、env、inspire、migrate、optimize、up コマンドが実行可能です。さらに許可したいコマンドがあれば、tinker.php 設定ファイルの commands 配列に追加してください。
'commands' => [
// App\Console\Commands\ExampleCommand::class,
],
#エイリアスにしないクラス
通常、Tinker は対話中にクラスを自動的にエイリアスしますが、特定のクラスをエイリアスしないように設定できます。tinker.php 設定ファイルの dont_alias 配列にクラスを列挙してください。
'dont_alias' => [
App\Models\User::class,
],
#コマンドの作成
Artisan に付属するコマンドに加えて、独自のカスタムコマンドを作成できます。コマンドは通常 app/Console/Commands ディレクトリに保存しますが、Composer で読み込める限り任意の場所に置けます。
#コマンドの生成
新しいコマンドを作成するには、make:command Artisanコマンドを使用できます。このコマンドは、app/Console/Commands ディレクトリに新しいコマンドクラスを作成します。このディレクトリがアプリケーションに存在しなくても心配いりません。make:command Artisanコマンドを初めて実行するときに自動的に作成されます。
php artisan make:command SendEmails
#コマンドの構造
コマンドを生成したら、クラスの signature と description プロパティに適切な値を設定してください。これらは list 画面でコマンドを表示する際に使われます。signature は コマンドの入力定義にも使います。handle メソッドはコマンド実行時に呼ばれ、ここにコマンドの処理を記述します。
例としてコマンドを見てみましょう。handle メソッドの引数で必要な依存を受け取れます。Laravel の サービスコンテナ が型ヒントに基づいて自動的に注入します。
<?php
namespace App\Console\Commands;
use App\Models\User;
use App\Support\DripEmailer;
use Illuminate\Console\Command;
class SendEmails extends Command
{
/**
* コンソールコマンドの名前とシグネチャ
*
* @var string
*/
protected $signature = 'mail:send {user}';
/**
* コンソールコマンドの説明
*
* @var string
*/
protected $description = 'ユーザーにマーケティングメールを送信する';
/**
* コンソールコマンドを実行する
*/
public function handle(DripEmailer $drip): void
{
$drip->send(User::find($this->argument('user')));
}
}
コードの再利用性を高めるため、コンソールコマンドは軽量に保ち、処理はアプリケーションのサービスに委譲するのが良い習慣です。上記の例では、メール送信の重い処理をサービスクラスに任せています。
#クロージャコマンド
クロージャベースのコマンドは、クラスとして定義する代わりの方法です。ルートクロージャがコントローラーの代わりになるのと同様に、コマンドクロージャはコマンドクラスの代わりと考えられます。app/Console/Kernel.php の commands メソッド内で Laravel は routes/console.php ファイルを読み込みます。
/**
* アプリケーションのクロージャベースコマンドを登録する
*/
protected function commands(): void
{
require base_path('routes/console.php');
}
このファイルは HTTP のルートを定義するわけではありませんが、アプリケーションへのコンソールベースのエントリポイント(ルート)を定義します。 このファイル内で、Artisan::command メソッドを使ってクロージャベースのコンソールコマンドをすべて定義できます。 command メソッドは2つの引数を受け取ります: コマンド署名 と、コマンドの引数およびオプションを受け取るクロージャです:
Artisan::command('mail:send {user}', function (string $user) {
$this->info("Sending email to: {$user}!");
});
クロージャは基底のコマンドインスタンスにバインドされているため、通常のコマンドクラスで使えるヘルパーメソッドにすべてアクセスできます。
#依存の型ヒント
コマンドの引数やオプションに加え、クロージャコマンドは サービスコンテナ から解決したい依存を型ヒントで受け取れます。
use App\Models\User;
use App\Support\DripEmailer;
Artisan::command('mail:send {user}', function (DripEmailer $drip, string $user) {
$drip->send(User::find($user));
});
#クロージャコマンドの説明
クロージャベースのコマンドを定義する際、purpose メソッドで説明を追加できます。この説明は php artisan list や php artisan help 実行時に表示されます。
Artisan::command('mail:send {user}', function (string $user) {
// ...
})->purpose('ユーザーにマーケティングメールを送信する');
#分離可能なコマンド
この機能を使うには、アプリケーションのデフォルトキャッシュドライバーが memcached、redis、dynamodb、database、file、または array である必要があります。また、すべてのサーバーが同じ中央キャッシュサーバーと通信している必要があります。
同時に一つのコマンドだけが実行されるようにしたい場合があります。その場合、コマンドクラスに Illuminate\Contracts\Console\Isolatable インターフェイスを実装します。
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Contracts\Console\Isolatable;
class SendEmails extends Command implements Isolatable
{
// ...
}
コマンドが Isolatable とマークされると、Laravel は自動的に --isolated オプションを追加します。このオプション付きでコマンドが呼ばれると、Laravel はアプリケーションのデフォルトキャッシュドライバーを使ってアトミックロックを取得し、他のインスタンスが実行中でないことを保証します。もし他のインスタンスが実行中なら、コマンドは実行されませんが、正常終了ステータスコードで終了します。
php artisan mail:send 1 --isolated
コマンドが実行できなかった場合に返す終了ステータスコードを指定したい場合は、isolated オプションで指定できます。
php artisan mail:send 1 --isolated=12
#ロックID
デフォルトでは、Laravel はコマンド名を使ってアトミックロックのための文字列キーを生成します。ただし、Artisan コマンドクラスに isolatableId メソッドを定義すると、このキーをカスタマイズでき、コマンドの引数やオプションをキーに組み込めます。
/**
* コマンドの分離可能IDを取得する
*/
public function isolatableId(): string
{
return $this->argument('user');
}
#ロックの有効期限
デフォルトでは、分離ロックはコマンド終了時に期限切れになります。コマンドが中断されて終了できなかった場合は、1時間後に期限切れになります。ただし、コマンドに isolationLockExpiresAt メソッドを定義してロックの有効期限を調整できます。
use DateTimeInterface;
use DateInterval;
/**
* コマンドの分離ロックの有効期限を決定する
*/
public function isolationLockExpiresAt(): DateTimeInterface|DateInterval
{
return now()->addMinutes(5);
}
#入力の定義
コンソールコマンドを書く際、引数やオプションを通じてユーザーから入力を受け取ることが一般的です。Laravel ではコマンドの signature プロパティを使って、期待する入力を簡単に定義できます。signature はコマンド名、引数、オプションを一つの表現力豊かなルート風構文で定義します。
#引数
ユーザーが指定するすべての引数やオプションは波括弧で囲みます。以下の例では、必須の引数 user を定義しています。
/**
* コンソールコマンドの名前とシグネチャ
*
* @var string
*/
protected $signature = 'mail:send {user}';
引数をオプションにしたり、デフォルト値を設定することもできます。
// オプションの引数...
'mail:send {user?}'
// デフォルト値付きのオプション引数...
'mail:send {user=foo}'
#オプション
オプションも引数と同様にユーザー入力の一種です。コマンドラインで指定する際は、オプションは二つのハイフン(--)で始まります。オプションには値を受け取るものと受け取らないものがあります。値を受け取らないオプションはブールの「スイッチ」として機能します。以下はその例です。
/**
* コンソールコマンドの名前とシグネチャ
*
* @var string
*/
protected $signature = 'mail:send {user} {--queue}';
この例では、Artisanコマンドを呼び出す際に --queue スイッチを指定できます。--queue スイッチが渡された場合、オプションの値は true になります。指定されなければ、値は false です:
php artisan mail:send 1 --queue
#値を持つオプション
次に、値を期待するオプションを見てみましょう。ユーザーがオプションに値を指定する必要がある場合、オプション名の末尾に = を付けます:
/**
* コンソールコマンドの名前とシグネチャ。
*
* @var string
*/
protected $signature = 'mail:send {user} {--queue=}';
この例では、ユーザーはオプションに値を渡せます。コマンド実行時にオプションが指定されなければ、その値は null になります:
php artisan mail:send 1 --queue=default
オプションにデフォルト値を割り当てるには、オプション名の後にデフォルト値を指定します。ユーザーがオプション値を渡さなければ、デフォルト値が使われます:
'mail:send {user} {--queue=default}'
#オプションのショートカット
オプションにショートカットを割り当てるには、オプション名の前にショートカットを指定し、| で区切ります:
'mail:send {user} {--Q|queue}'
ターミナルでコマンドを呼び出す際、オプションのショートカットは単一のハイフンを付けて指定し、値を渡す場合は = を含めません:
php artisan mail:send 1 -Qdefault
#入力配列
引数やオプションで複数の入力値を受け取りたい場合、* を使えます。まずはそのような引数を指定した例を見てみましょう:
'mail:send {user*}'
このメソッドを呼び出す際、user 引数に複数の値を順番に渡せます。例えば、以下のコマンドは user の値を 1 と 2 の配列に設定します:
php artisan mail:send 1 2
この * はオプションの引数定義と組み合わせて、0個以上の引数を許可できます:
'mail:send {user?*}'
#オプション配列
複数の入力値を期待するオプションを定義する場合、コマンドに渡す各オプション値はオプション名をプレフィックスとして付ける必要があります:
'mail:send {--id=*}'
このようなコマンドは複数の --id 引数を渡して呼び出せます:
php artisan mail:send --id=1 --id=2
#入力の説明
引数やオプションに説明を割り当てるには、引数名と説明をコロンで区切ります。コマンド定義が長くなる場合は複数行に分けても構いません:
/**
* コンソールコマンドの名前とシグネチャ。
*
* @var string
*/
protected $signature = 'mail:send
{user : ユーザーのID}
{--queue : ジョブをキューに入れるかどうか}';
#入力が不足している場合のプロンプト
コマンドに必須の引数がある場合、指定されなければエラーメッセージが表示されます。代わりに、PromptsForMissingInput インターフェイスを実装すると、必須引数が不足している際に自動でユーザーに入力を促せます:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Contracts\Console\PromptsForMissingInput;
class SendEmails extends Command implements PromptsForMissingInput
{
/**
* コンソールコマンドの名前とシグネチャ。
*
* @var string
*/
protected $signature = 'mail:send {user}';
// ...
}
Laravelが必須引数をユーザーから取得する必要がある場合、引数名や説明を使って適切に質問を自動生成し、ユーザーに尋ねます。質問文をカスタマイズしたい場合は、promptForMissingArgumentsUsing メソッドを実装し、引数名をキーにした質問文の配列を返してください:
/**
* 不足している入力引数を尋ねるための質問を返す。
*
* @return array
*/
protected function promptForMissingArgumentsUsing()
{
return [
'user' => 'どのユーザーIDにメールを送りますか?',
];
}
プレースホルダーを指定したい場合は、質問文とプレースホルダーを含むタプルを返せます:
return [
'user' => ['どのユーザーIDにメールを送りますか?', '例: 123'],
];
プロンプトの挙動を完全に制御したい場合は、ユーザーに入力を促し回答を返すクロージャを指定できます:
use App\Models\User;
use function Laravel\Prompts\search;
// ...
return [
'user' => fn () => search(
label: 'ユーザーを検索:',
placeholder: '例: Taylor Otwell',
options: fn ($value) => strlen($value) > 0
? User::where('name', 'like', "%{$value}%")->pluck('name', 'id')->all()
: []
),
];
包括的な Laravel Prompts ドキュメントには、利用可能なプロンプトとその使い方が詳しく記載されています。
ユーザーに options の選択や入力を促したい場合は、コマンドの handle メソッド内でプロンプトを含められます。ただし、自動で不足引数のプロンプトが表示された場合のみ促したいなら、afterPromptingForMissingArguments メソッドを実装してください:
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use function Laravel\Prompts\confirm;
// ...
/**
* 不足引数のプロンプト後に実行する処理。
*
* @param \Symfony\Component\Console\Input\InputInterface $input
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @return void
*/
protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output)
{
$input->setOption('queue', confirm(
label: 'メールをキューに入れますか?',
default: $this->option('queue')
));
}
#コマンドの入出力
#入力の取得
コマンド実行中に、引数やオプションの値にアクセスする必要があります。argument と option メソッドを使います。存在しない引数やオプションは null が返ります:
/**
* コンソールコマンドを実行する。
*/
public function handle(): void
{
$userId = $this->argument('user');
}
すべての引数を array として取得したい場合は、arguments メソッドを呼びます:
$arguments = $this->arguments();
オプションも同様に option メソッドで取得できます。すべてのオプションを配列で取得するには、options メソッドを使います:
// 特定のオプションを取得...
$queueName = $this->option('queue');
// すべてのオプションを配列で取得...
$options = $this->options();
#入力のプロンプト
Laravel Prompts は、コマンドラインアプリケーションに美しく使いやすいフォームを追加するPHPパッケージで、ブラウザのようなプレースホルダーやバリデーション機能を備えています。
出力を表示するだけでなく、コマンド実行中にユーザーから入力を受け付けることもできます。ask メソッドは質問を表示し、ユーザーの入力を受け取り、その値を返します:
/**
* コンソールコマンドを実行する。
*/
public function handle(): void
{
$name = $this->ask('お名前は何ですか?');
// ...
}
ask メソッドは第2引数にデフォルト値を指定でき、ユーザーが入力しなかった場合に返されます:
$name = $this->ask('お名前は何ですか?', 'Taylor');
secret メソッドは ask と似ていますが、ユーザーの入力がコンソールに表示されません。パスワードなどの機密情報を尋ねる際に便利です:
$password = $this->secret('パスワードは何ですか?');
#確認の質問
ユーザーに「はい」か「いいえ」の確認を求める場合は、confirm メソッドを使います。デフォルトは false ですが、ユーザーが y または yes と答えれば true を返します。
if ($this->confirm('続行しますか?')) {
// ...
}
必要に応じて、confirm メソッドの第2引数に true を渡すと、デフォルトで true を返すようにできます:
if ($this->confirm('続行しますか?', true)) {
// ...
}
#オートコンプリート
anticipate メソッドは候補を提示してオートコンプリートを提供します。ユーザーは候補に関係なく任意の回答が可能です:
$name = $this->anticipate('お名前は何ですか?', ['Taylor', 'Dayle']);
代わりに、anticipate メソッドの第二引数としてクロージャを渡すこともできます。クロージャはユーザーが入力文字をタイプするたびに呼び出されます。クロージャはこれまでのユーザー入力を表す文字列の引数を受け取り、オートコンプリートの候補の配列を返す必要があります:
$name = $this->anticipate('ご住所は?', function (string $input) {
// オートコンプリート候補を返す...
});
#複数選択式の質問
ユーザーにあらかじめ用意した選択肢から選ばせたい場合は、choice メソッドを使います。第3引数にデフォルト値の配列インデックスを指定できます:
$name = $this->choice(
'お名前は何ですか?',
['Taylor', 'Dayle'],
$defaultIndex
);
さらに、choice メソッドは第4引数と第5引数で、最大試行回数や複数選択の許可を指定できます:
$name = $this->choice(
'お名前は何ですか?',
['Taylor', 'Dayle'],
$defaultIndex,
$maxAttempts = null,
$allowMultipleSelections = false
);
#出力の書き込み
コンソールに出力するには、line、info、comment、question、warn、error メソッドを使います。各メソッドは用途に応じたANSIカラーを使います。例えば、一般的な情報を表示するには通常 info メソッドを使い、緑色のテキストで表示されます:
/**
* コンソールコマンドを実行する。
*/
public function handle(): void
{
// ...
$this->info('コマンドは成功しました!');
}
エラーメッセージを表示するには error メソッドを使います。エラーは通常赤色で表示されます:
$this->error('何か問題が発生しました!');
無色のテキストを表示したい場合は line メソッドを使います:
$this->line('画面にこれを表示します');
空行を表示したい場合は newLine メソッドを使います:
// 空行を1行表示...
$this->newLine();
// 空行を3行表示...
$this->newLine(3);
#テーブル
table メソッドは複数行・複数列のデータを正しくフォーマットして表示します。カラム名とデータを渡すだけで、Laravelが自動で適切な幅と高さを計算します:
use App\Models\User;
$this->table(
['Name', 'Email'],
User::all(['name', 'email'])->toArray()
);
#プログレスバー
長時間かかる処理では、進捗状況を示すプログレスバーを表示すると便利です。withProgressBar メソッドを使うと、指定したイテラブルの各要素処理ごとにプログレスバーが進みます:
use App\Models\User;
$users = $this->withProgressBar(User::all(), function (User $user) {
$this->performTask($user);
});
プログレスバーの進み方を手動で制御したい場合は、まず処理の総ステップ数を定義し、各アイテム処理後にプログレスバーを進めます:
$users = App\Models\User::all();
$bar = $this->output->createProgressBar(count($users));
$bar->start();
foreach ($users as $user) {
$this->performTask($user);
$bar->advance();
}
$bar->finish();
より高度なオプションについては、Symfony Progress Bar コンポーネントのドキュメントをご覧ください。
#コマンドの登録
すべてのコンソールコマンドは、アプリケーションの「コンソールカーネル」である App\Console\Kernel クラス内で登録されます。このクラスの commands メソッド内で、カーネルの load メソッドが呼び出されているのが確認できます。load メソッドは app/Console/Commands ディレクトリをスキャンし、その中のコマンドを自動的に Artisan に登録します。さらに、他のディレクトリをスキャンして Artisan コマンドを登録するために、load メソッドを追加で呼び出すことも可能です:
/**
* アプリケーションのコマンドを登録します。
*/
protected function commands(): void
{
$this->load(__DIR__.'/Commands');
$this->load(__DIR__.'/../Domain/Orders/Commands');
// ...
}
必要に応じて、App\Console\Kernel クラス内の $commands プロパティにコマンドのクラス名を追加して手動で登録することもできます。このプロパティがまだ定義されていない場合は、自分で定義してください。Artisan 起動時に、このプロパティにリストされたすべてのコマンドは サービスコンテナ によって解決され、Artisan に登録されます:
protected $commands = [
Commands\SendEmails::class
];
#プログラムからコマンドを実行する
CLI 以外の場所から Artisan コマンドを実行したい場合があります。例えば、ルートやコントローラーから Artisan コマンドを実行したい場合です。Artisan ファサードの call メソッドを使うことで実現できます。call メソッドは、最初の引数にコマンドのシグネチャ名またはクラス名を受け取り、2番目の引数にコマンドのパラメータ配列を受け取ります。終了コードが返されます:
use Illuminate\Support\Facades\Artisan;
Route::post('/user/{user}/mail', function (string $user) {
$exitCode = Artisan::call('mail:send', [
'user' => $user, '--queue' => 'default'
]);
// ...
});
または、Artisan コマンド全体を文字列として call メソッドに渡すこともできます:
Artisan::call('mail:send 1 --queue=default');
#配列の値を渡す
コマンドが配列を受け取るオプションを定義している場合、そのオプションに配列の値を渡せます:
use Illuminate\Support\Facades\Artisan;
Route::post('/mail', function () {
$exitCode = Artisan::call('mail:send', [
'--id' => [5, 13]
]);
});
#ブール値を渡す
migrate:refresh コマンドの --force フラグのように文字列値を受け取らないオプションの値を指定する場合は、オプションの値に true または false を渡してください:
$exitCode = Artisan::call('migrate:refresh', [
'--force' => true,
]);
#Artisan コマンドのキューイング
Artisan ファサードの queue メソッドを使うと、Artisan コマンドをキューに入れてバックグラウンドで キューワーカー に処理させることができます。このメソッドを使う前に、キューの設定とキューリスナーの起動を確認してください:
use Illuminate\Support\Facades\Artisan;
Route::post('/user/{user}/mail', function (string $user) {
Artisan::queue('mail:send', [
'user' => $user, '--queue' => 'default'
]);
// ...
});
onConnection と onQueue メソッドを使うと、Artisan コマンドを送信する接続やキューを指定できます:
Artisan::queue('mail:send', [
'user' => 1, '--queue' => 'default'
])->onConnection('redis')->onQueue('commands');
#他のコマンドからコマンドを呼び出す
既存の Artisan コマンドから他のコマンドを呼び出したい場合があります。call メソッドを使って実行できます。この call メソッドはコマンド名とコマンドの引数・オプションの配列を受け取ります:
/**
* コンソールコマンドを実行します。
*/
public function handle(): void
{
$this->call('mail:send', [
'user' => 1, '--queue' => 'default'
]);
// ...
}
別のコンソールコマンドを呼び出し、その出力をすべて抑制したい場合は、callSilently メソッドを使えます。callSilently は call と同じシグネチャを持ちます:
$this->callSilently('mail:send', [
'user' => 1, '--queue' => 'default'
]);
#シグナル処理
ご存知の通り、OS は実行中のプロセスにシグナルを送ることができます。例えば、SIGTERM シグナルは OS がプログラムに終了を要求する方法です。Artisan コンソールコマンドでシグナルを監視し、発生時にコードを実行したい場合は、trap メソッドを使えます:
/**
* コンソールコマンドを実行します。
*/
public function handle(): void
{
$this->trap(SIGTERM, fn () => $this->shouldKeepRunning = false);
while ($this->shouldKeepRunning) {
// ...
}
}
複数のシグナルを同時に監視したい場合は、trap メソッドにシグナルの配列を渡せます:
$this->trap([SIGTERM, SIGQUIT], function (int $signal) {
$this->shouldKeepRunning = false;
dump($signal); // SIGTERM / SIGQUIT
});
#スタブのカスタマイズ
Artisan コンソールの make コマンドは、コントローラー、ジョブ、マイグレーション、テストなどさまざまなクラスを作成するために使います。これらのクラスは、入力に基づいて値が埋め込まれる「スタブ」ファイルを使って生成されます。しかし、Artisan が生成するファイルに小さな変更を加えたい場合があります。その場合は、stub:publish コマンドを使ってよく使われるスタブをアプリケーションに公開し、カスタマイズできます:
php artisan stub:publish
公開されたスタブはアプリケーションのルートにある stubs ディレクトリに配置されます。これらのスタブに加えた変更は、Artisan の make コマンドで対応するクラスを生成するときに反映されます。
#イベント
Artisan はコマンド実行時に3つのイベントを発行します:Illuminate\Console\Events\ArtisanStarting、Illuminate\Console\Events\CommandStarting、Illuminate\Console\Events\CommandFinished。ArtisanStarting は Artisan の実行開始直後に発行されます。次に、コマンド実行直前に CommandStarting が発行されます。最後に、コマンド実行完了後に CommandFinished が発行されます。