php artisan migrate没反应或提示“Nothing to migrate”,是因为Laravel只执行migrations表中未记录的迁移文件;需确认.env数据库配置生效、迁移文件命名规范(YYYY_MM_DD_HHMMSS_格式)、且该文件名未存在于migrations表中。

php artisan migrate 没反应?先盯住 migrations 表和 .env
运行 php artisan migrate 后提示 “Nothing to migrate”,大概率不是命令错了,而是 Laravel 根本没发现要跑的迁移——它只执行 migrations 表里没有记录的文件。你新加的 2026_09_15_100000_create_posts_table.php 文件,如果已存在于 migrations 表的 migration 字段中,就不会再执行。
必须确认三件事:
-
DB_DATABASE和DB_CONNECTION在.env里配对且生效(比如 MySQL 连得上,库名存在);Mac 上常见连错成sqlite或空库,结果迁移静默跑在错误数据库里 - 迁移文件确实在
database/migrations/下,命名严格为YYYY_MM_DD_HHMMSS_*格式,不能含中文、短横线(-)或大写字母 - 执行
SELECT * FROM migrations;看新文件名是否已存在;若存在但表实际没建,说明上次执行中断了,需手动删掉该行或用php artisan migrate:reset(仅开发环境)
Mac 上外键报错 SQLSTATE[HY000]: General error: 1005 怎么办
这问题在 macOS + MySQL(尤其 Homebrew 安装的 8.4+)特别高频,本质是字段类型不匹配或引擎不一致。Laravel 默认用 InnoDB,但如果你手动建过表、或迁移中混用了 foreignId() 和 unsignedBigInteger(),就容易触发。
检查点很具体:
- 被引用的主键字段(如
users.id)是不是BIGINT UNSIGNED?那关联字段(如posts.user_id)也必须声明为$table->foreignId('user_id')->constrained();,不能写成$table->unsignedBigInteger('user_id')后再手动加外键 - 所有涉及外键的表,必须用
InnoDB引擎;如果某张表是MyISAM(比如手动创建的),迁移会直接失败 - Mac 上 MySQL 默认字符集可能是
utf8mb4_0900_ai_ci,但旧迁移文件若写了charset=utf8,可能引发隐式转换冲突;统一在config/database.php的mysql配置里加'charset' => 'utf8mb4'和'collation' => 'utf8mb4_unicode_ci'
--path 参数在 Mac 终端里怎么写才不拼错路径
Mac 用户常因路径分隔符或相对路径理解偏差导致 --path 静默失效:Laravel 把 --path 当作相对于 database/migrations/ 的子路径,不是绝对路径。
正确姿势只有两种:
- 只传文件名:
php artisan migrate --path=2026_09_15_100000_create_posts_table.php(推荐,最安全) - 传子目录名(如果迁移放在
database/migrations/2026/下):php artisan migrate --path=2026/2026_09_15_100000_create_posts_table.php - 绝对禁用:
--path=database/migrations/...或--path=./database/migrations/...——Laravel 会把它拼成database/migrations/database/migrations/...,然后找不到文件,还不报错
如果真要从非标准目录加载(比如团队共用 migration 库),必须用 --realpath 并给绝对路径:php artisan migrate --realpath=/Users/you/project/custom-migrations/2026_09_15.php
想重来一遍但怕丢数据?别碰 migrate:fresh
php artisan migrate:fresh 在 Mac 本地开发时看似方便,但它会无差别 DROP TABLE IF EXISTS 所有业务表(除了 migrations 和 failed_jobs)。你手写的种子数据、测试用户、甚至刚填的配置表,全清空,且不可逆。
更稳妥的替代路径:
- 只回退最后一次迁移:
php artisan migrate:rollback(它只撤回最近一个batch,哪怕 batch 里有 5 个迁移) - 回退指定数量:
php artisan migrate:rollback --step=2 - 如果 down() 方法写得靠谱,
php artisan migrate:reset是比fresh更可控的选择;但前提是每个迁移的down()真正删了对应结构,而不是留着空方法
真正麻烦的是那种改了字段类型又没写 down() 的迁移——Laravel 不会提醒你逻辑不完整,等你 rollback 时才发现表还在,字段却回不去了。


















