收藏版:Phinx 数据库迁移完全指南

2025-12-12 0 1,165

最近在维护老项目时,又一次用到了 Phinx。
这个工具我已经用了很多年,几乎每个项目都会用上它。它属于那种平时不常用,但每个项目都离不开 的工具。

问题在于,它用得不频繁,每次写迁移脚本时总会忘记某个参数怎么写、某个字段该用什么类型。
这些当然可以去查官方文档,但 Phinx 的文档虽然内容齐全,却总让我觉得信息分散、查起来不够顺手。

于是,我干脆花点时间,把自己常用的命令、配置方式、字段类型和参数说明都系统地整理了一遍。
一方面方便自己查阅,另一方面也希望能帮到同样在项目中使用 Phinx 的开发者。

如果你也在 PHP 项目里用 Phinx 管理数据库迁移,这篇文章或许能成为你的「快捷参考手册」。


前期配置

安装 Phinx

composer require robmorgan/phinx

初始化配置

执行初始化命令:

vendor/bin/phinx init

该命令会在项目根目录下生成一个 phinx.php 配置文件。
配置文件中:

  • ​paths 用于指定迁移脚本与填充脚本的路径;
  • ​environments 用于定义不同环境(例如开发、测试、生产)的数据库配置;
  • 若执行迁移命令时不指定环境,则默认使用 default_environment 指定的环境。

环境配置与 .env 支持

为了统一管理数据库配置,我习惯用 .env 文件来维护连接信息。
但由于 phinx 脚本并不运行在 PHP 框架生命周期内,常见的 .env 加载方式(如 Laravel 的)无法直接使用,因此我通常会额外安装 vlucas/phpdotenv:

composer require vlucas/phpdotenv

然后在 phinx.php 中添加如下配置:

<?php
$dotenv = DotenvDotenv::createImmutable(__DIR__);
$dotenv->load();
return [
    \"paths\" => [
        \"migrations\" => \"database/migrations\",
        \"seeds\" => \"database/seeds\"
    ],
    \"environments\" => [
        \"default_migration_table\" => \"phinxlog\",
        \"default_environment\" => \"production\",
        \"production\" => [
            \"adapter\" => \"mysql\",
            \"host\" => $_SERVER[\'DB_HOST\'],
            \"name\" => $_SERVER[\'DB_NAME\'],
            \"user\" => $_SERVER[\'DB_USER\'],
            \"pass\" => $_SERVER[\'DB_PASS\'],
            \"port\" => $_SERVER[\'DB_PORT\'],
            \"charset\" => $_SERVER[\'DB_CHARSET\']
        ]
    ]
];

常用命令

创建迁移文件

vendor/bin/phinx create 迁移名称

Phinx 会自动根据时间戳与名称生成迁移文件。
命名建议保持统一规范:

  • 创建表:Create + 表名 → 例如 CreateUsersTable​
  • 修改表:Modify + 表名 + 操作 → 例如 ModifyUsersAddStatus​
  • 删除表:Delete + 表名 → 例如 DeleteOldLogsTable​

执行迁移

没什么好说的,执行这个命令即可执行迁移

vendor/bin/phinx migrate

参数说明:

  • ​-e:指定环境(默认 production)
  • ​-t:指定执行到的版本号(不传则执行到最新)
  • ​--dry-run:仅打印 SQL 而不实际执行

设置断点(Breakpoint)

生产环境中执行迁移后,建议立刻设置断点。
断点能防止误操作导致大规模回滚。

vendor/bin/phinx breakpoint

参数:

  • ​-e 环境名
  • ​-t 版本号
  • ​-r 删除断点

回滚迁移

慎用!
迁移的回滚会撤销数据库结构更改,例如删除表或字段,表中数据会全部丢失。
生产环境不建议直接回滚,而是通过新的迁移来完成结构恢复。

vendor/bin/phinx rollback

参数说明:

  • ​-e 环境名
  • ​-t 指定版本号(或 0 回滚全部)
  • ​-d 按日期回滚(YYYYmmddHHiiss)
  • ​-f 强制回滚(忽略断点)
  • ​--dry-run 仅打印 SQL 不执行

