Laravel迁移失败主因是版本不兼容:类名与文件名须严格一致、禁用PHP命名参数、必须安装doctrine/dbal且调用change()方法、外键需手动启用、时间戳不可手动修改。

直接改迁移文件名或硬套新语法,90% 的迁移失败都源于此——Laravel 迁移不是纯 PHP 脚本,它受框架版本、PHP 版本、DBAL 依赖三重约束,错一个就报错。
迁移类命名和继承必须匹配 Laravel 主版本
从 Laravel 6.x 开始,迁移类名必须与文件名严格一致,且必须继承 Illuminate\Database\Migrations\Migration。旧项目若还用 use Illuminate\Database\Schema\Blueprint 单独引入、没写完整基类,升级后会报 Class not found。
- 错误写法(Laravel 9+ 不认):
class CreateUsersTable extends Migration但文件是2014_10_12_000000_create_users_table.php→ 类名应为CreateUsersTable,不能是CreateUserTable或Create_Users_Table - 检查命令:
php artisan migrate:status看是否所有迁移显示 “Ran”;若某条显示 “N”,但表已存在,说明类加载失败 - 修复动作:运行
composer dump-autoload刷新自动加载,尤其跨主版本(如 5.8 → 6.x)后必做
PHP 命名参数(column:'user_id')在迁移里是定时炸弹
PHP 8.0+ 才支持命名参数,但 Laravel 迁移常跑在低版本 PHP 上。你在 Laravel 10 项目里写了 $table->string(column:'title'),PHP 7.4 或 8.0 以下直接报 syntax error, unexpected ':'。
- 正确写法永远是位置参数:
$table->string('title')、$table->unsignedBigInteger('user_id') -
unsignedInteger()在 Laravel 9+ 已废弃,必须换unsignedBigInteger(),否则建表后外键关联失败 - 查当前 PHP 版本:
php -v;确认迁移能否跑通:php -l database/migrations/2020_01_01_000000_create_posts_table.php
Schema 构建器行为变化:外键、字段修改、默认值
Laravel 9+ 默认禁用外键约束,Schema::create() 内部自动调用 disableForeignKeyConstraints(),导致你写了 constrained() 却没生成真实外键。
- 补救方式:在迁移
up()方法末尾加Schema::enableForeignKeyConstraints(); - 改字段类型(如
string→text)需doctrine/dbal,否则报Unknown database type enum或SQLSTATE[42000] - 设置默认值别用
default: null,改用nullable();若真要DEFAULT NULL,得用useCurrentNull()(Laravel 10.28+)
时间戳不一致导致 migrate 反复执行或跳过
迁移靠文件名前缀(YYYY_MM_DD_HHMMSS)排序执行,一旦手动改名、删文件、跨环境同步漏掉几个,migrations 表记录和磁盘文件就对不上。
- 现象:
php artisan migrate显示 “nothing to migrate”,但查表发现某张表没建;或反复提示 “table already exists” - 诊断命令:
php artisan migrate:status对比输出和SELECT * FROM migrations; - 安全补漏方式:
php artisan migrate --path=database/migrations/2023_01_01_000000_add_status_to_orders.php,别靠猜时间戳 - 严禁手动删
migrations表记录或清空它——这会让框架彻底失序
最易被忽略的是:迁移文件本身没变,但底层 doctrine/dbal 版本变了,change() 行为就可能失效;别只盯着 Laravel 版本,composer show doctrine/dbal 也得看一眼。


















