🎉

Laravel11以降の新常識

2024/03/12に公開

Laravel11以降の新常識

Laravelはメジャーバージョンアップのタイミングでたまにそれまでの常識が通じなくなる大きな変更を入れてくる。

最近だとLaravel8。ルーティングの書き方、モデルディレクトリ、Tailwind、スターターキット一新。これからLaravelを使い始める人ほど混乱する変更が大量に発生。

Laravel11は8以来の大きな変更があるので新常識の覚え直しが必要。

https://laravel.com/docs/11.x/releases

大事な前提

Laravel11以降に作った新プロジェクトが対象の話。
Laravel10から11に更新したプロジェクトは以前のままの使い方をしたほうがいいと公式にも推奨されている。互換は維持されている。

スリム化されたスケルトン

app/内のファイルがごっそり減らされた。
https://github.com/laravel/laravel/tree/11.x

  • 使わなくてもいいController
  • 空のAppServiceProvider
  • Userは変わらず

3ファイルしかない。

初期状態のファイルが減っただけでmakeコマンドを使った時に必要なディレクトリが作られる点は同じ。

(Laravel10から更新したプロジェクトはスリム化に追従しなくてもいい)

コアはbootstrap/app.php

今までbootstrap/を触ることはほとんどなかったけど今後はbootstrap/app.phpが最重要ファイル。
完全な新常識なのでしっかり覚え直さないと「Laravelの基本的な使い方」が分からなくなる。

<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        //
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

とはいえ今まで他で設定していた機能を集約しただけなので実際に使うのはミドルウェアくらい。

ミドルウェア

今まではapp/Http/Middleware内にいくつもミドルウェアがあったけど実際の使い方は少し設定を変更する程度。

Laravel11での設定変更はbootstrap/app.phpで行う。

->withMiddleware(function (Middleware $middleware) {
    $middleware->trustProxies(at: '*');
})

Laravel10のデフォルトミドルウェアと同じ設定ができるように用意されてるので詳細はMiddlewareクラスを確認。
https://github.com/laravel/framework/blob/11.x/src/Illuminate/Foundation/Configuration/Middleware.php

プロジェクト独自のミドルウェアがapp/Http/Middlewareに作られるのは同じ。
Kernel.phpではなくbootstrap/app.phpで登録。

use App\Http\Middleware\EnsureTokenIsValid;
 
->withMiddleware(function (Middleware $middleware) {
     $middleware->append(EnsureTokenIsValid::class);
})

サービスプロバイダー

今まで手動でconfig/app.phpに追加していた場合、Laravel11ではbootstrap/providers.phpに追加。
makeコマンドで作ったら自動で追加される。

タスクスケジュール

routes/console.phpで設定。

routes/console.php
use Illuminate\Support\Facades\Schedule;

Schedule::command('emails:send')->daily();

Laravel11.1以降はbootstrap/app.phpでも設定可能。

bootstrap/app.php
use Illuminate\Console\Scheduling\Schedule;

->withSchedule(function (Schedule $schedule) {
    $schedule->command('emails:send')->daily();
})

Controllerは何も継承しない

app/Http/Controllers/Controller.phpは空。

namespace App\Http\Controllers;

abstract class Controller
{
    //
}

継承してないのでコントローラー内での$this->authorize()などが使えなくなる。代わりにGate::authorize()を使う。(必要なコントローラーに手動でAuthorizesRequestsを追加してもいい)

使わないならapp/Http/Controllers/Controller.phpは削除可能。削除されてるとmakeコマンドで作成したコントローラーは何も継承しない。このControllerを使って共通化するのはよくないのでさっさと削除してもいい。

今のLaravelはコントローラーを全く使わない使い方もできるのでばっさりスリム化。

(Laravel10から更新したプロジェクトは今まで通りのコントローラーの使い方していい)

イベントは自動検出

Laravel10でもEventServiceProviderで自動検出を有効化できた。

public function shouldDiscoverEvents(): bool
{
    return true;
}

Laravel11はこれがデフォルトの動作なのでEventServiceProviderは不要。

手動で登録したい場合はAppServiceProviderで行う。

use App\Domain\Orders\Events\PodcastProcessed;
use App\Domain\Orders\Listeners\SendPodcastNotification;
use Illuminate\Support\Facades\Event;

public function boot(): void
{
    Event::listen(
        PodcastProcessed::class,
        SendPodcastNotification::class,
    );
}

データベースはSQLiteがデフォルト化

composer create-projectlaravel/installerでプロジェクト作成した場合はSQLite。
https://laravel.build/ でSailを使う場合はMySQLなどを使うように設定される。

データベースの設定ができてなくマイグレーションに失敗するのは初心者質問の定番なので一番失敗の少ないSQLiteをデフォルトにするのがいい。

configファイル

開発中はconfig/内のファイルが全部削除されてフレームワーク内に移ってたけど流石に分かりにくいと判断されたのか一部は元に戻っている。

フレームワーク内のconfigとマージされるのは同じなので不要なconfigファイルを削除したり、必要な項目だけに減らしてもいい。
https://laravel-news.com/laravel11-streamlined-configs

今後の課題

  • Laravel10から11に更新して以前の使い方を継続してるプロジェクト。
  • Laravel11以降の新プロジェクト、もしくはLaravel10から更新時にスリム化に追従したプロジェクト。

2つの使い方が混在した状態が続いていくことになる。
ドキュメントはLaravel11の仕様に変更されてるので以前の使い方を続けるなら読み換えが必要。
両方知ってる人なら問題なくてもいずれLaravel11以降しか知らない人が増えたら面倒なことになる。

早めにスリム化に追従するかどうかの決断が必要。

Discussion