ThinkPHP 6 需安装 topthink/think-migration 才支持 migrate 命令;迁移文件不可修改,应新增文件做增量变更;多环境需同步 migration 文件与 migration 表状态;自定义迁移中禁用 Db 门面,应使用 getConnection() 或手动引入 facade。

Migration 命令执行失败:找不到 migrate:run 命令
ThinkPHP 6 默认不内置 Migration 功能,必须手动安装 topthink/think-migration 扩展。没装就直接运行 php think migrate:run,会报错 Command "migrate:run" is not defined。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 先执行
composer require topthink/think-migration(注意不是think-orm的迁移组件) - 确认
config/migration.php存在且已配置好数据库连接(它默认读database.default,但部分版本需显式指定connection) - 若仍报错,检查
app/command.php是否已自动注册命令 —— 新版 TP6.1+ 通常自动加载,老项目可能需要手动追加think\migration\Command
生成迁移文件时表名/字段写错,改完代码再 migrate:refresh 不生效
migrate:refresh 本质是先 down 再 up,但它只按迁移文件里的 up() 和 down() 方法执行,不会重新解析 PHP 文件内容。如果改了已有迁移文件的 up() 逻辑,再跑 refresh,旧的 down 操作可能已删表,导致 up 失败或结构不一致。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 迁移文件一旦
up过,就应视为“已发布”,禁止修改其up()/down()内容 - 字段补漏、索引调整等,必须新建迁移文件,用
$this->table('user')->change()或addColumn()等方法增量操作 - 本地调试可用
migrate:rollback --step=1回退单步,确认 down 逻辑无误后再提交
多环境迁移时 dev 和 prod 表结构不一致
常见原因是迁移文件未纳入 Git,或不同环境执行了不同批次的 migrate:run,又没同步 migration_status 表。TP 的迁移状态存在数据库的 migration 表里,如果 prod 环境手动建过表、跳过了某些迁移,后续再跑就会冲突。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 所有迁移文件必须提交 Git,并在部署脚本中明确执行
php think migrate:run --force(--force绕过生产环境确认) - 上线前先查
SELECT * FROM migration ORDER BY id DESC LIMIT 5,比对各环境最后执行的 migration 文件名是否一致 - 避免在 prod 直接
migrate:reset—— 它会清空所有迁移记录并删表,风险极高
自定义迁移类中 use Db 报错 Class 'Db' not found
在 up() 或 down() 方法里直接调用 Db::table('user')->insert(...),会触发类未加载错误。因为 Migration 类运行在命令行上下文,未自动引入 ThinkPHP 的门面类别名。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 改用原生 PDO 操作:
$this->getConnection()->insert(...)(getConnection()返回PDO实例) - 如需 ORM 能力,手动引入:
use think\facade\Db;,但注意不能用模型(UserModel::create()),因模型依赖完整 HTTP 上下文 - 大量初始化数据建议另写命令行指令(
php think seed:user),而非塞进迁移文件
迁移真正难的不是写 up/down,而是让所有人——包括刚入职的同事和 CI 流水线——在同一时刻、同一路径下,执行完全相同的迁移序列。任何绕过 migrate:run 的手动 DDL 操作,都会让 migration 表变成废纸。


















