Laravel11以降から使い始めた人に必要そうな質問と回答一覧
Laravel11以降から使い始めた人に必要そうな質問と回答一覧
Laravel11ではアプリケーション構造が大幅に変わったのでこれまでの本や記事が一気に古びた。
初心者質問の定番だけど、古い本を見ながら最新のLaravelを使おうとしても使えない。
configファイルが少ない
あまり使われないconfigファイルが削除された。
Laravel11以降しか知らない人にはかなり分かりにくいのでしっかり理解が必要。
- プロジェクトのconfigとフレームワーク内のconfigがマージされて使われるのでファイルがなくても設定は存在している。 https://github.com/laravel/framework/tree/11.x/config
- マージする時はプロジェクト側のconfigが優先。
- ほとんどの設定は
.env
で変更できるのでconfigファイルを変更することは少ない。
config/sanctum.php
はsanctumをインストールしたら追加される。
config/broadcasting.php
はブロードキャスト機能をインストールしたら追加される。
app/Http/Middleware
がなくてミドルウェアの設定を変更できない
bootstrap/app.php
での設定に変わった。
Laravel10
TrustProxies.php
protected $proxies = '*';
VerifyCsrfToken.php
protected $except = [
'stripe/*',
'http://example.com/foo/bar',
'http://example.com/foo/*',
];
Laravel11
->withMiddleware(function (Middleware $middleware) {
$middleware->trustProxies(at: '*')
->validateCsrfTokens(except: [
'stripe/*',
'http://example.com/foo/bar',
'http://example.com/foo/*',
]);
})
Laravel10で可能だった設定はすべてMiddlewareクラスに移動している。
app/Http/Kernel.php
がなくてミドルウェアを追加できない
bootstrap/app.php
での追加に変わった。
Laravel10
protected $middleware = [
// ...
\App\Http\Middleware\EnsureTokenIsValid::class,
];
Laravel11
use App\Http\Middleware\EnsureTokenIsValid;
->withMiddleware(function (Middleware $middleware) {
$middleware->append(EnsureTokenIsValid::class);
})
$this->validate()
や$this->authorize()
が使えない
コントローラーでベースコントローラーを継承しなくなったので代わりにRequestやGateを使う。
use App\Models\Post;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
class PostController extends Controller
{
public function update(Request $request, Post $post) {
$validated = $request->validate([]);
Gate::authorize('update', $post);
if ($request->user()->cannot('update', $post)) {
abort(403);
}
}
}
ValidatesRequests
やAuthorizesRequests
を追加すれば引き続き使える。authorizeResource()
を使いたい場合もAuthorizesRequests
を追加する方法を選ぶ。
use App\Models\Post;
use Illuminate\Http\Request;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Validation\ValidatesRequests;
class PostController extends Controller
{
use AuthorizesRequests, ValidatesRequests;
public function __construct()
{
$this->authorizeResource(Post::class, 'post');
}
public function update(Request $request, Post $post) {
$validated = $this->validate([]);
$this->authorize('update', $post);
}
}
色々なコントローラーで使うならapp/Http/Controllers/Controller.php
に追加してLaravel10仕様に戻してもいい。
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Validation\ValidatesRequests;
abstract class Controller
{
use AuthorizesRequests, ValidatesRequests;
}
$this->middleware()
がないのでコントローラー内でのミドルウェアの指定ができない
リリースノート・アップグレードガイドには書いてないけど使い方が大きく変わっている。
Laravel10
class UserController extends Controller
{
/**
* Instantiate a new controller instance.
*/
public function __construct()
{
$this->middleware('auth');
$this->middleware('log')->only('index');
$this->middleware('subscribed')->except('store');
}
}
Laravel11
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Routing\Controllers\HasMiddleware;
use Illuminate\Routing\Controllers\Middleware;
class UserController extends Controller implements HasMiddleware
{
/**
* Get the middleware that should be assigned to the controller.
*/
public static function middleware(): array
{
return [
'auth',
new Middleware('log', only: ['index']),
new Middleware('subscribed', except: ['store']),
];
}
// ...
}
元々コントローラー内でのミドルウェア指定は分かりにくいのでルーティングで指定したほうがいい。
Route::get('user', UserController::class)->middleware(['auth']);
app/Http/Controllers/Controller.php をLaravel10仕様に戻してもいい
Laravel10からアップグレードしたLaravel11ではそのまま使えるので別に禁止されてない。コントローラー内での$this->middleware()
が引き続き使える。
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
abstract class Controller extends BaseController
{
use AuthorizesRequests, ValidatesRequests;
}
routes/api.php
がない
API関連の機能は必要な人だけ追加するように変わったので個別にインストールする。
php artisan install:api
routes/channels.php
がない
Broadcasting ブロードキャストもAPIと同じく個別にインストールする。
php artisan install:broadcasting
app/Console/Kernel.php
がなくてScheduleの設定ができない
routes/console.php
での設定に変わった。
Laravel10
protected function schedule(Schedule $schedule): void
{
$schedule->command('inspire')->hourly();
}
Laravel11
use Illuminate\Support\Facades\Schedule;
Schedule::command('inspire')->hourly();
Laravel11.1でbootstrap/app.php
での指定も可能になった。せっかくスリム化したのにタスクスケジュールの設定方法が2つに増えた。
use Illuminate\Console\Scheduling\Schedule;
->withSchedule(function (Schedule $schedule) {
$schedule->command('inspire')->hourly();
})
イベントとリスナーの登録方法が分からない
イベントと「handle()にイベントを指定したリスナー」を作れば自動的に登録されるので手動登録は不要。
php artisan make:event PodcastProcessed
php artisan make:listener SendPodcastNotification --event=PodcastProcessed
use App\Events\PodcastProcessed;
class SendPodcastNotification
{
/**
* Handle the given event.
*/
public function handle(PodcastProcessed $event): void
{
// ...
}
}
本番環境ではキャッシュを忘れない。
php artisan event:cache
よくある間違いで開発環境でcacheコマンドを実行してはいけない。clearコマンドで戻せるけど最初から一度も実行しなければ何も問題は起きない。
php artisan event:clear
config/app.php
へのサービスプロバイダー追加方法が分からない
bootstrap/providers.php
への追加に変わった。
Laravel10
'providers' => ServiceProvider::defaultProviders()->merge([
// ...
App\Providers\AppServiceProvider::class,
App\Providers\FooServiceProvider::class,
])->toArray(),
Laravel11
<?php
return [
App\Providers\AppServiceProvider::class,
App\Providers\FooServiceProvider::class,
];
Laravel用のcomposerパッケージならServiceProviderの自動検出に対応しているのでbootstrap/providers.php
への手動追加は不要。
プロジェクト独自のServiceProviderをmakeコマンドで作った場合もbootstrap/providers.php
は自動更新されるので手動追加は不要。
php artisan make:provider FooServiceProvider
RouteServiceProvider::HOME
がない
消えたままなので使わずルート名などで指定。
return to_route('home');
return redirect('/home');
app/Exceptions/Handler.php
がない
bootstrap/app.php
での設定に変わった。
->withExceptions(function (Exceptions $exceptions) {
$exceptions->dontReport(MissedFlightException::class);
$exceptions->report(function (InvalidOrderException $e) {
// ...
});
})
Laravel10でもこの辺りを変更することはほとんどなかったので覚えなくていい。
ルーティングをもっとカスタマイズしたい
Laravel10
RouteServiceProvider
でルートファイルを追加できた。
$this->routes(function () {
Route::middleware('api')
->prefix('api')
->group(base_path('routes/api.php'));
Route::middleware('web')
->group(base_path('routes/web.php'));
Route::middleware('web')
->group(base_path('routes/foo.php'));
});
Laravel11
web.php
とは別のルートファイルを追加するならthen
use Illuminate\Support\Facades\Route;
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
then: function () {
Route::middleware('web')
->group(base_path('routes/foo.php'));
},
)
Laravel10と同じように全部自分で定義したいならusing
use Illuminate\Support\Facades\Route;
->withRouting(
commands: __DIR__.'/../routes/console.php',
using: function () {
Route::middleware('api')
->prefix('api')
->group(base_path('routes/api.php'));
Route::middleware('web')
->group(base_path('routes/web.php'));
Route::middleware('web')
->group(base_path('routes/foo.php'));
},
)
LaravelデフォルトのServiceProviderを置き換えたい
一部のサードパーティパッケージはデフォルトのServiceProviderをパッケージのServiceProviderに置き換えて使うように指示してくる。(こんなパッケージは使わない方がいい)
config/app.php
からproviders
は消えているけどフレームワーク内のconfig/app.php
には残っている。「configはマージして使われる」のでプロジェクト側のconfig/app.php
にproviders
を追加すればいい。
use Illuminate\Support\ServiceProvider;
'providers' => ServiceProvider::defaultProviders()->replace([
Illuminate\Foo\FooServiceProvider::class => Bar\BarServiceProvider::class,
])->toArray(),
途中参加したプロジェクトでの判別方法
bootstrap/app.php
の中身を確認。
-
return Application::configure(...
ならLaravel11以降に新しく作られたプロジェクト、もしくはLaravel10からのアップグレード時にLaravel11の仕様に合わせてスリム化したプロジェクト。Laravel11以降のドキュメントだけ見ればいい。 - Laravel10と同じbootstrap/app.phpならLaravel10からのアップグレード時にスリム化してない。公式にはスリム化しない方が推奨なのでこれも多くなるはず。現在使ってるバージョンがなんだろうとドキュメントは最新版とLaravel10版を参照する。
2つの使い方が混在するのでしばらくは混乱するかもしれない。
リリース後に何度も聞かれてる質問を見つけたら追加するかも
質問があればteratailへ。
英語ならLaracasts Forum。
Discussion