Laravel では環境変数を用いてアプリケーション内の設定を更新することができます。
この記事では Routing 設定を環境変数を用いて切り替える方法について書きます。
動作環境
- PHP 7.2.26
- Laravel 6.9.0
TL;DR
- Controller または Middleware に
config()
の値を用いた条件分岐を書くことで実現可能。 - routes/web.php に条件分岐を書くとテストが困難。
シチュエーション
アプリケーションの何らかの機能が廃止され、ある特定のパスへのリクエストを別のパスにリダイレクトさせたいケースについて考えます。
このリダイレクトを行うかどうかは環境変数に応じて決定されるものとします。
// 廃止されるパス
Route::get('/old/resources', 'OldIndexController@index');
// リダイレクト先にしたいパス
Route::get('/new/resources', 'NewIndexController@index')->name('new.resources.index');
config/hoge.php
return [
// true のとき、 /old/resources から /new/resources へリダイレクトさせる
'enable_new_resources' => env('ENABLE_NEW_RESOURCES', true),
]
方法1. Controller で条件分岐する
OldIndexController で条件分岐をすると最もシンプルに実現できそうです。
app/Http/Controllers/OldIndexController.php
class OldIndexController
{
private $redirector
public function __construct(Redirector $redirector)
{
$this->redirector = $redirector;
}
public function index()
{
if (config('hoge.enable_new_feature')) {
return $this->redirector->route('new.resources.index', [], 301);
}
// 既存の処理
}
}
方法2: 新規作成した Middleware で条件分岐する
Middleware を使用すれば複数のパスを対象にまとめて設定することもできます。
routes/web.php
Route::middleware(['redirectToNewResources'])->group(function () {
Route::get('/old/resources', 'OldIndexController@index');
// 他にリダイレクトさせたいパスがあれば追加する
});
app/Http/Kernel.php
class Kernel extends HttpKernel
{
protected $routeMiddleware = [
'redirectToNewResources' => 'RedirectToNewResources::class',
]
}
app/Http/Middleware/RedirectToNewResources.php
class RedirectToNewResources
{
private $redirector
public function __construct(Redirector $redirector)
{
$this->redirector = $redirector;
}
public function handle($request, Closure $next)
{
if (config('hoge.enable_new_feature')) {
return $this->redirector->route('new.resources.index', [], 301);
}
return $next($request);
}
}
おまけ: routes/web.php に条件分岐を書く場合(失敗例)
routes/web.php に条件分岐を書いても一応実現できます。
routes/web.php
if (config('hoge.enable_new_feature')) {
Route::redirect('/old/resources', '/new/resources', 301);
} else {
Route::get('/old/resources', 'OldIndexController@index');
}
ただしこのように実装した場合、テスト中で Config
ファサードを利用して設定を切り替えても Routing には反映されません。
恐らく Laravel 起動時に RouteServiceProvider が読み込まれた時点での Routing 設定が登録されることが原因と思われます。