起因於某次 Laravel 的 issue(#5899)中提出的一個狀況
問題中描述的狀況是
簡而言之,因為不同 migration 中擁有相同的 class 名稱導致執行 migrate 建立資料表時發生錯誤
雖然 migration 檔名前面會加上日期防止檔名完全相同,但是 class 名稱並不會這麼做
上述兩個 migration 檔案,class name 都會是 CreateNewTable
在後來的 PR(#36906)中,有人提出一個解決辦法
使用 PHP 的 Anonymous classes 來解決這個問題
下方是匿名 migration 的範例
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
// 沒有名稱的 class
return new class extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('people', function (Blueprint $table) {
$table->string('first_name')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('people', function (Blueprint $table) {
$table->dropColumn('first_name');
});
}
};
匿名 migration 在 8.37 中正式支援
Laravel 官方有在考慮 migration 預設是否要直接使用匿名 class
因為屬於 Breaking change,有可能在 Laravel 9 中才會變成預設設定
如果希望指令預設直接生成匿名 migration
官方提到可以手動修改 stub 檔案,首先在專案中輸入指令,生成 stubs 資料夾
php artisan stub:publish
修改 stubs 資料夾底下的三個檔案
// 將三個 stub 檔案中原本的 class name 設定
class {{ class }} extends Migration
{
...
}
// 改為使用匿名 class
return new class extends Migration
{
...
// 大括弧後面要加上 ";"
};
這時輸入指令 make:migration 就會看到新生成的 migration 檔案使用匿名 class
參考資料
New in Laravel 8.37: Anonymous Migrations with no Class Names
Anonymous Migrations in Laravel 8.37
Anonymous classes
後端工程師, PHP 基金會每月 5 鎂小額贊助人 稍微擅長 PHP、Python 與 Google Search,偶爾寫寫 TypeScript 對於逗號後面必須加空格有著絕對的堅持