← All results

PHP 8.5 lets #[\Override] mark a property that replaces a parent property

Group: Properties · Category: language · File: properties_override_attribute.php

A matching parent property is silent. A property with no parent counterpart is a fatal (has #[\Override] attribute, but no matching parent property exists). Class constants are not a valid target (allowed targets: method, property). Method #[\Override] is the control: that target is older and must stay accepted. Source: vimeo/psalm#11891 (6.19.0). References: - https://wiki.php.net/rfc/marking_overriden_methods - psalm#11891

Analyzer results

AnalyzerVersionResultDiagnostics
phan 6.0.10Phan 6.0.10 php-ast version 1.1.3 PHP version used to run Phan: 8.5.11 Pass
properties_override_attribute.php:51: Saw an @override annotation for property \Conformance\Tests\PropertiesOverrideAttribute\MissingParentProperty::other, but could not find an overridden property [PhanCommentOverrideOnNonOverrideProperty]
properties_override_attribute.php:56: Saw use of attribute \Override declared at internal:0 which supports being declared on \Attribute::TARGET_PROPERTY|\Attribute::TARGET_METHOD but it was declared on public const FLAG which requires an attribute declared to support \Attribute::TARGET_CLASS_CONSTANT [PhanAttributeWrongTarget]
phpstan 2.3.1PHPStan - PHP Static Analysis Tool 2.3.1 Pass reported Lv.0+
properties_override_attribute.php:51: Property Conformance\Tests\PropertiesOverrideAttribute\MissingParentProperty::$other has #[\Override] attribute but does not override any property. [reported-from-level=0]
With strict-rules
properties_override_attribute.php:51: Property Conformance\Tests\PropertiesOverrideAttribute\MissingParentProperty::$other has #[\Override] attribute but does not override any property.
psalm 6.20.0Psalm 6.20.0@804f03c0c183d149fcd4b8c7c0c9b3fbf836d34c
next: 7.0.0-rc2
Fail (pzoom≠)
pzoom (Psalm port)
properties_override_attribute.php:56: Attribute Override cannot be used on a class constant [InvalidAttribute]
Expectation diff
Lines 50, 51: Expected error (tag missing)
mago 1.57.0mago 1.57.0 Fail
properties_override_attribute.php:56: Attribute `Override` cannot be used on a class constant. [invalid-attribute-target]
Expectation diff
Lines 50, 51: Expected error (tag missing)
mir 0.87.0mir 0.87.0 Fail
properties_override_attribute.php:56: InvalidAttribute: Attribute Override cannot be used on this target [MIR1600]
Expectation diff
Lines 50, 51: Expected error (tag missing)
phpantom 0.11.1phpantom_lsp 0.11.1 Fail

No diagnostics reported.

Expectation diff
Lines 50, 51: Expected error (tag missing)
intelephense 1.18.5intelephense 1.18.5 Fail
properties_override_attribute.php:56: Attribute "Override" has invalid target. [P1087]
Expectation diff
Lines 50, 51: Expected error (tag missing)
phpactor 2026.10.07.0Phpactor 2026.10.07.0 Fail

No diagnostics reported.

Expectation diff
Lines 50, 51: Expected error (tag missing)
phpy 1.0.19409phpy 1.0.19409 Fail

No diagnostics reported.

Expectation diff
Lines 50, 51: Expected error (tag missing)
qodana 262.10968.76PhpStorm 262.10968.76 Fail

No diagnostics reported.

Expectation diff
Lines 50, 51: Expected error (tag missing)
noverify 0.5.5NoVerify, version 0.5.5: built on: 2025.04.22 14:36:46 OS: r-kuchinskas arm64 Commit: 4774b82f8adc53fbef38f95e97af4b953b4d1529 Fail

No diagnostics reported.

Expectation diff
Lines 50, 51: Expected error (tag missing)
steins 0.1.8steins 0.1.8 (2026-09-21 revision 76306a9) Fail

No diagnostics reported.

Expectation diff
Lines 50, 51: Expected error (tag missing)
phpstan-strict 2.3.1PHPStan - PHP Static Analysis Tool 2.3.1 Pass
properties_override_attribute.php:51: Property Conformance\Tests\PropertiesOverrideAttribute\MissingParentProperty::$other has #[\Override] attribute but does not override any property.
psalm-next 7.0.0-rc2Psalm 7.0.0-rc2@20339e3fe5b8d03bcd8061030eb2a83ad50e5783 Fail

No diagnostics reported.

Expectation diff
Lines 50, 51: Expected error (tag missing)

Source

<?php

declare(strict_types=1);

namespace Conformance\Tests\PropertiesOverrideAttribute;

/**
 * PHP 8.5 lets `#[\Override]` mark a property that replaces a parent property.
 *
 * A matching parent property is silent. A property with no parent counterpart
 * is a fatal (`has #[\Override] attribute, but no matching parent property
 * exists`). Class constants are not a valid target (`allowed targets: method,
 * property`). Method `#[\Override]` is the control: that target is older and
 * must stay accepted.
 *
 * Source: vimeo/psalm#11891 (6.19.0).
 *
 * References:
 * - https://wiki.php.net/rfc/marking_overriden_methods
 * - https://github.com/vimeo/psalm/pull/11891
 */

class ParentBox
{
    public int $value = 1;

    public function label(): string
    {
        return 'parent';
    }
}

class MatchingProperty extends ParentBox
{
    #[\Override] // E?[noise]: tools that still reject Override on properties blame the attribute
    public int $value = 2; // V: the parent declares the same property
}

class MatchingMethod extends ParentBox
{
    #[\Override]
    public function label(): string // V: method Override is not what this file is adding
    {
        return 'child';
    }
}

class MissingParentProperty extends ParentBox
{
    #[\Override] // E[missing]
    public int $other = 3; // E[missing]: no parent property named $other
}

class OverrideOnConstant extends ParentBox
{
    #[\Override] // E?[const]
    public const int FLAG = 1; // E?[const]: Override cannot target a class constant
}