A collection of PHPStan rules to enforce best practices and standards in database migration files for Phinx and Laravel / Illuminate.
composer require --dev bellangelo/phpstan-migration-rulesThe extension will be automatically registered if you have phpstan/extension-installer installed. Otherwise, add it manually to your phpstan.neon:
includes:
- vendor/bellangelo/phpstan-migration-rules/extension.neonAll rules are enabled by default. You can customize behavior in your phpstan.neon:
parameters:
migrationRules:
requiredCollation: utf8mb4 # Default is utf8
phinx:
enforceCollation: true
forbidAfter: true
forbidEnumColumn: true
forbidRawSql: true
forbidMultipleTableCreations: true
laravel:
enforceCollation: true
forbidAfter: true
forbidEnumColumn: true
forbidRawSql: true
forbidMultipleTableCreations: trueIf you only use one framework, disable the other to avoid unnecessary processing:
parameters:
migrationRules:
phinx:
enforceCollation: false
forbidAfter: false
forbidEnumColumn: false
forbidRawSql: false
forbidMultipleTableCreations: falseEach rule below applies to migration files for both Phinx and Laravel, unless stated otherwise.
Enforces that table definitions explicitly define a collation.
Prevents relying on database defaults, which may differ between environments.
| Framework | How collation is detected |
|---|---|
| Phinx | table('name', ['collation' => '…']) |
| Laravel | $table->collation('…') or $table->collation = '…' inside the Blueprint callback |
Forbids column positioning via after.
May trigger full table rewrites or long locks, unsafe for large or production tables.
| Framework | Forbidden usage |
|---|---|
| Phinx | addColumn(..., ['after' => 'column']) |
| Laravel | $table->string('x')->after('y') |
Forbids the use of enum column types in migrations.
Modifying enum values requires a full
ALTER TABLE, which can cause long locks on large tables. Use a string column with application-level validation instead.
| Framework | Forbidden usage |
|---|---|
| Phinx | addColumn('col', 'enum', ['values' => [...]]) |
| Laravel | $table->enum('col', [...]) |
Forbids raw SQL execution inside migrations.
Raw SQL bypasses the schema builder, making migrations harder to review, less portable, and prone to errors.
| Framework | Forbidden usage |
|---|---|
| Phinx | $this->execute('...'), $this->query('...') |
| Laravel | DB::statement('...'), DB::unprepared('...') |
Ensures each migration creates at most one table.
Improves rollback safety and migration clarity.
| Framework | What counts as a table creation |
|---|---|
| Phinx | Multiple calls to create() on table instances |
| Laravel | Multiple Schema::create() calls in the same migration |