Skip to content

Skip "static::" const fetch overridden by child class in ForbiddenStaticClassConstFetchRule - #376

Merged
TomasVotruba merged 1 commit into
mainfrom
skip-static-const-fetch-overridden-by-child
Oct 16, 2026
Merged

TomasVotruba merged 1 commit into
mainfrom
skip-static-const-fetch-overridden-by-child

Conversation

@TomasVotruba

@TomasVotruba TomasVotruba commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

Closes #352.

ForbiddenStaticClassConstFetchRule flagged every static::SOME_CONST fetch. But late static binding is meaningful when a child class overrides the constant - the value genuinely changes per class, which is the intended use.

Rule now uses PHPStan collectors:

  • StaticClassConstFetchCollector - records each static::CONST fetch (skips static::class magic and abstract classes)
  • ClassConstantDeclarationCollector - records each class, its parent and the constants it declares

The rule reports a fetch only when no child class overrides that constant; when a child redeclares it, the fetch is kept. static::class is always allowed.

How it works

Reported - no child overrides the constant, so static:: behaves like self:::

class SomeClass
{
    protected const SOME_CONST = 'value';

    public function run()
    {
        return static::SOME_CONST; // error
    }
}

Skipped - a child class overrides the constant, so late static binding changes the value on purpose:

class ParentClass
{
    protected const SOME_CONST = 'parent';

    public function run()
    {
        return static::SOME_CONST; // no error
    }
}

class ChildClass extends ParentClass
{
    protected const SOME_CONST = 'child';
}

Skipped - static::class is late static binding magic, not an overridable constant:

class SomeClass
{
    public function run()
    {
        return static::class; // no error
    }
}

Builds on the failing fixture from #373.

Fixtures cover: child overrides const (skip), child without override (report), static::class (skip).

@TomasVotruba
TomasVotruba merged commit 3e1ea6b into main Oct 16, 2026
9 checks passed
@TomasVotruba
TomasVotruba deleted the skip-static-const-fetch-overridden-by-child branch October 16, 2026 10:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Skip "static::class" in "ForbiddenStaticClassConstFetchRule"

1 participant