Fix: Extractor not detecting class-level attribute changes#139
Fix: Extractor not detecting class-level attribute changes#139ivanvasechko wants to merge 1 commit intophpstan:mainfrom ivanvasechko:fix/detect-class-attribute-changes
Conversation
|
That looks correct to me: https://github.com/phpstan/php-8-stubs/actions/runs/19666260699/job/56323867068?pr=139 @ondrejmirtes, thoughts on this? |
|
PHPStan itself is not reading these attributes, it uses phpstorm-stubs for that. In this repo I'm generally interested only in fixing bugs that manifesr in PHPStan. Are you using this repo for some other purpose? |
Not really, just facing the error with PHP 8.5 and the latest PHP Stan. php -v
PHP 8.5.0 (cli) (built: Nov 20 2025 19:48:32) (NTS)
Copyright (c) The PHP Group
Built by https://github.com/docker-library/php
Zend Engine v4.5.0, Copyright (c) Zend Technologies
with Zend OPcache v8.5.0, Copyright (c), by Zend Technologiescomposer show phpstan/phpstan
name : phpstan/phpstan
descrip. : PHPStan - PHP Static Analysis Tool
keywords : dev, static analysis
versions : * 2.1.32
released : 2025-11-11, last week
type : library
license : MIT License (MIT) (OSI approved) https://spdx.org/licenses/MIT.html#licenseText
homepage :
source : []
dist : [zip] https://api.github.com/repos/phpstan/phpstan/zipball/e126cad1e30a99b137b8ed75a85a676450ebb227 e126cad1e30a99b137b8ed75a85a676450ebb227
path : /var/www/html/vendor/phpstan/phpstan
names : phpstan/phpstanTrying to set Note: Using configuration file /var/www/html/phpstan.neon.
4/4 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
------ ---------------------------------------------------------------------------------------------------------------------
Line Models/User.php
------ ---------------------------------------------------------------------------------------------------------------------
22 Property App\Models\User::$fillable overrides property Illuminate\Database\Eloquent\Model::$fillable but is missing
the #[\Override] attribute.
🪪 property.missingOverride
33 Property App\Models\User::$hidden overrides property Illuminate\Database\Eloquent\Model::$hidden but is missing the
#[\Override] attribute.
🪪 property.missingOverride
------ ---------------------------------------------------------------------------------------------------------------------
[ERROR] Found 2 errors If adding /**
* The attributes that are mass assignable.
*
* @var list<string>
*/
#[\Override]
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* @var list<string>
*/
#[\Override]
protected $hidden = [
'password',
'remember_token',
];Getting a new error: root@31ab76a196d5:/var/www/html# vendor/bin/phpstan
Note: Using configuration file /var/www/html/phpstan.neon.
4/4 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
------ -------------------------------------------------------------
Line Models/User.php
------ -------------------------------------------------------------
22 Attribute class Override does not have the property target.
🪪 attribute.target
34 Attribute class Override does not have the property target.
🪪 attribute.target
------ -------------------------------------------------------------
[ERROR] Found 2 errors So my assumption was that there is something wrong with stubs. If it's not what used by PHPStan, feel free to close the PR, sorry for the confusion. |
|
Please open an issue in phpstan/phpstan. |

Problem
The extractor was not detecting changes to class-level attributes when updating stubs between PHP versions. It only compared methods and constants within classes, but never checked if the class declaration's own attributes (like
#[Attribute(...)]) had changed.This caused several attribute classes to have outdated stubs in PHP 8.5:
Attribute::TARGET_PROPERTYTARGET_CONSTANT|TARGET_CLASSandreadonlyproperties#[Attribute(Attribute::TARGET_METHOD)]declaration#[Attribute(Attribute::TARGET_CLASS)]and$flagspropertyRoot Cause
In
compareStatementsInNamespace()(~line 506), after comparing class members (methods and constants), the code would simply return the old class statement without comparing the class'sattrGroups:Solution
Added new method
hasAttributeChanges()that compares class-level attributes between old and new class declarations#[Since]and#[Until]meta-attributesprettyPrintExpr()trueif any difference is detectedModified
compareStatementsInNamespace()to check for class-level attribute changes before returningstmtDiff()to generate both#[Until]and#[Since]versionsTesting
Ran the extractor with PHP 8.5 source (
./extractor/extract.php --update -- 8.4 8.5) and verified:Impact
This fix ensures PHPStan can correctly:
#[\Override]on properties in PHP 8.5+#[\Deprecated]References