phpmig 在 PHP 8.5 下因依赖过时 Symfony 组件且官方已归档而失效;推荐改用 Laravel Migrator(illuminate/database),手动初始化连接与迁移器,兼容 PHP 8.5 并保持原有迁移文件结构。

phpmigrate 在 PHP 8.5 下直接报错:Class "Phpmig\Console\Application" not found
这是最常见现象——你装了 phpmig,执行 phpmig status 就崩,根本进不去。原因很直接:phpmig 官方早在 2016 年就停止维护,其依赖的 Symfony/console v2/v3 和 symfony/filesystem 等组件在 PHP 8.5 下大量使用已被移除的语法(比如 is_callable() 对 Closure 的处理变化、mb_ereg_replace() 废弃),且不兼容 PHP 8.4+ 新增的严格类型检查逻辑。
- 别试
composer require phpmig/phpmig+php -v 8.5组合,99% 失败 - 官方 GitHub 仓库已归档(Archived),Issues 全部关闭,没人修
- 强行降级到 PHP 8.2 或改用 Docker 隔离环境,只是绕开问题,不是解决
替代方案:用 Laravel Migrator 手动驱动,不依赖框架
你不需要整个 Laravel,只要它的迁移执行器。它轻量、PHP 8.5 原生支持、SQL 抽象干净,且配置完全可控。核心是复用 Illuminate\Database + Illuminate\Migrations,手动初始化连接和迁移路径。
- 安装最小依赖:
composer require illuminate/database ^10.0(Laravel 10 兼容 PHP 8.1–8.5) - 迁移文件保持原样:放在
migrations/目录下,命名如2024_05_10_120000_create_users_table.php - 关键区别:不用
phpmig migrate,改用自定义 PHP 脚本调用Illuminate\Database\Migrations\Migrator - 数据库配置必须显式传入数组,不能靠
.env自动加载(避免隐式依赖)
<?php
require_once 'vendor/autoload.php';
use Illuminate\Database\Capsule\Manager as Capsule;
use Illuminate\Database\Migrations\Migrator;
use Illuminate\Database\Migrations\MigrationRepositoryInterface;
$capsule = new Capsule();
$capsule->addConnection([
'driver' => 'mysql',
'host' => '127.0.0.1',
'database' => 'myapp',
'username' => 'root',
'password' => '',
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
]);
$capsule->setAsGlobal();
$repository = new \Illuminate\Database\Migrations\DatabaseMigrationRepository(
$capsule->getDatabaseManager(), 'migrations'
);
$migrator = new Migrator($repository, $capsule->getDatabaseManager(), new \Illuminate\Filesystem\Filesystem());
$migrator->run('migrations'); // 执行所有未跑的迁移
迁移文件里写 Schema::create() 报错:Call to undefined function Schema::create()
这是典型“只抄代码没抄上下文”的坑。Laravel 的 Schema 是 facade,必须提前启动服务容器或手动绑定,否则就是裸函数调用失败。
- 迁移文件开头必须加:
use Illuminate\Support\Facades\Schema; - 但仅加 use 不够——facade 依赖
Illuminate\Foundation\Application实例,而上面的手动脚本没启动它 - 正确做法:改用
$this->schema()(在继承Illuminate\Database\Migrations\Migration的类中可用),或直接用$this->connection->getSchemaBuilder() - 更稳妥的是放弃 facade,全部走底层 builder:
$this->connection->getSchemaBuilder()->create(...)
为什么不用 Doctrine Migrations?它不是更标准吗?
Doctrine Migrations 确实支持 PHP 8.5,也活跃维护,但它默认强耦合 Doctrine DBAL,一旦你项目用的是原生 PDO、Medoo 或自己封装的查询器,就得额外桥接一层,容易在 up()/down() 中混淆事务边界和连接状态。
立即学习“PHP免费学习笔记(深入)”;
- DBAL 的
SchemaManager对 MySQL 8.0+ 的 JSON、Generated Columns 支持滞后,某些 DDL 操作会静默失败 - 它的
version表结构固定为doctrine_migration_versions,无法与现有migrations表共存,迁移历史割裂 - 如果你只是从
phpmig迁移过来,已有几十个202x_*.php文件,Doctrine 要求重写为VersionXXXX类,成本远高于换 Laravel Migrator
MigrationException,但不会自动 rollback 已执行的语句。如果某次 up() 中间出错,得靠你在 down() 里手工补救,这点比 phpmig 更需谨慎。











