nijidigital / phpstan-rules
custom phpstan rules created by dsf-niji
Installs: 308
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 1
Open Issues: 1
Type:phpstan-extension
pkg:composer/nijidigital/phpstan-rules
Requires
- php: >=8.2
- phpstan/phpstan: ^2.0
- psr/clock: ^1.0
Requires (Dev)
- doctrine/migrations: ^3.9
- friendsofphp/php-cs-fixer: ^3.86
- phpstan/phpstan-deprecation-rules: ^2
- phpunit/phpunit: ^11.5
- rector/rector: ^2.1
README
Custom PhpStan rules made with ❤️ by Niji.
Installation
To use this extension, require it in Composer:
composer require --dev nijidigital/phpstan-rules
If you also install phpstan/extension-installer then you're all set!
Manual installation
If you don't want to use phpstan/extension-installer
, include extension.neon in your project's PHPStan config:
includes:
- vendor/nijidigital/phpstan-rules/extension.neon
Existing rules
NoRelativeDatetime
Prevents usage of relative date/time strings and empty constructors in DateTime
and DateTimeImmutable
to ensure consistent and testable date handling.
Examples
❌ Invalid:
// Empty constructors $now = new \DateTime(); $now = new \DateTimeImmutable(); // Relative date strings $yesterday = new \DateTime('yesterday'); $nextMonth = new \DateTime('next month'); $twoHoursLater = new \DateTimeImmutable('+2 hours');
✅ Valid alternatives:
// Use absolute dates for fixed dates $fixedDate = new \DateTime('2025-07-01 13:12:11'); // Use ClockInterface for current time and modifications function doSomethingWithTime(ClockInterface $clock) { $now = $clock->now(); $yesterday = $clock->now()->modify('-1 day'); $nextMonth = $clock->now()->modify('+1 month'); // (...) }
DoctrineMigrationsSafeMigration
Detects potentially unsafe database migration operations that could break backward compatibility in Doctrine migrations. Operations can be marked as safe using PHPStan's standard @phpstan-ignore
comment.
Examples
❌ Invalid:
class UnsafeMigration extends AbstractMigration { public function up(Schema $schema): void { // These operations may not be backward compatible $this->addSql('DROP TABLE user'); $this->addSql('ALTER TABLE user CHANGE name email VARCHAR(255)'); $this->addSql('ALTER TABLE user DROP COLUMN name'); $this->addSql('DROP DATABASE test'); $this->addSql('TRUNCATE TABLE user'); } }
✅ Valid alternatives:
class SafeMigration extends AbstractMigration { public function up(Schema $schema): void { // Safe operations (no ignore comment needed) $this->addSql('ALTER TABLE user ADD COLUMN email VARCHAR(255)'); $this->addSql('CREATE INDEX idx_user_email ON user (email)'); $this->addSql('INSERT INTO user (name) VALUES (\'John\')'); // Unsafe operations marked as intentionally safe /* @phpstan-ignore doctrineMigrations.unsafeMigration */ $this->addSql('DROP TABLE legacy_user'); /* @phpstan-ignore doctrineMigrations.unsafeMigration */ $this->addSql('ALTER TABLE user CHANGE name full_name VARCHAR(255)'); } }
Configuration
You can customize the behavior of this rule using the parameters
section in your phpstan.neon
configuration:
parameters: niji: doctrineMigrations: safeMigration: # Custom list of blacklisted SQL patterns with their error messages blacklistedQueries: '/DROP\s+TABLE\s+/im': 'Dropping tables is not allowed' '/ALTER\s+TABLE\s+.+\s+DROP\s+COLUMN/im': 'Dropping columns breaks backward compatibility'
Available options:
blacklistedQueries
: Array of regex patterns (as keys) with their corresponding error messages (as values). If not specified, uses default patterns for common unsafe operations.
DoctrineMigrationsDescription
Ensures that Doctrine migration classes provide meaningful descriptions by validating the return value of the getDescription()
method against a configurable pattern.
Examples
❌ Invalid:
class MyMigration extends AbstractMigration { public function getDescription(): string { return ''; // Empty description } public function up(Schema $schema): void { $this->addSql('ALTER TABLE user ADD COLUMN email VARCHAR(255)'); } }
✅ Valid:
class MyMigration extends AbstractMigration { public function getDescription(): string { return 'Add email column to user table'; } public function up(Schema $schema): void { $this->addSql('ALTER TABLE user ADD COLUMN email VARCHAR(255)'); } }
Configuration
By default, the rule accepts any non-empty string. You can customize the accepted pattern using the parameters
section in your phpstan.neon
configuration:
parameters: niji: doctrineMigrations: description: # Custom regex pattern for migration descriptions acceptedPattern: '/^[A-Z][a-z0-9\s]+\.?$/'
Available options:
acceptedPattern
: A regex pattern that migration descriptions must match. Defaults to/.+/im
(any non-empty string).
Troubleshooting
PhpStorm doesn't provide any autocomplete on PhpStan classes
1. Copy the file `vendor/phpstan/phpstan/phpstan.phar` to a local folder of your choice, ie : `C:\php_include_path`.
2. In PhpStorm, go to File | Settings | PHP and add your newly created folder to the include path.