查看状态

用于查看迁移执行状态,确认哪些迁移尚未执行。

vendor/bin/phinx status

参数说明:

  • -e:环境名

创建填充(Seeder)

vendor/bin/phinx seed:create 填充名称

命名建议使用表名 + 填充描述,例如:

UsersAddDemoDataSeeder

执行填充:

vendor/bin/phinx seed:run

参数:

  • ​-e 指定环境
  • ​-s 指定执行的 Seeder,可多次传入

迁移脚本详解

支持的字段类型

Phinx 在 MySQL 下支持的字段类型如下:

类型 MySQL 类型 必需参数 说明
​smallinteger​ SMALLINT — 小整数
​integer​ INT — 常规整数
​biginteger​ BIGINT — 大整数
​float​ FLOAT — 单精度浮点数
​double​ DOUBLE — 双精度浮点数
​decimal​ DECIMAL(M,D) ​precision,scale​ 定点小数(金额等)
​bit​ BIT — 位字段
​boolean​ TINYINT(1) — 布尔值(0/1)
​char​ CHAR(n) ​limit​ 定长字符串
​string​ VARCHAR(n) ​limit​ 可变长度字符串
​text​ TEXT — 文本
​enum​ ENUM(…) ​values​ 枚举类型
​set​ SET(…) ​values​ 集合类型
​uuid​ CHAR(36) — UUID字符串
​date​ DATE — 日期
​time​ TIME — 时间
​datetime​ DATETIME — 日期与时间
​timestamp​ TIMESTAMP — 时间戳
​binary​ BINARY(n) ​limit​ 定长二进制数据
​blob​ BLOB — 二进制大对象
​tinyblob​ TINYBLOB — 小型二进制
​mediumblob​ MEDIUMBLOB — 中型二进制
​longblob​ LONGBLOB — 超大二进制
​json​ JSON — JSON 数据类型

常用字段参数

参数名 类型 说明
​limit / length​ int 长度或字节限制
​default​ mixed 默认值
​null​ bool 是否允许为 NULL
​after​ string 放置在某个字段之后(或 PhinxDbAdapterMysqlAdapter::FIRST )
​comment​ string 字段注释
​precision​ int 小数总位数
​scale​ int 小数位数
​signed​ bool 是否允许负数
​values​ array/string 枚举或集合可选值,英文逗号隔开的字符串或数组
​identity​ bool 是否自增(需搭配 null:false)

各种操作调用代码

<?php

declare(strict_types=1);

use PhinxDbAdapterMysqlAdapter;
use PhinxMigrationAbstractMigration;

