Installation Add the package via Composer:
composer require alexssssss/phinx-bundle
Register the bundle in config/app.php under providers:
Alexssssss\PhinxBundle\PhinxBundle::class,
Configuration Publish the default config:
php artisan vendor:publish --provider="Alexssssss\PhinxBundle\PhinxBundle" --tag="config"
Update config/phinx.php with your database connection details (e.g., mysql, postgres).
First Migration Generate a migration file:
php artisan phinx:generate create_users_table
Edit the generated file in database/migrations/ (Phinx-specific format, not Laravel’s).
Run Migrations Execute migrations:
php artisan phinx:migrate
Rollback if needed:
php artisan phinx:rollback
Use Phinx to manage database schema changes (e.g., adding a created_at column to users):
php artisan phinx:generate add_created_at_to_users
Edit the migration to include:
$table->addColumn('created_at', 'datetime')
->addIndex(['created_at'], ['name' => 'idx_users_created_at']);
Run the migration:
php artisan phinx:migrate
Laravel + Phinx Coexistence
Schema builder for application-specific migrations (e.g., seeding, soft deletes).Environment-Specific Configs
Override config/phinx.php per environment (e.g., config/phinx.local.php):
'environments' => [
'default_migration_table' => 'phinxlog',
'connection' => 'mysql',
'host' => env('DB_HOST'),
'name' => env('DB_DATABASE'),
'user' => env('DB_USERNAME'),
'pass' => env('DB_PASSWORD'),
'port' => env('DB_PORT', '3306'),
],
Seeding Data
Use Phinx’s seed() method for one-time data setup:
public function run()
{
$users = [
['name' => 'Admin', 'email' => 'admin@example.com'],
];
$this->insert('users', $users);
}
Run seeds:
php artisan phinx:seed
Blue-Green Deployments
--target flag to migrate to a specific version:
php artisan phinx:migrate --target=20230101000000
Schema::getConnection()->getPdo() for zero-downtime schema changes.Laravel Eloquent + Phinx: Avoid mixing Eloquent models with Phinx-generated tables. Use raw queries or repositories for Phinx-managed tables.
DB::table('phinx_users')->insert([...]);
Shared Migrations:
Store Phinx migrations in a shared repo (e.g., database/phinx_migrations) and symlink them into the project:
ln -s ../shared-migrations/database/migrations database/
Testing:
Use php artisan phinx:rollback in phpunit.xml to reset the test database:
<env name="DB_CONNECTION" value="sqlite_test"/>
<env name="PHINX_ENV" value="testing"/>
Migration Table Conflicts
phinxlog by default. If Laravel’s migrations table conflicts, rename Phinx’s table in config/phinx.php:
'default_migration_table' => 'phinx_migrations',
Transaction Handling Phinx migrations run in a single transaction by default. For large migrations, disable transactions:
$this->execute("SET autocommit=1");
Laravel’s Schema vs. Phinx
Schema uses its own migration table (migrations). Phinx ignores this table.default_migration_table.Foreign Key Constraints Phinx doesn’t automatically handle foreign keys across migrations. Use raw SQL or disable constraints temporarily:
$this->execute("SET FOREIGN_KEY_CHECKS=0");
// ... migrations ...
$this->execute("SET FOREIGN_KEY_CHECKS=1");
Verbose Output
Enable debug mode in config/phinx.php:
'debug' => true,
Or run with:
php artisan phinx:migrate --debug
Dry Runs Test migrations without applying them:
php artisan phinx:migrate --dry-run
SQL Logging
Enable SQL logging in config/phinx.php:
'log' => [
'echo' => true,
],
Custom Commands
Extend Phinx’s CLI with custom commands. Example: Add a phinx:fresh command to wipe and remigrate:
// app/Console/Commands/PhinxFresh.php
use Phinx\Migration\Manager;
public function handle()
{
$manager = new Manager($this->app['phinx']);
$manager->dropAll();
$manager->migrate();
}
Pre/Post-Migration Hooks
Use Phinx’s beforeMigrate/afterMigrate events in config/phinx.php:
'events' => [
'beforeMigrate' => [
'App\Phinx\Events\BeforeMigrateListener',
],
],
Custom Data Types
Extend Phinx’s data types for project-specific needs. Example: Add a json type handler:
// app/Phinx/JsonDataType.php
use Phinx\Db\Adapter\MysqlAdapter;
class JsonDataType extends \Phinx\Db\Adapter\MysqlAdapter\Column\Text
{
public function getSql()
{
return 'LONGTEXT';
}
}
Register it in config/phinx.php:
'data_types' => [
'json' => 'App\Phinx\JsonDataType',
],
Environment Variables
Use Laravel’s env() helper in config/phinx.php for dynamic configs:
'host' => env('PHINX_HOST', 'localhost'),
Multi-Database Support
Configure multiple environments in config/phinx.php:
'environments' => [
'production' => [...],
'staging' => [...],
],
Run migrations for a specific environment:
php artisan phinx:migrate --environment=staging
Migration Order Phinx sorts migrations by filename (timestamp prefix). Ensure consistent naming:
# Good: 20230101000000_create_users.php
# Bad: users_2023.php
How can I help you explore Laravel packages today?