PHPStan rules shared across KnpLabs organization projects.
- PHP 8.2 or higher
- PHPStan ^2.0
composer require --dev knplabs/phpstan-rules phpstan/extension-installerThe extension is loaded automatically.
Warning
The package is not yet available on Packagist. It will be release with the v1.0.0 once internal tests has been done.
During testing phase, install via VCS repository pointing at dev-main. Add repository to your composer.json:
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/KnpLabs/phpstan-rules"
}
]
}Then require dev-main version:
composer require --dev knplabs/phpstan-rules:dev-mainIf you don't use phpstan/extension-installer, include the extension in your phpstan.neon:
includes:
- vendor/knplabs/phpstan-rules/extension.neonEnforces the PSR-20 recommendation to avoid instantiating DateTime or DateTimeImmutable with the current time directly. This makes code that depends on the current time testable and respects the clock abstraction.
Triggers on:
$a = new DateTime();
$b = new DateTime('now');
$c = new DateTimeImmutable();
$d = new DateTimeImmutable('now');Does not trigger on (explicit non-"now" timestamps are fine):
$a = new DateTime('2023-01-01');
$b = new DateTimeImmutable('yesterday');Recommended fix: inject Psr\Clock\ClockInterface and call $clock->now():
use Psr\Clock\ClockInterface;
final class MyService
{
public function __construct(private readonly ClockInterface $clock) {}
public function doSomething(): void
{
$now = $this->clock->now();
// ...
}
}Enforces the PSR-20 recommendation to avoid using time() or date() directly. This makes code that depends on the current time testable and respects the clock abstraction.
Triggers on:
$a = time();
$b = date('Y-m-d');
$c = date('Y-m-d', time());
$d = date('Y-m-d', 'now');Does not trigger on (explicit non-"now" timestamps are fine):
$a = date('Y-m-d', 1672531200);
$b = date('Y-m-d', $someTimestamp);Recommended fix: inject Psr\Clock\ClockInterface and call $clock->now():
use Psr\Clock\ClockInterface;
final class MyService
{
public function __construct(private readonly ClockInterface $clock) {}
public function doSomething(): void
{
$now = $this->clock->now();
// ...
}
}See CONTRIBUTING.md for the human contributor guide.
If you are working with an AI agent (Claude Code), refer to CLAUDE.md — it contains the AI-facing instructions for this repository.
MIT — see LICENSE.