配置
当您使用 Init 命令初始化项目时,Phinx 会在您项目的根目录中创建一个默认文件。默认情况下,此文件使用 YAML 数据序列化格式,但您可以使用 --format 命令行选项来指定 yaml、yml、json 或 php 格式。
如果给定了 --configuration 命令行选项,Phinx 将加载指定的文件。否则,它将尝试查找 phinx.php、phinx.json、phinx.yml 或 phinx.yaml,并加载找到的第一个文件。更多信息请参见命令章节。
请记得将配置文件存放在 Web 服务器上无法公开访问的目录之外。该文件包含您的数据库凭据,可能会被意外地以纯文本形式提供给外界。
请注意,JSON 和 YAML 文件是被解析的,而 PHP 文件是被包含 (included) 的。这意味着:
- 它必须返回一个配置项数组。
- 变量作用域是局部的,也就是说,您需要显式声明您的初始化文件读取或修改的任何全局变量。
- 其标准输出被抑制。
- 与 JSON 和 YAML 不同,您可以省略环境连接详情,而是指定
connection,其中必须包含一个已初始化的 PDO 实例。当您希望迁移与您的应用程序交互和/或共享相同的连接时,这非常有用。但是,请记住也要传递数据库名称,因为 Phinx 无法从 PDO 连接中推断出这一点。
$app = require 'app/phinx.php';
$pdo = $app->getDatabase()->getPdo();
return [
'environments' => [
'default_environment' => 'development',
'development' => [
'name' => 'devdb',
'connection' => $pdo
]
]
];
迁移路径
第一个选项指定了您的迁移目录的路径。Phinx 默认使用 %%PHINX_CONFIG_DIR%%/db/migrations。
%%PHINX_CONFIG_DIR%% 是一个特殊令牌,会自动被替换为您的 phinx 配置文件所在的根目录。
要覆盖默认的 %%PHINX_CONFIG_DIR%%/db/migrations,您需要在配置中添加以下内容:
paths:
migrations: /your/full/path
您也可以通过在配置中使用数组来提供多个迁移路径:
paths:
migrations:
- application/module1/migrations
- application/module2/migrations
可以通过为每个迁移路径添加一个键来指定类的命名空间:
paths:
migrations:
App\Module1\Migrations: application/module1/migrations
App\Module2\Migrations: application/module2/migrations
您也可以在路径中使用 %%PHINX_CONFIG_DIR%% 令牌。
paths:
migrations: '%%PHINX_CONFIG_DIR%%/your/relative/path'
迁移是使用 glob 捕获的,因此您可以为多个目录定义一个模式。
paths:
migrations: '%%PHINX_CONFIG_DIR%%/module/*/{data,scripts}/migrations'
自定义迁移基类
默认情况下,所有迁移都将继承自 Phinx 的 AbstractMigration 类。通过在配置中设置 migration_base_class,可以将其更改为一个继承自 AbstractMigration 的自定义类:
migration_base_class: MyMagicalMigration
种子路径
第二个选项指定了您的种子目录的路径。Phinx 默认使用 %%PHINX_CONFIG_DIR%%/db/seeds。
%%PHINX_CONFIG_DIR%% 是一个特殊令牌,会自动被替换为您的配置文件所在的根目录。
要覆盖默认的 %%PHINX_CONFIG_DIR%%/db/seeds,您需要在 yaml 配置中添加以下内容:
paths:
seeds: /your/full/path
您也可以通过在配置中使用数组来提供多个种子路径:
paths:
seeds:
- /your/full/path1
- /your/full/path2
您也可以在路径中使用 %%PHINX_CONFIG_DIR%% 令牌。
paths:
seeds: '%%PHINX_CONFIG_DIR%%/your/relative/path'
可以通过为每个种子路径添加一个键来指定类的命名空间:
paths:
seeds:
App\Module1\Seeds: application/module1/seeds
App\Module2\Seeds: application/module2/seeds
自定义 Seeder 基类
默认情况下,所有 seeder 类都将继承自 Phinx 的 AbstractSeed 类。通过在配置中设置 seed_base_class,可以将其更改为一个继承自 AbstractSeed 的自定义类:
seed_base_class: MyMagicalSeeder
自定义迁移模板
可以通过在配置文件中定义模板文件路径来使用自定义迁移模板:
templates:
file: src/templates/customMigrationTemplate.php
自定义 Seeder 模板
可以通过在配置文件中定义模板文件路径来使用自定义 Seeder 模板:
templates:
seedFile: src/templates/customSeederTemplate.php
环境
Phinx 的一个关键特性是支持多个数据库环境。您可以使用 Phinx 在开发环境中创建迁移,然后在生产环境中运行相同的迁移。环境是在 environments 嵌套集合下指定的。例如:
environments:
default_migration_table: phinxlog
default_environment: development
production:
adapter: mysql
host: localhost
name: production_db
user: root
pass: ''
port: 3306
charset: utf8mb4
collation: utf8mb4_unicode_ci
这将定义一个名为 production 的新环境。
当多个开发人员在同一个项目上工作,并且每个人都有不同的环境(例如,遵循 <环境类型>-<开发者名称>-<机器名称> 这样的约定),或者当您需要为不同目的(分支、测试等)设置独立的环境时,可以使用环境变量 PHINX_ENVIRONMENT 来覆盖 yaml 文件中的默认环境:
export PHINX_ENVIRONMENT=dev-`whoami`-`hostname`
迁移表
为了跟踪某个环境的迁移状态,Phinx 会创建一个表来存储这些信息。您可以通过配置 default_migration_table 来自定义此表的创建位置,该配置将作为所有环境的默认值:
environment:
default_migration_table: phinxlog
如果省略此字段,则默认为 phinxlog。对于支持它的数据库(如 Postgres),可以在模式(schema)名称前加上一个点分隔符(.)。例如,phinx.log 将在 phinx 模式下创建 log 表,而不是在 public(默认)模式下创建 phinxlog 表。
您也可以为每个环境单独指定 migration_table。任何未指定 migration_table 的环境将回退使用在顶层定义的 default_migration_table。下面是一个使用示例:
environment:
default_migration_table: phinxlog
development:
migration_table: phinxlog_dev
# ... development 的其余设置
production:
# ... production 的其余设置
在上面的示例中,development 环境将在 phinxlog_dev 表中查找迁移状态,而 production 环境将使用 phinxlog 表。
表前缀和后缀
您可以定义表前缀和表后缀:
environments:
development:
....
table_prefix: dev_
table_suffix: _v1
testing:
....
table_prefix: test_
table_suffix: _v2
套接字连接
当使用 MySQL 适配器时,也可以使用套接字(socket)代替网络连接。套接字路径通过 unix_socket 配置:
environments:
default_migration_table: phinxlog
default_environment: development
production:
adapter: mysql
name: production_db
user: root
pass: ''
unix_socket: /var/run/mysql/mysql.sock
charset: utf8
外部变量
Phinx 会自动获取任何以 PHINX_ 为前缀的环境变量,并使其在配置文件中作为一个令牌(token)可用。令牌的名称与变量完全相同,但您必须通过在两边用两个 %% 符号包裹来访问它。例如:'%%PHINX_DBUSER%%'。如果您希望将机密的数据库凭据直接存储在服务器上,而不是存储在版本控制系统中,这个功能尤其有用。以下示例可以轻松演示此功能:
environments:
default_migration_table: phinxlog
default_environment: development
production:
adapter: mysql
host: '%%PHINX_DBHOST%%'
name: '%%PHINX_DBNAME%%'
user: '%%PHINX_DBUSER%%'
pass: '%%PHINX_DBPASS%%'
port: 3306
charset: utf8
数据源名称 (DSN)
Phinx 支持使用数据源名称 (DSN) 来指定连接选项,这在您使用单个环境变量来保存数据库凭据时非常有用。根据底层驱动程序的不同,PDO 有不同的 DSN 格式,因此 Phinx 使用了一种被其他项目(如 Doctrine、Rails、AMQP、PaaS 等)使用的、与数据库无关的 DSN 格式。
<adapter>://[<user>[:<pass>]@]<host>[:<port>]/<name>[?<additionalOptions>]
一个 DSN 至少需要 adapter、host 和 name。
- 如果没有用户名,则不能指定密码。
port必须是一个正整数。additionalOptions采用查询字符串的形式,并将作为选项数组传递给适配器。
environments:
default_migration_table: phinxlog
default_environment: development
production:
# 示例数据源名称
dsn: mysql://root@localhost:3306/mydb?charset=utf8
DSN 被解析后,其值会与已有的连接选项合并。在 DSN 中指定的值绝不会覆盖任何直接作为连接选项指定的值。
environments:
default_migration_table: phinxlog
default_environment: development
development:
dsn: '%%DATABASE_URL%%'
production:
dsn: '%%DATABASE_URL%%'
name: production_database
如果提供的 DSN 无效,它将被完全忽略。
支持的适配器
Phinx 目前原生支持以下数据库适配器:
- MySQL: 指定
mysql适配器。 - PostgreSQL: 指定
pgsql适配器。 - SQLite: 指定
sqlite适配器。 - SQL Server: 指定
sqlsrv适配器。
适配器可用的设置如下:
adapter: 要使用的适配器名称,例如pgsql。host: 数据库服务器的主机名(或 IP 地址)。port: 数据库服务器的 TCP 端口号。user: 数据库的用户名。pass: 数据库的密码。name: 此环境的数据库名称。对于 SQLite,建议使用绝对路径,不带文件扩展名。suffix: 用于 SQLite 数据库文件的后缀。默认为.sqlite3。schema: 对于 PostgreSQL,允许指定要用于数据库的模式。默认为public。
对于每个适配器,您可以通过在配置对象中设置常量名的小写版本来配置底层 PDO 对象的行为。这适用于 PDO 选项(例如 \PDO::ATTR_CASE 将是 attr_case)和特定于适配器的选项(例如对于 MySQL,您可以将 \PDO::MYSQL_ATTR_IGNORE_SPACE 设置为 mysql_attr_ignore_space)。请查阅 PDO 文档以了解允许的属性及其值。
例如,要设置上述示例选项:
$config = [
"environments" => [
"development" => [
"adapter" => "mysql",
# 其他适配器设置
"attr_case" => \PDO::ATTR_CASE,
"mysql_attr_ignore_space" => 1,
],
],
];
默认情况下,Phinx 设置的唯一属性是 \PDO::ATTR_ERRMODE 为 PDO::ERRMODE_EXCEPTION。不建议覆盖此设置。
MySQL
MySQL 适配器有一个不幸的限制,即某些操作会导致隐式提交,无论事务状态如何。值得注意的是,此列表包括 CREATE TABLE、ALTER TABLE 和 DROP TABLE,这些是 Phinx 将运行的最常见操作。这意味着与其他适配器在迁移失败时会尝试优雅地回滚事务不同,如果 MySQL 的迁移失败,它可能会使您的数据库处于部分迁移的状态。
SQLite
声明一个 SQLite 数据库使用简化的结构:
environments:
development:
adapter: sqlite
name: ./data/derby
suffix: ".db" # 默认为 ".sqlite3"
testing:
adapter: sqlite
memory: true # 将 memory 设置为 *任何* 值都会覆盖 name
从 PHP 8.1 开始,只要 open_basedir 未设置,SQLite 适配器就支持通过使用 URI 方案来支持 cache 和 mode 查询参数。
environments:
testing:
adapter: sqlite
name: my_app
mode: memory # 决定新数据库是只读打开、读写打开、读写并创建(如果不存在),还是一个纯内存数据库,从不与磁盘交互。
cache: shared # 决定新数据库是使用共享缓存模式还是私有缓存打开。
SQL Server
当使用 sqlsrv 适配器并连接到命名实例时,您应该省略 port 设置,因为 SQL Server 会自动协商端口。此外,省略 charset: utf8 或将其更改为 charset: 65001,这对应于 SQL Server 的 UTF8。
自定义适配器
您可以通过向 AdapterFactory 注册一个 Phinx\Db\Adapter\AdapterInterface 的实现来提供自定义适配器:
$name = 'fizz';
$class = 'Acme\Adapter\FizzAdapter';
AdapterFactory::instance()->registerAdapter($name, $class);
适配器可以在调用 $app->run() 之前的任何时候注册,该调用通常由 bin/phinx 执行。
模板
您可以通过多种方式覆盖 Phinx 生成模板的方式:
file- 要使用的备用文件的路径。class- 用于模板的类,必须实现Phinx\Migration\CreationInterface接口。style- 用于模板的样式,可以是change或up_down,如果未设置,则默认为change。
您应该只使用这些选项中的一个。这些选项可以通过向创建命令传递命令行选项来覆盖。在配置文件中的使用示例是:
templates:
style: up_down
别名
模板创建类名可以设置别名,并与创建命令的 --class 命令行选项一起使用。
设置别名的类仍然需要实现 Phinx\Migration\CreationInterface 接口。
aliases:
permission: \Namespace\Migrations\PermissionMigrationTemplateGenerator
view: \Namespace\Migrations\ViewMigrationTemplateGenerator
版本顺序
在回滚或打印迁移状态时,Phinx 会根据 version_order 选项对已执行的迁移进行排序,该选项可以有以下值:
creation(默认值): 迁移按其创建时间排序,这也是其文件名的一部分。execution: 迁移按其执行时间(也称为开始时间)排序。
引导路径
您可以提供一个 bootstrap PHP 文件的路径,该文件将在任何 phinx 命令运行之前被包含。请注意,设置外部变量来修改配置将不起作用,因为此时配置已经被解析了。
paths:
bootstrap: 'phinx-bootstrap.php'
在引导脚本中,以下变量将可用:
/**
* @var string $filename 由配置提供的文件名
* @var string $filePath 文件的绝对真实路径
* @var \Symfony\Component\Console\Input\InputInterface $input 正在执行的命令的输入对象
* @var \Symfony\Component\Console\Output\OutputInterface $output 正在执行的命令的输出对象
* @var \Phinx\Console\Command\AbstractCommand $context 正在执行的命令对象
*/
功能标志
对于一些破坏性变更,Phinx 提供了一种选择不使用新行为的方式。以下标志可用:
unsigned_primary_keys: Phinx 是否应将主键创建为无符号整数? (默认:true)column_null_default: Phinx 是否应默认将列创建为可为 null? (默认:true)
由于 MySQL 的 TIMESTAMP 字段不支持 2038-01-19 之后的日期,您可以选择对由 addTimestamps() 函数创建的字段使用 DATETIME 字段类型:
add_timestamps_use_datetime: Phinx 是否应将 created_at 和 updated_at 字段创建为 datetime? (默认:false)
feature_flags:
unsigned_primary_keys: false
这些值也可以通过修改 Phinx\Config\FeatureFlags 类上的类字段来设置,将标志名称转换为驼峰命名法 (camelCase),例如:
Phinx\Config\FeatureFlags::$unsignedPrimaryKeys = false;