final class CreateTable extends AbstractMigration
{
    /**
     * Change Method.
     *
     * Write your reversible migrations using this method.
     *
     * More information on writing migrations is available here:
     * https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
     *
     * Remember to call \"create()\" or \"update()\" and NOT \"save()\" when working
     * with the Table class.
     */
    public function change(): void
    {
        // 前置说明:
        // create() 操作: 表不存在的情况下,创建表,并保存字段操作
        // update() 操作: 表存在的情况下,变更表,并保存字段操作
        // 所有的操作记得到最后一定需要对构建的表对象执行保存操作,否则不会执行

        // 判断表是否存在: $this->hasTable(\'table_name\');

        // 删除表: $this->table(\'table_name\')->drop()->save();

        // 构建表
        $table = $this->table(\'table_name\', [\'id\' => \'table_id\', \'comment\' => \'这是 table 表\']);
        // 第二个参数字段,可不传,主要用于在 create() 时构建表级的基本信息
        // 支持的参数:
        // id:            主键 ID 列,传入字符串或者布尔类型
        //                    如果是字符串:按照字符串内容创建自增主键
        //                    如果是false:不自动创建主建
        //                    如果不传:自动创建名称为 id 的自增主键
        // comment:       设置表的注释
        // row_format:    设置表的行格式(MySQL 特有,例如 DYNAMIC, COMPACT, REDUNDANT, COMPRESSED)
        // engine:        设置表的存储引擎(MySQL 特有,例如 InnoDB, MyISAM, MEMORY)
        // collation:     设置字符集的排序规则,默认 utf8mb4_unicode_ci
        // signed:        整数类型是否允许负数,默认 false
        // limit:         设置主键最大长度

        // 变更表注释
        $table->changeComment(\'这是 table 表新的注释\');
        // 更改主键,可以设置多个列组联合主键
        $table->changePrimaryKey([\'new_id\']);
        // 重命名表
        $table->rename(\'new_table_name\');

        // 检查字段是否存在:$table->hasColumn(\'username\');

        // 重命名字段
        $table->renameColumn(\'老字段名\', \'新字段名\');

        // 删除字段
        $table->removeColumn(\'字段名\');

        // 添加字段
        $table->addColumn(\'字段名\', \'类型\', [\'参数\'])
              ->addColumn(\'avatar\', \'string\', [\'comment\' => \'头像\', \'null\' => true, \'after\' => \'name\'])
              ->addColumn(\'created_at\', \'integer\', [\'comment\' => \'创建时间\', \'null\' => false, \'limit\' => MysqlAdapter::INT_BIG]);
        // 类型:
        // 很多不必要或可以简化定义的类型,例如数字方面,可以全部都设置为 `integer` 通过 `limit` 参数设置长度即可自动创建对应类型
        // 以下是支持的类型:
        // smallinteger(SMALLINT):  小整数
        // integer(INT):            常规整数
        // biginteger(BIGINT):      大整数
        // float(FLOAT):            单精度浮点数
        // double(DOUBLE):          双精度浮点数
        // decimal(DECIMAL(M,D)):   定点小数,必须携带 `precision` 与 `scale` 参数
        // bit(BIT):                位字段
        // boolean(TINYINT(1)):     布尔值(0/1)

        // char(CHAR(n)):           定长字符串,必须携带 `limit` 参数
        // string(VARCHAR(n)):      可变长度字符串,必须携带 `limit` 参数
        // text(TEXT):              文本
        // enum(ENUM(...)):         枚举类型,必须携带 `values` 参数
        // set(SET(...)):           集合类型,必须携带 `values` 参数
        // uuid(CHAR(36)):          UUID字符串

        // date(DATE):              日期(YYYY-MM-DD)
        // time(TIME):              时间(HH:MM:SS)
        // datetime(DATETIME):      日期与时间
        // timestamp(TIMESTAMP):    时间戳

        // binary(BINARY(n)):       定长二进制数据,必须携带 `limit` 参数
        // blob(BLOB):              二进制大对象
        // tinyblob(TINYBLOB):      小型二进制
        // mediumblob(MEDIUMBLOB):  中型二进制
        // longblob(LONGBLOB):      超大二进制
        // json(JSON):JSON          数据类型

        // 参数:
        // 以下是支持的参数:
        // limit / length:          长度,int 类型,内容跟随字段类型变化
        // default:                 默认值,类型根据字段类型变化
        // null:                    是否允许为 null,bool 类型,true 或者 false
        // after:                   指定字段应该放在哪个列之后,string 类型传递列名,或者 PhinxDbAdapterMysqlAdapter::FIRST
        // comment:                 字段注释,string 类型
        // precision:               结合 scale 设置小数精度,int 类型
        // scale:                   结合 precision 设置小数精度,int 类型
        // signed:                  是否允许负数,bool 类型
        // values:                  枚举类型,可以是英文逗号分隔的string,或array
        // identity:                数字类型自增长,bool类型,需要设置 null:false

        // 修改字段
        $table->changeColumn(\'字段名\', \'类型\', [\'参数\']);

        // 设置索引
        $table->addIndex([\'字段名\']);

        // 删除索引
        $table->removeIndex([\'字段名\']);
        // 或者
        $table->removeIndexByName(\'索引名\');
    }
}

填充脚本(Seeder)示例

<?php

declare(strict_types=1);

use PhinxSeedAbstractSeed;

class TableAddDemoDataSeeder extends AbstractSeed
{
    /**
     * Run Method.
     *
     * Write your database seeder using this method.
     *
     * More information on writing seeders is available here:
     * https://book.cakephp.org/phinx/0/en/seeding.html
     */
    public function run(): void
    {
        // 构建数据
        $data = [
            [
                \'body\'    => \'foo\',
                \'created\' => date(\'Y-m-d H:i:s\'),
            ],
            [
                \'body\'    => \'bar\',
                \'created\' => date(\'Y-m-d H:i:s\'),
            ]
        ];
        // 构建表
        $table = $this->table(\'table_name\');

        // 添加数据,并保存
        $table->insert($data)
              ->saveData();

        // 清空表中的所有数据
        $table->truncate();
    }
}

老项目迁移接入

如果你是从已有数据库切换到 Phinx,可使用 phinx-migrations-generator 自动生成迁移文件。

composer require odan/phinx-migrations-generator --dev

它会直接读取现有的 phinx.php 配置,无需额外设置。
执行以下命令即可生成当前数据库结构的迁移文件:

vendor/bin/phinx-migrations generate

最后

Phinx 是一个非常轻量却强大的迁移工具,适用于几乎所有独立 PHP 项目。
写这篇笔记的初衷很简单——自己每次都要重新翻文档太麻烦了,不如干脆整理一份系统化的版本。
如果你也有相同的困扰,希望这篇文章能让你变得方便一些
觉得有用的话,别忘了收藏这篇文章~
更多内容可以在我的网站 hejunjie.life 查看

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

申明:本文由第三方发布,内容仅代表作者观点,与本网站无关。对本文以及其中全部或者部分内容的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。本网发布或转载文章出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,也不代表本网对其真实性负责。

左子网 编程相关 收藏版:Phinx 数据库迁移完全指南 https://www.zuozi.net/35735.html

常见问题
  • 1、自动:拍下后,点击(下载)链接即可下载;2、手动:拍下后,联系卖家发放即可或者联系官方找开发者发货。
查看详情
  • 1、源码默认交易周期:手动发货商品为1-3天,并且用户付款金额将会进入平台担保直到交易完成或者3-7天即可发放,如遇纠纷无限期延长收款金额直至纠纷解决或者退款!;
查看详情
  • 1、描述:源码描述(含标题)与实际源码不一致的(例:货不对板); 2、演示:有演示站时,与实际源码小于95%一致的(但描述中有”不保证完全一样、有变化的可能性”类似显著声明的除外); 3、发货:不发货可无理由退款; 4、安装:免费提供安装服务的源码但卖家不履行的; 5、收费:价格虚标,额外收取其他费用的(但描述中有显著声明或双方交易前有商定的除外); 6、其他:如质量方面的硬性常规问题BUG等。 注:经核实符合上述任一,均支持退款,但卖家予以积极解决问题则除外。
查看详情
  • 1、左子会对双方交易的过程及交易商品的快照进行永久存档,以确保交易的真实、有效、安全! 2、左子无法对如“永久包更新”、“永久技术支持”等类似交易之后的商家承诺做担保,请买家自行鉴别; 3、在源码同时有网站演示与图片演示,且站演与图演不一致时,默认按图演作为纠纷评判依据(特别声明或有商定除外); 4、在没有”无任何正当退款依据”的前提下,商品写有”一旦售出,概不支持退款”等类似的声明,视为无效声明; 5、在未拍下前,双方在QQ上所商定的交易内容,亦可成为纠纷评判依据(商定与描述冲突时,商定为准); 6、因聊天记录可作为纠纷评判依据,故双方联系时,只与对方在左子上所留的QQ、手机号沟通,以防对方不承认自我承诺。 7、虽然交易产生纠纷的几率很小,但一定要保留如聊天记录、手机短信等这样的重要信息,以防产生纠纷时便于左子介入快速处理。
查看详情

相关文章

猜你喜欢
发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务