Skip to content

KnpLabs/phpstan-rules

Repository files navigation

knplabs/phpstan-rules

CI PHP Packagist License

PHPStan rules shared across KnpLabs organization projects.

Requirements

  • PHP 8.2 or higher
  • PHPStan ^2.0

Installation

Using phpstan/extension-installer (recommended)

composer require --dev knplabs/phpstan-rules phpstan/extension-installer

The extension is loaded automatically.

Manual configuration

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-main

If you don't use phpstan/extension-installer, include the extension in your phpstan.neon:

includes:
    - vendor/knplabs/phpstan-rules/extension.neon

Rules

clock.disallowDateTimeNow — PSR-20 Clock Abstraction

Enforces 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();
        // ...
    }
}

clock.disallowTimeFunctions — PSR-20 Clock Abstraction (functions)

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();
        // ...
    }
}

Contributing

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.

License

MIT — see LICENSE.

About

No description, website, or topics provided.

Resources

License

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors