rfc:deprecated_interfaces

PHP RFC: #[\Deprecated] for interfaces

Introduction

The #[\Deprecated] attribute was introduced in PHP 8.4 (deprecated_attribute) and could be used to emit deprecation warnings when calling a function (or class method), or when accessing a class constant (or enum case). Starting in 8.5, deprecation warnings could also be emitted when accessing a global constant (attributes-on-constants) or when useing a trait (deprecated_traits). This RFC proposes to add support for emitting deprecation warnings when an interface is extended or implemented.

<?php
 
#[\Deprecated]
trait DemoInterface {}
 
class DemoClass implements DemoInterface {}
 
// Reports:
// Deprecated: Interface DemoInterface implemented by DemoClass is deprecated in %s on line %d
?>

Proposal

The #[\Deprecated] attribute will be allowed on interfaces. The existing target validation when applied to classes or enums is maintained.

When the interfaces that a class implements are loaded, any deprecated interfaces emit a deprecation message; these can be converted to an exception via a user error handler, and an uncaught exception will be treated the same as trying to implement a non-interface in terms of registration behavior. The same applies to interfaces extending other interfaces if those other interfaces are marked as deprecated.

Interfaces only emit deprecation warnings when directly extended or implemented, implementing child interfaces or extending implementing classes does not result in extra errors. See the comparison with existing tools below.

Examples

Simple example:

<?php
 
#[\Deprecated]
trait DemoInterface {}
 
class DemoClass implements DemoInterface {}
 
// Reports:
// Deprecated: Interface DemoInterface implemented by DemoClass is deprecated in %s on line %d
?>

With an exception:

<?php
 
function my_error_handler(int $errno, string $errstr, ?string $errfile = null, ?int $errline = null) {
	throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
}
 
set_error_handler('my_error_handler');
 
#[\Deprecated]
interface DemoInterface {}
 
class DemoClass implements DemoInterface {}
 
// Reports:
// Fatal error: Uncaught ErrorException: Interface DemoInterface implemented by DemoClass is deprecated in %s:%d
 
?>

Tool comparison

Given the following code:

<?php
 
/**
 * @deprecated
 */
interface BaseInterface {}
 
interface ChildInterface extends BaseInterface {}
 
class ImplementsBase implements BaseInterface {}
 
class ImplementsBoth implements BaseInterface, ChildInterface {}
 
class ImplementsChild implements ChildInterface {}
 
class ExtendsBaseImplementor extends ImplementsBase {}
 
?>

existing static analysis tools emit warnings for different sets of declarations. The behavior of the tools and the engine is as follows, where “yes” means a warning is emitted (with the engine behavior coming from using #[\Deprecated] rather than a comment):

Declaration Phan PHPStan Mago Psalm Engine
interface ChildInterface... yes yes yes no yes
class ImlementsBase... yes yes no yes yes
class ImlementsBoth... yes yes no yes yes
class ImlementsChild... no no no yes no
class ExtendsBaseImplementor... no no no yes no

PHPStan is as of the version on the playground (https://phpstan.org/try) on 2026.05.10, Psalm is as of commit 5c1c31c which was on its playground (https://psalm.dev/) on the same date. Phan is as of version 6.0.5, Mago is as of version 1.26.0.

Backward Incompatible Changes

None

Proposed PHP Version(s)

Next PHP (8.6)

RFC Impact

To the Ecosystem

IDEs and static analyzers will likely want to update to surface deprecation messages when an interface is extended or implemented without waiting for PHP to emit the errors.

To Existing Extensions

This lays the engine support for deprecating PHP-provided interfaces, but none are currently marked as deprecated.

To SAPIs

No impact other than deprecations being emitted when a deprecated interface is used.

Open Issues

Make sure there are no open issues when the vote starts!

Future Scope

Other places that #[\Deprecated] could eventually be supported include

  • extending a class
  • overriding a method
  • accessing a property

But the support for deprecating the use of a interface is pretty straightforward and there isn't room for future improvements within the context of deprecating interface.

Voting Choices

Add support for #[\Deprecated] on interfaces?
Real name Yes No
Final result: 0 0
This poll has been closed.

Patches and Tests

Implementation

After the RFC is implemented, this section should contain:

  1. the version(s) it was merged into
  2. a link to the git commit(s)
  3. a link to the PHP manual entry for the feature

References

Rejected Features

Keep this updated with features that were discussed on the mail lists.

Changelog

If there are major changes to the initial proposal, please include a short summary with a date or a link to the mailing list announcement here, as not everyone has access to the wikis' version history.

  • v0.1: created
rfc/deprecated_interfaces.txt · Last modified: by daniels