PHP单独使用phinx使用数据库迁移

可以独立使用的迁移包对比后,感觉phinx更接近PHP的使用习惯。

为什么要单独用?

因为我不想数据库的迁移文件依赖于某种框架。本来是可以在框架里直接安装这个包的,但是发现这个包依赖cakephp,而cakephp的函数与thinkphp的env()函数冲突。

官方文档:Phinx Documentation - 0.16

安装

新建个空目录,然后在这个目录执行:

composer require robmorgan/phinx

安装好后,在目录vendor\bin中能找到文件:phinx.bat。

建议:将vendor\bin的路径加入到系统变量path中,就可以直接用这个命令了。

命令

查看可用命令列表

phinx

查看可用命令的帮助,如:

phinx init --help

初始配置文件

phinx init E:\a\b

假设项目目录为:E:\a\b\。 在目录下创建配置文件phinx.php和phinx.yml,建议使用.php的文件(因为不用额外装包),删除掉phinx.yml。项目目录不是phinx的安装目录。

文件内容如下:

php 复制代码
<?php

return
[
    'paths' => [
        'migrations' => '%%PHINX_CONFIG_DIR%%/db/migrations',
        'seeds' => '%%PHINX_CONFIG_DIR%%/db/seeds'
    ],
    'environments' => [
        'default_migration_table' => 'phinxlog',
        'default_environment' => 'development',
        'production' => [
            'adapter' => 'mysql',
            'host' => 'localhost',
            'name' => 'production_db',
            'user' => 'root',
            'pass' => '',
            'port' => '3306',
            'charset' => 'utf8',
        ],
        'development' => [
            'adapter' => 'mysql',
            'host' => 'localhost',
            'name' => 'development_db',
            'user' => 'root',
            'pass' => '',
            'port' => '3306',
            'charset' => 'utf8',
        ],
        'testing' => [
            'adapter' => 'mysql',
            'host' => 'localhost',
            'name' => 'testing_db',
            'user' => 'root',
            'pass' => '',
            'port' => '3306',
            'charset' => 'utf8',
        ]
    ],
    'version_order' => 'creation'
];

**[path]**节可以指定迁移文件和种子文件所在的目录,可以指定为数组,如:

'paths' => [

'migrations' => [

'%%PHINX_CONFIG_DIR%%/db/migrations',

'd:/a/b'

],

'seeds' => '%%PHINX_CONFIG_DIR%%/db/seeds'

],

%%PHINX_CONFIG_DIR%% 变量是phinx的内置变量,是配置文件所在的目录。

**[environments]**节为数据库环境配置:

default_migration_table:指定保存迁移记录的表名,执行迁移时会生成以这个为表名的表,保存每次执行的记录。

default_environment:默认使用的环境,development为开发环境,将development节下的数据库配置好。

创建迁移文件

phinx create SystemDict --path=E:\a\b\db\migrations -c E:\a\b\phinx.php

phinx create 表名 --path=存放迁移文件的目录 -c 配置文件路径(即执行init时创建的文件)

将会在目录中创建一个迁移文件,名称类似于:20250830084537_system_dict.php。

如果用的是IDE打开文件,可以看到AbstractMigration是标红的,这是因为phinx包不在项目目录中。可以配置下IDE的PHP包含路径:D:\soft\php\tools\vendor。

这是vscode的配置,我这里用的是Trae。

执行迁移

phinx migrate -c E:\a\b\phinx.php

将命令行的当前目录切换为:E:\a\b\,可直接执行phinx migrate,不需要指定配置文件。

可以看到执行成功了,但是由于迁移文件是个空的,所以数据库中没有任何变化,只是多了一个表:phinxlog。这就是配置文件中指定的表名,非必要时不需要特意去改。表里有了一条记录:

现在到迁移文件中添加表的定义:

php 复制代码
<?php

declare(strict_types=1);

use Phinx\Migration\AbstractMigration;

final class SystemDict 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
    {
        // 定义表
        $table = $this->table('__table_prefix__system_dict', ['id' => false, 'primary_key' => ['id'], 'comment' => '系统字典']);

        // 定义表字段和索引
        $table->addColumn('id', 'biginteger', ['limit' => 20, 'null' => false, 'signed' => false, 'identity' => true, 'comment' => '主键'])
            ->addColumn('create_time', 'datetime', ['comment' => '创建时间'])
            ->addColumn('update_time', 'datetime', ['comment' => '更新时间'])
            ->addColumn('code', 'string', ['limit' => 100, 'comment' => '字典编码'])
            ->addColumn('title', 'string', ['comment' => '字典标题,显示名'])
            ->addIndex('code', ['unique' => true, 'name' => 'idx_dict_code'])
            ->create();
    }
}

现在再去执行迁移命令,发现什么都没有变化。这是因为这个文件前一次已经执行过了,在phinxlog表中已经有了记录。要再次执行这个文件,需要先回滚掉前一次执行的记录。

为什么要在表定义设置 id=false?

phinx默认情况下会建一个名为id的int类型的主键字段,但有时候我们不想用int或是不想用id作为主键字段名。这时我们就要自已定义字段了。

回滚

phinx rollback -c E:\a\b\phinx.php

加了代码后执行,会得到一个错误:

这是因为之前执行时没有建表,现在回滚导致找不到表。先将代码中那表的代码注释掉,再执行回滚,回滚后再放开注释掉的代码。当然也可以手动删除迁移表中的记录,但不建议这么干。

每次执行回滚,只会回滚最后一次执行的迁移。如果想一次回滚多个记录,可以用-t参数指定回滚到的版本,具体可以查看回滚的帮助。

phinx rollback -c E:\a\b\phinx.php -t 20250830084537 # 是回滚到这个版本(这个不会回滚,只回滚这个版本之后的所有版本)

phinx rollback -c E:\a\b\phinx.php -t 0 # -t 参数指定为0时,将回滚所有版本!!

回滚后再执行下迁移,可以看到表建好了:

查看回滚的帮助

phinx rollback --help

支持的字段类型

以下是各种数据库都支持的类型

binary

boolean

char

date

datetime

decimal

float

double

smallinteger

integer

biginteger

string

text

time

timestamp

uuid

如果想用特殊类型,参考:Writing Migrations - 0.16,为了通用性,不建议使用特殊的类型。

问题

目前还没有发现如何统一定义表前缀。

相关推荐
BingoGo19 小时前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack19 小时前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo2 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack2 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack3 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo3 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack4 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理4 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
feifeigo1234 天前
matlab画图工具
开发语言·matlab
dustcell.4 天前
haproxy七层代理
java·开发语言·前端