bellangelo / phpstan-migration-rules
PHPStan rules for database migration tools (Phinx, Symfony, Laravel)
Package info
github.com/Bellangelo/phpstan-migration-rules
Type:phpstan-extension
pkg:composer/bellangelo/phpstan-migration-rules
Requires
- php: ^7.4 || ^8.0
Requires (Dev)
- illuminate/database: ^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0
- illuminate/support: ^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^9.5|^10.0
- rector/rector: ^2.3
- robmorgan/phinx: ^0.13
- squizlabs/php_codesniffer: ^4.0
- staabm/annotate-pull-request-from-checkstyle: ^1.8
README
A collection of PHPStan rules to enforce best practices and standards in database migration files for Phinx and Laravel / Illuminate.
Installation
composer require --dev bellangelo/phpstan-migration-rules
The 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.neon
Configuration
All 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: true
If you only use one framework, disable the other to avoid unnecessary processing:
parameters: migrationRules: phinx: enforceCollation: false forbidAfter: false forbidEnumColumn: false forbidRawSql: false forbidMultipleTableCreations: false
Rule catalog
Each rule below applies to migration files for both Phinx and Laravel, unless stated otherwise.
Rule: EnforceCollationRule
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 |
Rule: ForbidAfterRule
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') |
Rule: ForbidEnumColumnRule
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', [...]) |
Rule: ForbidRawSqlRule
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('...') |
Rule: ForbidMultipleTableCreationsRule
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 |