Repository navigation
Load genuinely-new native classes on every PHP version, tagged with @since - #12008
Merged
Merged
Conversation
This was referenced Sep 28, 2026
danog
force-pushed
the
versioned-native-class-stubs
branch
from
September 28, 2026 12:12
4c697d0 to
41cc692
Compare
…SInCE Classes introduced by PHP 8.0-8.5 (Stringable, ReflectionAttribute, ReflectionUnionType, UnhandledMatchError, the Curl handles, the enum interfaces and reflection classes, ReflectionIntersectionType, the resource->object classes, SensitiveParameterValue, NoDiscard, CurlSharePersistentHandle) move to the always-loaded stubs/PhpVersionedClasses.phpstub with an `@since` tag. Analysis therefore knows their shape on every version, and a use below that version is reported as undefined unless polyfilled. Reopens of pre-existing classes stay in the version-gated Php8X.phpstub files, as do the refined signatures of pre-existing functions (Php80Functions: get_headers, pack; Php82Functions: str_split) and the #[Attribute] meta-class (Php80Attribute), so their stricter typing is not applied on older versions. Php85.phpstub is gone. PhpVersionedClasses.phpstub is parsed with the grammar of the analysed version, so its readonly properties are declared with `@readonly` instead of the 8.1 keyword, which would otherwise make older parsers drop them. Co-Authored-By: Claude Opus 5.5
danog
force-pushed
the
versioned-native-class-stubs
branch
from
September 28, 2026 12:25
41cc692 to
aabe109
Compare
On a PHP 8.5 runtime this only holds with the always-loaded @SInCE stub. Co-Authored-By: Claude Opus 5.5
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part 2 of the split of #11974; #12006 and #12007 are merged.
With the always-loaded
@since 8.5stub,#[\NoDiscard]is reported as undefined at 8.0 on every runtime PHP version, including PHP 8.5, where the class comes from reflection. The runtime-dependent NoDiscardTest case was dropped from 6.x, so that coverage returns here asattributeBelowItsVersion.Summary
Classes introduced by PHP 8.0–8.5 used to live in the version-gated
Php80/Php81/Php82/Php85stubs. Below their version, analysis knew nothing about them. They now live in the always-loadedstubs/PhpVersionedClasses.phpstub, each with an@sincetag. Analysis knows their shape on every version, and with #12006 a use below that version is reported as undefined unless polyfilled.The moved classes:
StringableReflectionAttribute,ReflectionUnionType,ReflectionIntersectionTypeReflectionEnum,ReflectionEnumUnitCase,ReflectionEnumBackedCaseUnhandledMatchErrorCurlHandle,CurlMultiHandle,CurlShareHandle,CurlSharePersistentHandleUnitEnum,BackedEnumFTP\Connection,IMAP\Connection,LDAP\*,PgSql\*,PSpell\*SensitiveParameterValueNoDiscardWhat stays version-gated
Php8X.phpstub.get_headersandpackinPhp80Functions,str_splitinPhp82Functions) and the#[Attribute]meta-class (Php80Attribute) are split out and stay gated, so their stricter typing does not apply on older versions.Php85.phpstubis removed.PhpVersionedClasses.phpstubis also preloaded, replacing the oldPhp85.phpstubpreload.Parsing note
The always-loaded stub is parsed with the grammar of the analysed version, and
readonlyis only a keyword from 8.1 on. The stub therefore uses@readonly(and@psalm-immutableclasses) instead of the keyword. Otherwise older parsers drop e.g.UnitEnum::$name, and the property comes out mixed.Tests
NativeSymbolAvailabilityTestgains cases for:StringableUnitEnum::$name) being kept below 8.1A scratch project with
symfony/polyfill-php80installed, analysed at 7.4, reports nothing forStringableorUnhandledMatchError.🤖 Generated with Claude Code