Laravel11をインストールしてLaravel10との違いを見てみよう
Laravel11が2024年3月12日にリリースされたのでmacOSを利用してインストールを行いLaravel10との違いを確認していきましょう。Laravelを利用した経験がある人ならすぐに気が付く箇所が中心になっています。
インストール直後にすぐに気が付く違いとしてはデフォルトで作成されているconfigファイルやルーティングファイルがスリム化(ファイル数が減っている)されてことです。変更の頻度の低いもの(例:hashing.php)や利用するかどうかは作りたいアプリケーションによって変わる機能(例:APIルーティング)については利用する場合のみにファイルを作成して設定を行うという形になっています。
Laravel11と同時にアナウンスされたLaravel Reverbについてはこちらの記事で紹介しています。
目次
Composerによるインストール
composerがインストールされている環境で以下のコマンドを実行すると現在の最新版であるLaravel11をローカルにインストールすることができます。
% composer create-project laravel/laravel laravel11
//略
INFO Application key set successfully.
> @php -r "file_exists('database/database.sqlite') || touch('database/database.sqlite');"
> @php artisan migrate --graceful --ansi
INFO Preparing database.
Creating migration table ....................................... 3.81ms DONE
INFO Running migrations.
0001_01_01_000000_create_users_table ........... 6.92ms DONE
0001_01_01_000001_create_cache_table ........... 2.25ms DONE
0001_01_01_000002_create_jobs_table ............ 5.00ms DON
プロジェクトを作成する際にこれまでと大きな違いあり、composerコマンドを実行してインストールを開始するとSQLiteのデータベースファイルであるdatabase.sqliteファイルがdatabaseディレクトリに作成され、そのままmigrationも行われテーブルも作成されます。手動で設定するのもそれほど大変ではないですが開発でSQLiteを利用する人にとっては時短につながる機能強化です。
composerコマンドを利用してLaravel10をインストールする場合はバージョンを指定して行うことができますがLaravel10ではSQLiteのデータベースが作成されることはありません。
% composer create-project --prefer-dist laravel/laravel:^10.0 laravel10
Laravelコマンドによるインストール
composerだけではなくlaravel newコマンドを利用した場合のインストールも確認しておきます。composerコマンドとは異なりlaravel newコマンドを実行するといろいろ質問されそれに答える形でインストールする内容が決まります。はじめから利用するStackが決まっている人には便利です。
コマンドを実行するとスターターキットに何を利用するのか聞かれます。ここではLaravel Breezeを選択します。
% laravel new laravel11_new
_ _
| | | |
| | __ _ _ __ __ ___ _____| |
| | / _` | '__/ _` \ \ / / _ \ |
| |___| (_| | | | (_| |\ V / __/ |
|______\__,_|_| \__,_| \_/ \___|_|
┌ Would you like to install a starter kit? ────────────────────┐
│ ○ No starter kit │
│ › ● Laravel Breeze │
│ ○ Laravel Jetstream │
└──────────────────────────────────────────────────────────────┘
次にBreezeで利用するどのStackを利用するのか聞かれるのでBlade with Alpineを選択します。
┌ Which Breeze stack would you like to install? ───────────────┐
│ › ● Blade with Alpine ┃ │
│ ○ Livewire (Volt Class API) with Alpine │ │
│ ○ Livewire (Volt Functional API) with Alpine │ │
│ ○ React with Inertia │ │
│ ○ Vue with Inertia │ │
└──────────────────────────────────────────────────────────────┘
ダークモードをサポートするかどうか聞かれるのでここではデフォルトの”No”を選択します。
┌ Would you like dark mode support? ───────────────────────────┐
│ ○ Yes / ● No │
└──────────────────────────────────────────────────────────────┘
テストのフレームワークを聞かれるのでデフォルトのPestを選択します。
┌ Which testing framework do you prefer? ──────────────────────┐
│ › ● Pest │
│ ○ PHPUnit │
└──────────────────────────────────────────────────────────────┘
Gitのリポジトリを聞かれるので”No”を選択します。
┌ Would you like to initialize a Git repository? ──────────────┐
│ ○ Yes / ● No │
└──────────────────────────────────────────────────────────────┘
利用したいデータベースを聞かれるのでデフォルトのSQLiteを選択します。
┌ Which database will your application use? ───────────────────┐
│ ○ MySQL │
│ ○ MariaDB │
│ ○ PostgreSQL │
│ › ● SQLite │
│ ○ SQL Server │
└──────────────────────────────────────────────────────────────┘
デフォルトのデータベーステーブルの違い
作成されているmigrationファイル
Laravel11ではdatabaseのmigrationディレクトリを確認すると3つのファイルを確認することができます。
- 0001_01_01_000000_create_users_table.php
- 0001_01_01_000001_create_cache_table.php
- 0001_01_01_000002_create_jobs_table.php
デフォルトで存在するマイグレーションファイルの名前にはこれまでのようにタイムスタンプが含まれていません。各ファイルの中で複数のテーブルが作成されています。例えば0001_01_01_000002_create_jobs_table.phpファイルであればjobs, job_batches, failed_jobsの3つのテーブルが作成されます。
php artisan make:migrationコマンドを利用して新たにmigrationテーブルを作成するとこれまで通りタイムスタンプがファイル名に入ります。
% php artisan make:migration create_flights_table
INFO Migration [database/migrations/2024_03_13_004455_create_flights_table.php] created successfully.
Laravel10ではデフォルトでは4つのファイルが作成されます。作成されるテーブルも異なっています。
- 2014_10_12_000000_create_users_table.php
- 2014_10_12_100000_create_password_reset_tokens_table.php
- 2019_08_19_000000_create_failed_jobs_table.php
- 2019_12_14_000001_create_personal_access_tokens_table.php
.envファイル
.envファイルの内容もLaravel11では変わっている箇所も多いのでデータベースの部分にのみ注目するとLaravel11ではプロジェクト作成時にSQLiteのデータベースを作成するでMySQLの設定がコメントアウトされています。
DB_CONNECTION=sqlite
# DB_HOST=127.0.0.1
# DB_PORT=3306
# DB_DATABASE=laravel
# DB_USERNAME=root
# DB_PASSWORD=
Laravel10ではコメントアウトされている箇所がデフォルトの設定値です。
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=
Welcomeページの違い
php artisan serveコマンドを利用して開発サーバを起動してみましょう。
% php artisan serve
INFO Server running on [http://127.0.0.1:8000]. .
デザインが変わっていることがわかります。
Laravel10ではこちらの画面でした。
ダークモードにも対応しておりダークモードだとこのような感じです。
configディレクトリの確認
Laravel11のconfigディレクトリを確認するとLaravel10と比較してファイル数が減っていることが確認できます。
Laravel11でconfigディレクトリに移動してlsコマンドを実行すると10ファイル存在することがわかります。
config % ls
app.php cache.php filesystems.php mail.php services.php
auth.php database.php logging.php queue.php session.php
Laravel10で同じようにconfigディレクトリでlsコマンドを実行すると15ファイル存在することがわかります。ファイル数だけ見ると5つのファイルがなくなっています。
config % ls
app.php database.php queue.php
auth.php filesystems.php sanctum.php
broadcasting.php hashing.php services.php
cache.php logging.php session.php
cors.php mail.php view.php
突然ですがhashing.phpファイルを利用してHashingの設定を行ったという経験がある人はどれくらいいるでしょうか。Laravel11では変更の頻度が低いものはデフォルトではconfigファイルが存在しません。変更の頻度が低いと言っても利用する人はいます。その場合はコマンドを利用してconfigファイルを作成することができます。
hashingの場合は”php artisan config:publish hashing”を実行することで作成できます。
% php artisan config:publish hashing
INFO Published 'hashing' configuration file.
実行後configディレクトリを確認するとconfig.phpファイルを確認することができます。
それぞれの機能についてマニュアルで確認することでどのようなコマンドを利用するとconfigファイルが作成できるかわかりますがconfig:publishの後にhashingをつけない場合は選択肢が表示されます。スクロールすることができるのでhashingも見つけることができます。このように簡単にconfigファイルの作成を行うことができます。
% php artisan config:publish
┌ Which configuration file would you like to publish? ─────────┐
│ › ● app ┃ │
│ ○ auth │ │
│ ○ broadcasting │ │
│ ○ cache │ │
│ ○ cors │ │
└──────────────────────────────────────────────────────────────┘
デフォルトで存在しないConfigファイルもコマンドを利用することでConfigファイルを作成するできることがわかりました。
APIルーティング
routesディレクトリを確認するとLaravel11ではconsole.php, web.phpの2つのファイルになっています。Laravel10ではconsole.phpとweb.phpの他にapi.phpとchannels.phpが存在します。
apiルーティングのインストール
api.phpとchannels.phpを必要としないアプリケーションもあるので必要な場合はコマンドを利用して作成する必要があります。コマンドはphp artisan installを利用するので実行すると実行後のメッセージの最後にapi, broadcastingについての説明があります。
% php artisan install
//略
Available commands for the "install" namespace:
install:api Create an API routes file and install Laravel Sanctum or Laravel Passport
install:broadcasting Create a broadcasting channel routes file
コマンドを実行するとapi.phpファイルを作成するだけではなくLaravel Sanctumのインストールも行い、マイグレーションファイルによりSanctumで利用するpersonal_access_tokensテーブルの作成も行われます。
% php artisan install:api
./composer.json has been updated
Running composer update laravel/sanctum
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 0 updates, 0 removals
- Locking laravel/sanctum (v4.0.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
- Downloading laravel/sanctum (v4.0.0)
- Installing laravel/sanctum (v4.0.0): Extracting archive
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
INFO Discovering packages.
laravel/sail .................... DONE
laravel/sanctum ................. DONE
laravel/tinker .................. DONE
nesbot/carbon ................... DONE
nunomaduro/collision ............ DONE
nunomaduro/termwind ............. DONE
spatie/laravel-ignition ......... DONE
85 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
> @php artisan vendor:publish --tag=laravel-assets --ansi --force
INFO No publishable resources for tag [laravel-assets].
No security vulnerability advisories found.
INFO Published API routes file.
One new database migration has been published. Would you like to run all pending database migrations? (yes/no) [yes]:
>
INFO Running migrations.
2024_03_13_020123_create_personal_access_tokens_table .............................................................. 9.51ms DONE
INFO API scaffolding installed. Please add the [Laravel\Sanctum\HasApiTokens] trait to your User model.
コマンド実行後にroutesディレクトリを確認するとapi.phpファイルが作成されています。
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
まだ認証機能を追加していないので動作確認のためUserモデルからユーザ一覧を取得するルーティングをapi.phpファイルに追加します。
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
Route::get('/users', function () {
return \App\Models\User::all();
});
ユーザが存在しないのでSeedingを利用してユーザを作成します。database/seedersディレクトリのDatabaseSeeder.phpファイルを利用します。
% php artisan db:seed
INFO Seeding database.
<?php
namespace Database\Seeders;
use App\Models\User;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*/
public function run(): void
{
// User::factory(10)->create();
User::factory()->create([
'name' => 'Test User',
'email' => 'test@example.com',
]);
}
}
ブラウザからlocalhost:8000/api/usersにアクセスするとユーザ情報が表示されAPIルーティングが動作することを確認できます。
ルーティングの登録
デフォルトでは存在しないapi.phpファイルを作成することがわかりましたがどのファイルでapi.phpファイルが登録されてアプリケーションで利用できるのかを確認します。
Laravel10まではapp/ProvidersディレクトリにあるRouteServiceProvider.phpファイルの中で登録が行われていました。
<?php
namespace App\Providers;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;
class RouteServiceProvider extends ServiceProvider
{
/**
* The path to your application's "home" route.
*
* Typically, users are redirected here after authentication.
*
* @var string
*/
public const HOME = '/home';
/**
* Define your route model bindings, pattern filters, and other route configuration.
*/
public function boot(): void
{
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
$this->routes(function () {
Route::middleware('api')
->prefix('api')
->group(base_path('routes/api.php'));
Route::middleware('web')
->group(base_path('routes/web.php'));
});
}
}
Laravel11ではRouteServiceProviderではなくbootstrapディレクトリにあるapp.phpファイルの中で登録されています。
<?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',
api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
//
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();
php artisan route:listコマンドを利用して登録されているルーティングを確認することができます。
% php artisan route:list
GET|HEAD / ...................................................................................
POST _ignition/execute-solution ignition.executeSolution › Spatie\LaravelIgnition › Execu…
GET|HEAD _ignition/health-check ignition.healthCheck › Spatie\LaravelIgnition › HealthCheckCo…
POST _ignition/update-config ignition.updateConfig › Spatie\LaravelIgnition › UpdateConfi…
GET|HEAD api/user ............................................................................
GET|HEAD api/users ...........................................................................
GET|HEAD sanctum/csrf-cookie sanctum.csrf-cookie › Laravel\Sanctum › CsrfCookieController@show
GET|HEAD up ..................................................................................
apiの行をコメントアウトします。
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
// api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
再度php artisan route:listコマンドを実行するとapiに関するルーティングが登録されていないことがわかります。
% php artisan route:list
GET|HEAD / ...................................................................................
POST _ignition/execute-solution ignition.executeSolution › Spatie\LaravelIgnition › Execu…
GET|HEAD _ignition/health-check ignition.healthCheck › Spatie\LaravelIgnition › HealthCheckCo…
POST _ignition/update-config ignition.updateConfig › Spatie\LaravelIgnition › UpdateConfi…
GET|HEAD sanctum/csrf-cookie sanctum.csrf-cookie › Laravel\Sanctum › CsrfCookieController@show
GET|HEAD up ..................................................................................
upルーティング
bootstrap/app.phpファイルとroute:listコマンドの出力内容を確認するとupというルーティングを確認することができます。
ブラウザから確認するとアプリケーションが正常に起動しているか確認することができます。
.envファイルの確認
.envファイルの中でデータベースのデフォルト値がMySQLからSQLiteに変更になっていましたがその他の環境変数にも変更があります。
例えばLaravel11ではAPP_LOCALの値を.envの環境変数で設定することができるようになっています。
APP_LOCALE=en
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=en_US
これまではlocaleの値はconfigディレクトリの中のapp.phpファイルで直接更新を行なっていましたがLaravel11では.envの環境変数を利用して値を設定することができます。
/*
|--------------------------------------------------------------------------
| Application Locale Configuration
|--------------------------------------------------------------------------
|
| The application locale determines the default locale that will be used
| by Laravel's translation / localization methods. This option can be
| set to any locale for which you plan to have translation strings.
|
*/
'locale' => env('APP_LOCALE', 'en'),
'fallback_locale' => env('APP_FALLBACK_LOCALE', 'en'),
'faker_locale' => env('APP_FAKER_LOCALE', 'en_US'),
例えば.envファイルでAPP_FAKER_LOCALEの値をen_USからja_JPに変更します。
APP_FAKER_LOCALE=ja_JP
tinkerを利用してユーザの作成を行います。nameが日本語になっていることが確認できます。
% php artisan tinker
Psy Shell v0.12.0 (PHP 8.3.2 — cli) by Justin Hileman
> App\Models\User::factory()->create()
= App\Models\User {#5149
name: "山岸 結衣",
email: "watanabe.akemi@example.net",
email_verified_at: "2024-03-13 02:26:57",
#password: "$2y$12$Q2b9LL.GFrfbb0j1VA.HUeQq7Gnnlg17V79cb068N6ZJt38XY5ZAe",
#remember_token: "HxRvQIux8E",
updated_at: "2024-03-13 02:26:57",
created_at: "2024-03-13 02:26:57",
id: 2,
}
このように.envファイルの環境変数から設定できる値が以前のバージョンよりも増えています。
Middlewareの設定
Laravel11ではapp/Httpディレクトリの下にControllersディレクトリしか存在せずLaravel10までに存在したMiddlewareディレクトリとKernel.phpファイルが存在しません。
新しいMiddlewareの設定
Laravel10では新たにMiddlewareを追加した場合にはKernel.phpファイルに作成したMiddlewareを追加していましたが設定方法が変わっています。
動作確認のためにphp artisan make:middlewareコマンドを利用してExampleLoggerという名前のMiddlewareを作成します。
% php artisan make:middleware ExampleLogger
INFO Middleware [app/Http/Middleware/ExampleLogger.php] created successfully.
コマンドを実行するとapp/HttpディレクトリにMiddlewareディレクトリが作成されその下にExampleLoggerファイルが作成されます。
作成したMiddlewareはbootstrapディレクトリのapp.phpファイルで行うことができます。withMiddlewareメソッドに新たに作成したExampleLoggerを追加しています。
<?php
use App\Http\Middleware\ExampleLogger;
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',
api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
$middleware->append(ExampleLogger::class);
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();
開発サーバを起動してブラウザからlocalhost:8000にアクセスを行い、storage/logs/laravel.logファイルに”middleware working”の文字列が表示されれば正常に動作しています。
[2024-03-13 04:31:48] local.INFO: middleware working!
これまでのMiddlewareの設定
Laravel10までに存在していたMiddlewareディレクトリに保存されていたファイルについてはvendor/laravel/framework/src/illuminate/Foundation/Http/Middlewareディレクトリに存在します。
Kernel.phpファイルに記述されていたaliasの設定などについてはvendor/laravel/framework/src/illuminate/Foundation/ConfigurationディレクトリのMiddleware.phpファイルの中に記述されています。
Laravel10で行っていたMiddlewareの設定を行いたい場合を確認しておきます。
例えばVerifyCrsfTokenのミドルウェアでCRSFによる保護を無効にしたい場合はapp/Providers/AppServiceProvider.phpファイルのbootメソッドで行うことができます。
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
VerifyCsrfToken::except(['test/*']);
}
}
VerifyCsrfToken.phpファイルが持つ静的メソッドのexceptを利用しています。
public static function except($uris)
{
static::$neverVerify = array_values(array_unique(
array_merge(static::$neverVerify, Arr::wrap($uris))
));
}
app/Consoleディレクトリ
Laravel10ではappディレクトリの下のConsole/Kernel.phpファイルでscheduleとcommandの設定を行うことができしたがLaravel11ではConsoleディレクトリそのものがなくなっています。
scheduleやcommandの設定を行いたい場合にはroutesディレクトリのconsole.phpファイルで行います。
<?php
use Illuminate\Foundation\Inspiring;
use Illuminate\Support\Facades\Artisan;
Artisan::command('inspire', function () {
$this->comment(Inspiring::quote());
})->purpose('Display an inspiring quote')->hourly();
inspireという名前のコマンドが登録されており、1時間毎に実行されるように設定しています。登録されたコマンドをphp artisan listコマンドで確認することができます。
% php artisan list
Laravel Framework 11.0.3
//略
Available commands:
//略
help Display help for a command
inspire Display an inspiring quote
list List commands
migrate Run the database migrations
//略
スケジュールに登録されているのでphp artisan schedule:listコマンドで確認することができます。
% php artisan schedule:list
0 * * * * php artisan inspire .................. Next Due: 24 minutes from now
新しいCommandの作成
php artisan make:commandコマンドを利用して新しいcommandファイルを作成することができます。
% php artisan make:command LoggerCommand
INFO Console command [app/Console/Commands/LoggerCommand.php] created successfully.
appディレクトリの下にConsole/Commandsディレクトリが作成されその下にLoggerCommand.phpファイルが作成されます。
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class LoggerCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'app:logger-command';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Execute the console command.
*/
public function handle()
{
//
}
}
app/Console/Commandsに保存されたファイルは自動で登録が行われるので作成直後でもphp artisan listコマンドを実行すると作成したコマンドが登録されています。名前は$signatureに設定されているapp:logger-commandです。
% php artisan list
//略
app
app:logger-command Command description
作成したCommandを定期的にスケジュールで設定したい場合には以下のようにroutes/console.phpファイルで行うことができます。
<?php
use Illuminate\Support\Facades\Schedule;
use Illuminate\Foundation\Inspiring;
use Illuminate\Support\Facades\Artisan;
Artisan::command('inspire', function () {
$this->comment(Inspiring::quote());
})->purpose('Display an inspiring quote')->hourly();
Schedule::command('app:logger-command')->hourly();
スケジュールが設定されているかどうかはphp artisan schedule:listコマンドで確認できます。
% php artisan schedule:list
0 * * * * php artisan inspire .............. Next Due: 10 minutes from now
0 * * * * php artisan app:logger-command ... Next Due: 10 minutes from now
スケジュールが設定されていることが確認できます。