はじめに
数年以上、数世代以上前のLaravel プロジェクトを新しいLaravel 12へ移行する際、段階的なアップグレードは非常に手間がかかります。プロジェクトの規模が小規模〜中規模であれば、新規プロジェクトを作成して移行する方法が効率的です。
Claude codeなどを利用することで、両方の構造の違いを分析して自動でファイルを作成することも可能です。
移行の判断基準
新規作成がおすすめのケース
- モデル数が10個以下
- コントローラーが10個以下
- カスタムパッケージへの依存が少ない
- テストカバレッジが低い
段階的アップグレードが必要なケース
- 大規模プロジェクト(モデル50個以上など)
- 複雑なカスタムパッケージを多用
- テストカバレッジが高く、テストを維持したい
Docker環境の構築
PHP 8.3 + MySQL 8.0 + NginxのDocker環境を構築します。
docker-compose.yml
services:
app:
build:
context: .
dockerfile: docker/php/Dockerfile
volumes:
- .:/var/www/html
depends_on:
- mysql
nginx:
image: nginx:alpine
ports:
- "8082:80"
volumes:
- .:/var/www/html
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- app
mysql:
image: mysql:8.0
platform: linux/amd64 # M1/M2 Mac用
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: laravel
MYSQL_USER: laravel
MYSQL_PASSWORD: secret
volumes:
- mysql-data:/var/lib/mysql
ports:
- "33062:3306"
volumes:
mysql-data:
docker/php/Dockerfile
FROM php:8.3-fpm
RUN apt-get update && apt-get install -y \
git curl libpng-dev libonig-dev libxml2-dev libzip-dev zip unzip \
&& docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd zip \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
WORKDIR /var/www/html
Laravel 12のインストール
# コンテナ内でLaravelをインストール
docker exec app composer create-project laravel/laravel /tmp/laravel-tmp
docker exec app bash -c "cp -r /tmp/laravel-tmp/. /var/www/html/"
主な変更点
1. モデルの配置場所
Laravel 旧バージョンではappディレクトリ直下でしたが、Laravel 8以降はapp/Modelsに配置します。
// 旧: app/User.php
namespace App;
// 新: app/Models/User.php
namespace App\Models;
2. マイグレーションの書き方
// 旧: クラス形式
class CreateUsersTable extends Migration
{
public function up()
{
Schema::create(users, function (Blueprint $table) {
$table->increments(id);
});
}
}
// 新: 無名クラス形式
return new class extends Migration
{
public function up(): void
{
Schema::create(users, function (Blueprint $table) {
$table->id(); // bigIncrements の省略形
});
}
};
3. ルートの書き方
// 旧: 文字列形式
Route::get(/users, UserController@index);
// 新: 配列形式(推奨)
use App\Http\Controllers\UserController;
Route::get(/users, [UserController::class, index]);
4. リレーションの型指定
// 旧
public function posts()
{
return $this->hasMany(AppPost);
}
// 新
use Illuminate\Database\Eloquent\Relations\HasMany;
public function posts(): HasMany
{
return $this->hasMany(Post::class);
}
データ移行
本番環境のデータベースをダンプして、Docker環境にインポートします。
# 本番からダンプ
mysqldump -u user -p database_name > backup.sql
# Dockerにインポート
docker exec -i mysql-container mysql -uroot -proot database_name < backup.sql
注意点
- 外部キー制約の型: 旧版がint(unsigned)で新版がbigint(unsigned)の場合、インポート時にエラーが発生します。SQLファイルを直接インポートするか、マイグレーションの型を合わせる必要があります。
- 非推奨パッケージ: fideloper/proxyやlaravelcollective/htmlなど、廃止・統合されたパッケージがあります。
- PHP 8の構文: コンストラクタプロパティプロモーション、名前付き引数、match式などが使えるようになります。
まとめ
小〜中規模プロジェクトであれば、段階的アップグレードより新規作成+移行の方が効率的です。Docker環境を用意し、モデル・マイグレーション・コントローラー・ビューを順次移行していくことで、クリーンな状態でLaravel 12の恩恵を受けられます。