Skip to content

Prevent ForbidMethodDeclaration sniff aborting on deprecated traits#36

Merged
alies-dev merged 1 commit into
mainfrom
fix/forbid-method-declaration-php85-deprecated-trait
Jun 23, 2026
Merged

Prevent ForbidMethodDeclaration sniff aborting on deprecated traits#36
alies-dev merged 1 commit into
mainfrom
fix/forbid-method-declaration-php85-deprecated-trait

Conversation

@alies-dev

Copy link
Copy Markdown
Member

Problem

On PHP 8.5 the #[\Deprecated] attribute is now honoured on traits. Loading a class that uses a deprecated trait emits a runtime deprecation (e.g. Trait X used by Y is deprecated, ...). In PHP 8.4 the attribute on a trait was a no-op, so nothing fired.

ForbidMethodDeclarationSniff::process() resolves the analysed class via is_subclass_of() / method_exists(), both of which autoload it. That autoload materialises the deprecated-trait usage, the deprecation fires, PHP_CodeSniffer turns it into an exception, and the whole file check aborts:

error - An error occurred during processing; checking has been aborted.
The error message was: Trait App\Http\Requests\RequestInviteAware used by
App\Http\Requests\InviteAwareRequest is deprecated, Please inject services
instead. ... The error originated in the
IxDFCodingStandard.Classes.ForbidMethodDeclaration sniff on line 34.
(Internal.Exception)

Any class under analysis that uses a #[\Deprecated] trait (or extends a deprecated class) hits this.

Fix

The deprecation is a side effect of the analysed code, not an issue with the sniff, so the sniff must not let it abort the run. The two reflection calls are moved into a private helper that silences E_DEPRECATED / E_USER_DEPRECATED (via a scoped set_error_handler restored in a finally) while resolving the class. Behaviour is otherwise identical.

Tests

Added ForbidMethodDeclarationSniffTest with fixtures where the analysed class uses a #[\Deprecated] trait. The regression test installs its own deprecation-capturing handler around the run and asserts none leak, so it fails on the unpatched sniff (with the exact PHP 8.5 trait-deprecation message) and passes after the fix. Verified against the real IxDF-web codebase: a full phpcs scan goes from 10 Internal.Exception failures to a clean run.

@alies-dev alies-dev self-assigned this Jun 23, 2026
@alies-dev alies-dev force-pushed the fix/forbid-method-declaration-php85-deprecated-trait branch from 9c652b9 to 64fbeee Compare June 23, 2026 10:53
is_subclass_of()/method_exists() autoload the analysed class. On PHP 8.5
the #[\Deprecated] attribute is honoured on traits, so loading a class that
uses a deprecated trait emits a deprecation ("Trait X used by Y is
deprecated"). PHP_CodeSniffer turns that into an exception, aborting the
whole file check with an Internal.Exception. Silence deprecations around the
reflection calls (they are a side effect of the analysed code, not of the
sniff) and add a regression test that fails on the leaked deprecation.
@alies-dev alies-dev force-pushed the fix/forbid-method-declaration-php85-deprecated-trait branch from 64fbeee to 4d06311 Compare June 23, 2026 10:55
@alies-dev alies-dev merged commit 1aba650 into main Jun 23, 2026
7 checks passed
@alies-dev alies-dev deleted the fix/forbid-method-declaration-php85-deprecated-trait branch June 23, 2026 10:57
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.

1 participant