Laravel 特定の環境でコマンドの実行を止める
はじめに
この前このようなポストを見かけた。
特定の環境でコマンド実行を無効化してくれる仕組みが11.9.0で増えていたようです。
記事もありました。
どうやって実行を止めているのか調べてみることした。
環境
- PHP 8.3.13
- Laravel 11.31.0
そもそも本番環境なら実行を止めてくれるのは?
特定のコマンドは本番環境(APP_ENV=production)であれば下記のように実行するか選択ができます。
選択なので許可するれば本番環境でも実行することは可能です。
では、何が違うのか?
この仕組みを追加したプルリクエストを見るのが一番早いので見てみます。
db:wipe
, migrate:fresh
, migrate:refresh
, migrate:reset
の4つのコマンドが本番環境では実行を選択はさせないで止めることができるってことらしい。
この機能を有効にする方法は、DBファサードのprohibitDestructiveCommands
メソッドを実行する必要がある。
DB::prohibitDestructiveCommands($this->app->isProduction());
引数にtrueを渡すと4つのコマンドを無効化できる。
やってみる
この処理を仕込むならAppServiceProvider
のboot
メソッドあたりに書いておけばいいだろう。
<?php
namespace App\Providers;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot(): void
{
DB::prohibitDestructiveCommands($this->app->isProduction());
}
}
仕込んだ状態でAPP_ENV=productionの場合に実行してみると
% php artisan migrate:fresh
WARN This command is prohibited from running in this environment.
選択もできないで動かなくなった。
もし、どれか1つだけ無効化する場合は下記のように書くことで対応できるようです。
ResetCommand::preventFromRunning($this->app->isProduction());
ほかのコマンドには仕込めないのか?
仕組みとしてはProhibitable
traitを読み込んでいれば使えるようなので自作コマンドにProhibitable
traitを読み込ませれば使えるようです。
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Console\Prohibitable;
class SampleCommand extends Command
{
use Prohibitable;
protected $signature = 'app:sample-command';
protected $description = 'Command description';
public function handle()
{
if ($this->isProhibited()) {
echo '実行できない' . PHP_EOL;
return Command::FAILURE;
}
echo '実行した' . PHP_EOL;
return Command::SUCCESS;
}
}
自作コマンドではprohibit
メソッドを実行することで無効化するかの判定を行うことができる。
仕込む場所は先ほどと同じでAppServiceProvider
のboot
メソッドで問題ないでしょう。
namespace App\Providers;
use App\Console\Commands\SampleCommand;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot(): void
{
SampleCommand::prohibit($this->app->isProduction());
}
}
では、先ほどと同じように実行してみます。
- APP_ENV=local
% php artisan app:sample-command
実行した
- APP_ENV=production
% php artisan app:sample-command
WARN This command is prohibited from running in this environment.
実行できない
できましたね。自作コマンドの場合は判定方法を変えれば本番環境以外でも実行を無効化できそうです。
まとめ
たまたま見かけた機能ですがフレームワークから事故防止の仕組みが用意してくれているのは嬉しいですね。
実際に自作コマンドに仕込む機会があるかは不明ですが、備えあれば憂いなしとも言いますし、何か機会があれば仕込んでおくと安心するかもしれないですね。
Discussion