PHPackages                             griffin/griffin - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. griffin/griffin

ActiveLibrary[Database &amp; ORM](/categories/database)

griffin/griffin
===============

Griffin is a Graph-Oriented Migration Framework for PHP

1.0.4(5y ago)1441[5 issues](https://github.com/griffin-php/griffin/issues)MITPHPPHP &gt;=8.0

Since Apr 24Pushed 5y ago2 watchersCompare

[ Source](https://github.com/griffin-php/griffin)[ Packagist](https://packagist.org/packages/griffin/griffin)[ RSS](/packages/griffin-griffin/feed)WikiDiscussions main Synced today

READMEChangelog (1)Dependencies (7)Versions (6)Used By (0)

griffin
=======

[](#griffin)

[![](https://raw.githubusercontent.com/griffin-php/griffin/main/icon.svg)](https://raw.githubusercontent.com/griffin-php/griffin/main/icon.svg)

Griffin is a Graph-Oriented Migration Framework for PHP

[![Build Status](https://github.com/griffin-php/griffin/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/griffin-php/griffin/actions/workflows/test.yml?query=branch%3Amain)[![Latest Stable Version](https://camo.githubusercontent.com/24ec1908ab7a20cda3699a25355e06cc551152686630afcac10a326a24c6578e/68747470733a2f2f706f7365722e707567782e6f72672f6772696666696e2f6772696666696e2f762f737461626c653f666f726d61743d666c6174)](https://packagist.org/packages/griffin/griffin)[![Codecov](https://camo.githubusercontent.com/9fd2bc66dd6c82638cabbbe94afa6a9258027ba7a23a0201ce6958166f6f380c/68747470733a2f2f636f6465636f762e696f2f67682f6772696666696e2d7068702f6772696666696e2f6272616e63682f6d61696e2f67726170682f62616467652e737667)](https://codecov.io/gh/griffin-php/griffin)[![License](https://camo.githubusercontent.com/8ff3293718364f36948b80922c46d7e1c3275e4d9e5f9e2a02a182a5f300f929/68747470733a2f2f706f7365722e707567782e6f72672f6772696666696e2f6772696666696e2f6c6963656e73653f666f726d61743d666c6174)](https://packagist.org/packages/griffin/griffin)

TL;DR
-----

[](#tldr)

Griffin is a generic migration framework that uses graph theory to provision anything. It plans execution based on migration dependencies and runs them in the correct order.

```
use FooBar\Database\Driver;
use Griffin\Migration\Container;
use Griffin\Migration\Migration;
use Griffin\Planner\Planner;
use Griffin\Runner\Runner;

$driver = new Driver(); // Pseudo Database Driver

$orders = (new Migration())
    ->withName('orders')
    ->withAssert(fn() => $driver->table->has('orders'))
    ->withUp(fn() => $driver->table->create('orders'))
    ->withDown(fn() => $driver->table->drop('orders'));

$items = (new Migration())
    ->withName('items')
    ->withDependencies(['orders'])
    ->withAssert(fn() => $driver->table->has('items'))
    ->withUp(fn() => $driver->table->create('items'))
    ->withDown(fn() => $driver->table->drop('items'));

$container = (new Container())
    ->addMigration($orders)
    ->addMigration($items);

$planner = new Planner($container);
$runner  = new Runner($planner);

$runner->up(); // create everything
$runner->down(); // destroy everything

$runner->up('items'); // create orders and items
$runner->down('orders'); // destroy orders and items

// create orders and items
// regardless the order of elements informed
$runner->up('items', 'orders');

// Dry Run
$runner->setDryRun();
$runner->up(); // do nothing
$runner->down(); // do nothing
$runner->unsetDryRun();
```

You might want to check [more examples](https://github.com/griffin-php/griffin-examples) to learn how to define migrations using Griffin.

Installation
------------

[](#installation)

This package uses [Composer](https://packagist.org/packages/griffin/griffin) as default repository. You can install it adding the name of package in `require`section of `composer.json`, pointing to the latest stable version.

```
{
  "require": {
    "griffin/griffin": "^1.0"
  }
}
```

### CLI

[](#cli)

This package includes the Griffin framework. If you want a CLI to run your migrations, please check [Griffin CLI](https://github.com/griffin-php/griffin-cli).

Introduction
------------

[](#introduction)

Migrations are tools to change system current state, adding (or removing) features based on previous state. Generally, they are used to create database structures from scratch, provisioning tables or columns using a step-by-step approach. There are standalone tools to run migrations, like Phinx. Also, there are other ones embedded into frameworks, like Laravel or Doctrine.

If we inspect them, they use a linear approach, where next state must *migrate*from current state. Migrations can be rolled back, so if we want to revert some changes, we must *rollback* from current state to previous state. Each migration knows how to create and destroy itself.

For example, we have three migrations `A`, `B` and `C` created sequentially. If our current state is `A` and we must migrate to `C`, we must execute migrations `B` and `C`, in that order, respectively. If we want to rollback from `C` to `A`, we must execute them backwards, `B` and `A`. But if you want to execute migrations `A` and `C`, because they are dependent, and ignore `B` for some reason, you can't. Even, if you want to rollback `C` and `A` ignoring `B`, you are locked.

Bringing to the world of database migrations, you can create migration `Orders`that creates table into schema. Right after that, other developer creates a migration called `Messages` without any dependency from `Orders`. Next, you create a migration named `Items` with a foreign key to `Orders`. Everything works fine and you deploy them to *stage* environment on friday.

```
./migrations/001_Orders.php
./migrations/002_Messages.php
./migrations/003_Items.php

```

On monday you find a problem with your migrations and you want to rollback. But you don't want to remove `Messages` table because other developer is showing the newest features to Product Owner.

And here comes Griffin.

Description
-----------

[](#description)

Griffin is a migration framework based on directed graphs, where each migration can be migrated and rolled back independently. Also, you can define dependencies for each migration and Griffin is responsible to plan the execution priority.

Based on provisioning tools like Puppet and Terraform, Griffin can plan execution and run it using graph theory, where each migration works like a vertice and dependencies define directed paths. Griffin searches for circular dependencies on planning and can automatically rollback changes if errors were found.

Griffin is a generic migration framework and it is not database focused. You are free to use Griffin to provisioning what needed, like directory structures, packages, crawlers and even database schemas.

Usage
-----

[](#usage)

Each migration must be defined using `Griffin\Migration\MigrationInterface`. Migrations must return its name with `getName` method and dependencies with `getDependencies`. Each migration must check if resource is created using `assert` method, returning a boolean as result. Also, they are responsible to create the resource using `up` method and to destroy using `down`. Griffin uses these methods to plan and run migrations.

```
namespace FooBar\Database\Migration;

use FooBar\Database\Driver;
use Griffin\Migration\MigrationInterface;

class Items implements MigrationInterface
{
    public function __construct(
        private Driver $driver,
    ) {}

    public function getName(): string
    {
        return self::class;
    }

    /**
     * @return string[]
     */
    public function getDependencies(): array
    {
        return [
            Order::class,
            Product::class,
        ];
    }

    public function assert(): bool
    {
        return $this->driver->table->has('items');
    }

    public function up(): void
    {
        $this->driver->table->create('items');
    }

    public function down(): void
    {
        $this->driver->table->drop('items');
    }
}
```

You can create objects from class `Griffin\Migration\Migration`, that implements `Griffin\Migration\MigrationInterface` and behaviors can be defined using immutable methods.

```
use FooBar\Database\Driver;
use Griffin\Migration\Migration;

$driver = new Driver();

$migration = (new Migration())
    ->withName('items')
    ->withDependencies(['orders', 'products'])
    ->withAssert(fn() => $driver->table->has('items'))
    ->withUp(fn() => $driver->table->create('items'))
    ->withDown(fn() => $driver->table->drop('items'));
```

### Planning

[](#planning)

Griffin plans your migrations execution before running them using `Griffin\Planner\Planner`. Every migration must be added to `Griffin\Migration\Container` instances and attached to planner on construction.

```
use FooBar\Database\Migration;
use Griffin\Migration\Exception as MigrationException;
use Griffin\Planner\Exception as PlannerException;
use Griffin\Planner\Planner;

$planner = new Planner();

$planner->getContainer()
    ->addMigration(new Migration\Orders())
    ->addMigration(new Migration\Items())
    ->addMigration(new Migration\Products());

/** @var Griffin\Migration\Container $migrations **/

try {
    // plan up execution for every migration
    $migrations = $planner->up();
    // plan up execution for Orders and Items
    $migrations = $planner->up(Migration\Items::class)
    // plan down execution
    $migrations = $planner->down();
} catch (PlannerException $e) {
    // PlannerException::DEPENDENCY_CIRCULAR (Circular Dependency Found)
    // PlannerException::DEPENDENCY_INVALID (Invalid Dependency Data Type)
} catch (MigrationException $e) {
    // MigrationException::NAME_UNKNOWN (Unknown Migration Name)
    // MigrationException::NAME_DUPLICATED (Duplicated Migration Name)
    // MigrationException::CALLABLE_UNKNOWN (Unknown Callable Function)
}
```

You can add migrations to container in any order, because dependencies are checked on planning stage. Migration names are unique and must not be duplicated. Using objects from `Griffin\Migration\Migration` immutable class can throw errors if callables were not defined.

This stage also searches for circular dependencies, where `A` depends of `B` and `B` depends of `A`. This type of requirement is not allowed and will rise an exception describing the problem.

### Running

[](#running)

After planning, Griffin runs migrations using `Griffin\Runner\Runner` class. Internally, Griffin plans migrations execution first and after that it will execute running on second stage.

```
use FooBar\Database\Migration;
use Griffin\Migration\Exception as MigrationException;
use Griffin\Planner\Exception as PlannerException;
use Griffin\Runner\Exception as RunnerException;
use Griffin\Runner\Runner;

$runner = new Runner();

$runner->getPlanner()->getContainer()
    ->addMigration(new Migration\Orders())
    ->addMigration(new Migration\Items())
    ->addMigration(new Migration\Products());

try {
    // run up for everything
    $runner->up();
    // run up for Orders and Items
    $runner->up(Migration\Items::class)
    // run complete down
    $runner->down();
} catch (RunnerException $e) {
    // RunnerException::ROLLBACK_CIRCULAR (Circular Rollback Found)
} catch (PlannerException $e) {
    // PlannerException::DEPENDENCY_CIRCULAR (Circular Dependency Found)
    // PlannerException::DEPENDENCY_INVALID (Invalid Dependency Data Type)
} catch (MigrationException $e) {
    // MigrationException::NAME_UNKNOWN (Unknown Migration Name)
    // MigrationException::NAME_DUPLICATED (Duplicated Migration Name)
    // MigrationException::CALLABLE_UNKNOWN (Unknown Callable Function)
}
```

For every planned migration `Griffin\Runner\Runner` will execute migration `up`method if `assert` returns `false`. During a migration execution, errors can be raised and Griffin will try to automatically rollback executed migrations. If during rollback from this migration Griffin finds another error, an exeception will be throw.

If you want to rollback migrations manually, Griffin will use migration `assert`method to check if resource was created and if this method returns `true`, migration method `down` will be called. As before, if Griffin finds an error it will try to recreate resources.

### Event Dispatcher

[](#event-dispatcher)

Lastly, Griffin use PSR-14 Event Dispatcher to trigger events after and before migrations up and down. You can use it to create a logger, as example, using `league/event` package or any PSR-14 implementation.

```
use FooBar\Database\Migration;
use Griffin\Event;
use Griffin\Migration\Container;
use Griffin\Planner\Planner;
use Griffin\Runner\Runner;
use League\Event\EventDispatcher;

$container = new Container();
$planner   = new Planner($container);
$runner    = new Runner($planner);

$logger = fn($event)
    => printf("%s::%s\n", get_class($event), get_class($event->getMigration()));

$dispatcher = new EventDispatcher(); // PSR-14

$dispatcher->subscribeTo(Event\Migration\UpBefore::class, $logger);
$dispatcher->subscribeTo(Event\Migration\UpAfter::class, $logger);

$dispatcher->subscribeTo(Event\Migration\DownBefore::class, $logger);
$dispatcher->subscribeTo(Event\Migration\DownAfter::class, $logger);

$runner
    ->setEventDispatcher($dispatcher)
    ->addMigration(new Migration\Orders());

$runner->up();
$runner->down();

// Griffin\Event\Migration\UpBefore::Database\Migration\Table\Item
// Griffin\Event\Migration\UpAfter::Database\Migration\Table\Item
// Griffin\Event\Migration\DownBefore::Database\Migration\Table\Item
// Griffin\Event\Migration\DownAfter::Database\Migration\Table\Item
```

Development
-----------

[](#development)

You can use Docker Compose to build an image and run a container to develop and test this package.

```
docker-compose build
docker-compose run --rm php composer install
docker-compose run --rm php composer test
```

References
----------

[](#references)

- Wikipedia: [Graph Theory](https://en.wikipedia.org/wiki/Graph_theory)
- Wikipedia: [Path on Graph Theory](https://en.wikipedia.org/wiki/Path_%28graph_theory%29)
- Wikipedia: [Schema Migration](https://en.wikipedia.org/wiki/Schema_migration)

License
-------

[](#license)

This package is opensource and available under MIT license described in [LICENSE](https://github.com/griffin-php/griffin/blob/main/LICENSE).

Icons made by [Freepik](https://www.freepik.com) from [Flaticon](https://www.flaticon.com).

###  Health Score

27

—

LowBetter than 47% of packages

Maintenance13

Infrequent updates — may be unmaintained

Popularity15

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity61

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~4 days

Total

5

Last Release

1876d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/907c8faa9e7d6e1777b18bafcc2b94909b1b82a9fe15b462fb18b02f88a00da1?d=identicon)[wandersonwhcr](/maintainers/wandersonwhcr)

---

Top Contributors

[![wandersonwhcr](https://avatars.githubusercontent.com/u/5286703?v=4)](https://github.com/wandersonwhcr "wandersonwhcr (306 commits)")

---

Tags

databasedependenciesframeworkgraphgraph-theorymigrationmigrationsphpmigrationdatabasemigrationsgraphdependenciesgraph-theory

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/griffin-griffin/health.svg)

```
[![Health](https://phpackages.com/badges/griffin-griffin/health.svg)](https://phpackages.com/packages/griffin-griffin)
```

###  Alternatives

[doctrine/migrations

PHP Doctrine Migrations project offer additional functionality on top of the database abstraction layer (DBAL) for versioning your database schema and easily deploying changes to it. It is a very easy to use and a powerful tool.

4.8k217.3M546](/packages/doctrine-migrations)[robmorgan/phinx

Phinx makes it ridiculously easy to manage the database migrations for your PHP app.

4.5k48.7M458](/packages/robmorgan-phinx)[odan/phinx-migrations-generator

Migration generator for Phinx

233913.8k25](/packages/odan-phinx-migrations-generator)[hyperf/database

A flexible database library.

192.9M319](/packages/hyperf-database)[tommyknocker/pdo-database-class

Framework-agnostic PHP database library with unified API for MySQL, MariaDB, PostgreSQL, SQLite, MSSQL, and Oracle. Query Builder, caching, sharding, window functions, CTEs, JSON, migrations, ActiveRecord, CLI tools, AI-powered analysis. Zero external dependencies.

846.1k](/packages/tommyknocker-pdo-database-class)[dragon-code/laravel-data-dumper

Adding data from certain tables when executing the `php artisan schema:dump` console command

3422.6k](/packages/dragon-code-laravel-data-dumper)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
