Loïc Faugeron Technical Blog

phinx 05/08/2015

phinx is a lightweight migration library, completly decoupled from any framework and libraries. In its most simple form, it allows you to write SQL statements to upgrade and downgrade your schema, or insert / delete data.

Installation

First of all, we need to install it using Composer:

composer require robmorgan/phinx:^0.4

With this we get a phar that can be run:

phinx

Tip: make your vendor's binaries available by adding vendor/bin to your $PATH. export PATH="vendor/bin:$PATH".

Then we need to configure the settings:

<?php
// File: phinx.php

$parameters = \Symfony\Component\Yaml\Yaml::parse(file_get_contents(__DIR__.'/app/config/parameters.yml'));

return array(
    'paths' => array(
        'migrations' => __DIR__.'/migrations'
    ),
    'environments' => array(
        'default_migration_table' => 'migration',
        'default_database' => 'prod',
        'prod' => array(
            'adapter' => 'pgsql', // Could also be "mysql", "sqlite" or "sqlsrv"
            'host' => $parameters['parameters']['database_host'],
            'name' => $parameters['parameters']['database_name'],
            'user' => $parameters['parameters']['database_user'],
            'pass' => $parameters['parameters']['database_pass'],
            'port' => $parameters['parameters']['database_port'],
            'charset' => 'utf8',
        ),
        'test' => array(
            'adapter' => 'pgsql',
            'host' => $parameters['parameters']['database_host'],
            'name' => $parameters['parameters']['database_name'].'_test',
            'user' => $parameters['parameters']['database_user'],
            'pass' => $parameters['parameters']['database_pass'],
            'port' => $parameters['parameters']['database_port'],
            'charset' => 'utf8',
        ),
    ),
);

The configuration could also be written in YAML, here I used PHP to be able to share the database configuration with the application's one.

Usage example

Migration files can be bootstrapped using the command:

phinx create FirstVersion

Which results in the following file (migrations/20150805201245_first_version.php):

<?php

use Phinx\Migration\AbstractMigration;

class FirstVersion extends AbstractMigration
{
    public function change()
    {
    }
}

In the change method we need to get a Table object using $this->table('table_name') and then use it to describe the changes in the schema: phinx is then able to figure out how to reverse them if necessary.

If you'd rather write SQL queries directly you need to remove change and define a up and a down method. In them you can use $this->query('SQL') to execute your queries.

Example:

<?php

use Phinx\Migration\AbstractMigration;

class FirstVersion extends AbstractMigration
{
    public function up()
    {
        $this->query('CREATE TABLE my_table;');
    }

    public function down()
    {
        $this->query('DROP TABLE my_table;');
    }
}

Migrating an application then becomes as simple as:

phinx migrate

And rolling back:

phinx rollback

Tips

Time for the personal tips!

Using Doctrine Migrations is fine when using Doctrine ORM, but for the rest (including Doctrine DBAL) I'd rather use phinx.

While Table allows to write portable migrations and saves you the time of writing the down method, I'd advise you to write directly SQL queries: it's a layer less to learn and it will be consistent with the migrations where you insert / update data.

Conclusion

Migration libraries are all very similar, the nice touch of phinx is that it's not coupled to any framework and it doesn't require any integration.

Give it a try!