nowo-tech / phpstan-frankenphp
PHPStan rules that help you migrate from PHP-FPM to FrankenPHP classic, then to worker mode. Rules are split by level with demos for every case.
Package info
github.com/nowo-tech/PhpStanFrankenPhp
Type:phpstan-extension
pkg:composer/nowo-tech/phpstan-frankenphp
Fund package maintenance!
Requires
- php: >=8.1 <8.6
- phpstan/phpstan: ^2.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- phpstan/phpstan-phpunit: ^2.0
- phpstan/phpstan-strict-rules: ^2.0
- phpunit/phpunit: ^10.0 || ^11.0
- rector/rector: ^2.0
- symfony/http-foundation: ^6.4 || ^7.0 || ^8.0
- symfony/process: ^6.4 || ^7.0 || ^8.0
- symfony/service-contracts: ^2.5 || ^3.0
This package is auto-updated.
Last update: 2026-08-03 12:47:05 UTC
README
⭐ Found this useful? Install from Packagist and star the repository on GitHub.
PHPStan rules that help you migrate from PHP-FPM to FrankenPHP classic, then to worker mode. Rules are split by level, documented with justification, and shipped with demos for every case.
This bundle is FrankenPHP worker mode friendly.
Installation
composer require --dev nowo-tech/phpstan-frankenphp
Enable levels intentionally (rules are not auto-enabled by extension.neon):
# phpstan.neon includes: - vendor/nowo-tech/phpstan-frankenphp/ruleset-classic.neon # - vendor/nowo-tech/phpstan-frankenphp/ruleset-worker.neon # - vendor/nowo-tech/phpstan-frankenphp/ruleset-worker-strict.neon # - vendor/nowo-tech/phpstan-frankenphp/ruleset-hardening.neon
See docs/CONFIGURATION.md and docs/RULES.md.
Quick example
// Flagged by classic rules: exit(1); fastcgi_finish_request(); $process->setTimeout(null); // Flagged by worker rules: private static array $cache = []; static $count = 0; $_ENV['TOKEN'] = $requestToken; // Flagged by hardening rules: set_time_limit(0); sleep(5); pcntl_fork();
Why
FrankenPHP classic already changes process lifetime compared to FPM (exit/die, FastCGI APIs, unbounded I/O). Worker mode keeps the app in memory: statics, globals, and $_ENV mutations survive across requests. This extension surfaces those sites in CI so you can fix them in order.
Fixes stay FPM-compatible. The suggested remediations are portable patterns (no FrankenPHP-only APIs). They make the codebase more solid on FPM and safe for worker mode. Details: docs/MIGRATION.md — FPM compatibility.
Levels (application order)
| Order | Ruleset | When |
|---|---|---|
| 1 | ruleset-classic.neon |
Moving FPM → FrankenPHP classic |
| 2 | ruleset-worker.neon |
Enabling FrankenPHP worker |
| 2b | ruleset-worker-strict.neon |
Optional: also flag $_GET/$_POST/… |
| 3 | ruleset-hardening.neon |
Production hardening (timeouts, fork, sleep) |
Full catalog: docs/RULES.md.
Demos
Symfony 8 + FrankenPHP
make -C demo/symfony8 up # Demo started at: http://localhost:8090 make -C demo/symfony8 phpstan-classic # expect findings on AntiPattern/
FrankenPHP worker mode: supported (tested in the Symfony 8 demo with FRANKENPHP_MODE=worker by default). See docs/DEMO-FRANKENPHP.md.
Fixture demos
Intentional violations and clean counterparts under demo/:
composer demo-classic # expect findings composer demo-worker composer demo-hardening composer demo-classic-good # must be clean
Development
make setup-hooks make ensure-up make qa make demo-all
Documentation
- Installation
- Configuration
- Usage
- Contributing
- Code of Conduct
- Changelog
- Upgrading
- Release
- Security
- Engram
- Spec-driven development
- GitHub Spec Kit
Additional documentation
- Rule catalog
- Migration guide (FPM → classic → worker)
- FrankenPHP demos
- Demos
- GitHub Actions CI requirements
- Branching strategy
Tests and coverage
make test
make test-coverage
- PHPUnit suites:
tests/Rule(RuleTestCase per rule),tests/Unit(helpers / edge branches),tests/Integration(neon wiring). - Line coverage on
src/: 100% (enforced viacomposer coverage-check/ CI on PHP 8.2).
License
MIT — see LICENSE.
