rfc:deprecated_traits

PHP RFC: #[\Deprecated] for traits

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). This RFC proposes to add support for emitting deprecation warnings when a trait gets used.

<?php
 
#[\Deprecated]
trait DemoTrait {}
 
class DemoClass {
	use DemoTrait;
}
 
// Reports:
// Deprecated: Trait DemoTrait used by DemoClass is deprecated in %s on line %d
?>

Proposal

The #[\Deprecated] attribute will be allowed on traits. Since Attribute::TARGET_CLASS includes traits as well as classes, interfaces, and enums, a validator will be used to ensure that when applied to a “class” (zend_class_entry), it must correspond to a trait.

When the traits that a class uses are loaded, any deprecated traits 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 use a non-trait as a trait in terms of registration behavior.

Traits only emit deprecation warnings when directly used, the children of a class using a deprecated trait do not emit any extra errors unless they also use the trait directly.

Examples

Simple example:

<?php
 
#[\Deprecated]
trait DemoTrait {}
 
class DemoClass {
	use DemoTrait;
}
 
// Reports:
// Deprecated: Trait DemoTrait used 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]
trait DemoTrait {}
 
class DemoClass {
	use DemoTrait;
}
 
// Reports:
// Fatal error: Uncaught ErrorException: Trait DemoTrait used by DemoClass is deprecated in %s:%d
 
?>

Backward Incompatible Changes

None

Proposed PHP Version(s)

Next PHP (8.5)

RFC Impact

To the Ecosystem

IDEs and static analyzers will likely want to update to surface deprecation messages when a trait is used without waiting for PHP to emit the errors.

To Existing Extensions

PHP core and the bundled extensions do not provide any traits, so there is no impact there.

To SAPIs

No impact other than deprecations being emitted when a deprecated trait 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
  • implementing an interface
  • overriding a method
  • accessing a property

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

Voting Choices

Add support for #[\Deprecated] on traits?
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.

rfc/deprecated_traits.txt · Last modified: by daniels