Artisanコンソール
はじめに
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は、PsySHパッケージによって強力なLaravelフレームワーク用のREPLです。
インストール
すべての Laravel アプリケーションには、デフォルトで Tinker が含まれています。ただし、アプリケーションから以前に削除した場合は、Composer を使用して Tinker をインストールすることができます:
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 で対話する際にクラスを自動的にエイリアスします。ただし、一部のクラスをエイリアスしないようにしたい場合があります。これは、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
メソッドを介して必要な依存関係をリクエストできることに注意してください。このメソッドのシグネチャで型ヒントされたすべての依存関係が自動的に注入されます。
<?php
namespace App\Console\Commands;
use App\Models\User;
use App\Support\DripEmailer;
use Illuminate\Console\Command;
class SendEmails extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'mail:send {user}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Send a marketing email to a user';
/**
* Execute the console command.
*/
public function handle(DripEmailer $drip): void
{
$drip->send(User::find($this->argument('user')));
}
}
コードの再利用性を高めるために、コンソールコマンドを軽量に保ち、アプリケーションサービスにタスクを達成させ るように委任するのが良い慣行です。上記の例では、メールを送信するための "重い作業" を行うためにサービスクラスを注入していることに注意してください。
終了コード
handle
メソッドから何も返されずにコマンドが正常に実行された場合、コマンドは成功を示す0
の終了コードで終了します。ただし、handle
メソッドはオプションで整数を返すことができ、コマンドの終了コードを手動で指定できます。
$this->error('何かがうまくいかなかった。');
return 1;
コマンド内の任意のメソッドからコマンドを "失敗" させたい場合は、fail
メソッドを利用できます。fail
メソッドは、コマンドの実行を即座に終了し、終了コード1
を返します。
$this->fail('何かがうまくいかなかった。');
クロージャコマンド
クロージャベースのコマンドは、コンソールコマンドをクラスとして定義する代わりに提供されます。ルートクロージャがコントローラの代替手段であるように、コマンドクロージャはコマンドクラスの代替手段と考えてください。
routes/console.php
ファイルはHTTPルートを定義していませんが、アプリケーションへのコンソールベースのエントリーポイント(ルート)を定義します。このファイル内で、Artisan::command
メソッドを使用して、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('Send a marketing email to a user');
分離可能なコマンド
この機能を利用するには、アプリケーションがデフォルトのキャッシュドライバとしてmemcached
、redis
、dynamodb
、database
、file
、またはarray
キャッシュドライバを使用している必要があります。さらに、すべてのサーバーが同じ中央キャッシュサーバーと通信している必要があります。
時々、特定のコマンドのインスタンスが一度に1つしか実行されないようにしたい場合があります。これを実現するために、コマンドクラスに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 はそのコマンドの他のインスタンスが既に実行中でないことを確認します。Laravel は、アプリケーションのデフォルトのキャッシュドライバを使用してアトミックロックを取得しようとします。他のコマンドのインスタンスが実行中の場合、コマンドは実行されませんが、コマンドは依然として成功の終了ステータスコードで終了します:
php artisan mail:send 1 --isolated
コマンドが実行できない場合に返すべき終了ステ ータスコードを指定したい場合は、isolated
オプションを使用して希望するステータスコードを指定できます:
php artisan mail:send 1 --isolated=12
ロック ID
デフォルトでは、Laravel はアプリケーションのキャッシュでアトミックロックを取得するために使用される文字列キーを生成するために、コマンドの名前を使用します。ただし、コマンドクラスで isolatableId
メソッドを定義することで、キーをカスタマイズすることができます。これにより、コマンドの引数やオプションをキーに統合することができます:
/**
* Get the isolatable ID for the command.
*/
public function isolatableId(): string
{
return $this->argument('user');
}
ロックの有効期限
デフォルトでは、分離ロックはコマンドが終了した後に期限切れになります。また、コマンドが中断されて終了できない場合、ロックは1時間後に期限切れになります。ただし、コマンドで isolationLockExpiresAt
メソッドを定義することで、ロックの有効期限を調整することができます:
use DateTimeInterface;
use DateInterval;
/**
* Determine when an isolation lock expires for the command.
*/
public function isolationLockExpiresAt(): DateTimeInterface|DateInterval
{
return now()->addMinutes(5);
}
入力の期待値の定義
コンソールコマンドを記述する際、ユーザーから引数やオプションを収集することは一般的です。Laravel は、コマンドの signature
プロパティを使用して、ユーザーから期待する入力を定義するのが非常に便利です。signature
プロパティを使用すると、コマンドの名前、引数、オプションを単一で表現力のあるルートのような構文で定義できます。
引数
すべてのユーザー提供引数とオプションは中括弧で囲まれています。次の例では、コマンドは1つの必須引数 user
を定義しています:
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'mail:send {user}';
引数をオプションにするか、引数のデフォルト値を定義することもできます:
// Optional argument...
'mail:send {user?}'
// Optional argument with default value...
'mail:send {user=foo}'
オプション
オプションは、引数と同様にユーザー入力の別の形式です。オプションは、コマンドライン経由で提供される場合、二つのハイフン (--
) で接頭辞が付けられます。オプションには値を受け取るものと受け取らないも のの2種類があります。値を受け取らないオプションはブール型の "スイッチ" として機能します。このタイプのオプションの例を見てみましょう:
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'mail:send {user} {--queue}';