引き続いて、Laravel 8.x更新で変わったことです。今回はRoute関連の話です。

Laravel 8.x以前では、routes/web.phpの中身はこんな感じでした。

Route::namespace('Auth')->middleware('guest')->group(function () {

    // Authentication Routes...
    Route::get('', 'LoginController@showLoginForm');
    Route::get('login', 'LoginController@showLoginForm')->name('login');
    Route::post('login', 'LoginController@login')->name('login-post');

    // Password Reset Routes...
    Route::get('password/reset', 'ForgotPasswordController@showLinkRequestForm')->name('password.forgot');
    Route::post('password/email', 'ForgotPasswordController@sendResetLinkEmail')->name('password.email');
    Route::get('password/reset/{token}', 'ResetPasswordController@showResetForm')->name('password.reset');
    Route::post('password/reset', 'ResetPasswordController@reset')->name('password.reset-post');
});

これが、Laravel 8.xでは、

use App\Http\Controllers\Admin;
use App\Http\Controllers\Auth;
use App\Http\Controllers\User;
use Illuminate\Support\Facades\Route;

Route::middleware('guest')->group(function () {

    // Authentication Routes...
    Route::get('', [Auth\LoginController::class, 'showLoginForm']);
    Route::get('login', [Auth\LoginController::class, 'showLoginForm'])->name('login');
    Route::post('login', [Auth\LoginController::class, 'login'])->name('login-post');

    // Password Reset Routes...
    Route::get('password/reset', [Auth\ForgotPasswordController::class, 'showLinkRequestForm'])->name('password.forgot');
    Route::post('password/email', [Auth\ForgotPasswordController::class, 'sendResetLinkEmail'])->name('password.email');
    Route::get('password/reset/{token}', [Auth\ResetPasswordController::class, 'showResetForm'])->name('password.reset');
    Route::post('password/reset', [Auth\ResetPasswordController::class, 'reset'])->name('password.reset-post');

});

となります。

何が変わったかというと、今までのコントローラクラス名@メソッド名(例:’LoginController@showLoginForm’)が、コントローラクラスパスとメソッド名の配列([Auth\LoginController::class, ‘showLoginForm’])となりました。

この変更が動作するためには、RouteServiceProvider.phpのファイルの編集も必要です。
L7.xのバージョンでは、以下のように$namespaceがありますが、

namespace App\Providers;

use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Route;

class RouteServiceProvider extends ServiceProvider
{
    /**
     * This namespace is applied to your controller routes.
     *
     * In addition, it is set as the URL generator's root namespace.
     *
     * @var string
     */
    protected $namespace = 'App\Http\Controllers';

...
    /**
     * Define the "web" routes for the application.
     *
     * These routes all receive session state, CSRF protection, etc.
     *
     * @return void
     */
    protected function mapWebRoutes()
    {
        Route::middleware('web')
            ->namespace($this->namespace)
            ->group(base_path('routes/web.php'));
    }

    /**
     * Define the "api" routes for the application.
     *
     * These routes are typically stateless.
     *
     * @return void
     */
    protected function mapApiRoutes()
    {
        Route::prefix('api')
            ->middleware('api')
            ->namespace($this->namespace)
            ->group(base_path('routes/api.php'));
    }
}

L8.xのバージョンでは、それを削除します。mapWebRoute()mapApiRoute()からもnamespace()を削除します。

namespace App\Providers;

use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Route;

class RouteServiceProvider extends ServiceProvider
{

...
    /**
     * Define the "web" routes for the application.
     *
     * These routes all receive session state, CSRF protection, etc.
     *
     * @return void
     */
    protected function mapWebRoutes()
    {
        Route::middleware('web')
            ->group(base_path('routes/web.php'));
    }

    /**
     * Define the "api" routes for the application.
     *
     * These routes are typically stateless.
     *
     * @return void
     */
    protected function mapApiRoutes()
    {
        Route::prefix('api')
            ->middleware('api')
            ->group(base_path('routes/api.php'));
    }
}

さて、上の変更によりプログラムの実行が速くなったとかのメリットはないと思いますが、この形式になることにより改善されたのは、vscodeのようなエディターにおいてweb.phpのファイル内から簡単にコントローラクラスの定義にジャンプできることです。エディターあるいはエディターのプラグインがクラスを認識できるようになったためです。

とは言え、このコード変更を手動でやるのはとても面倒ですね。私の大きいプロジェクトでrouteがたくさんあり、242箇所も変更が必要な部分があります。このようなときには、Laravel Shiftのサービスを使用することを勧めます。以前に、ここで紹介していますが、あれから数年、サイトのデザインとか変わっていますが基本的には同じサービスです。

最後に、上で編集したweb.phpやRouteServiceProvider.phpを何も編集せずにしておくことも可能です。それでも問題なくL8.xで動作します。

By khino