Req #75060 [Sus->Csd]: Allow traits to have constants to support emerging use cases

From: Date: Wed, 14 Dec 2022 14:07:56 +0000
Subject: Req #75060 [Sus->Csd]: Allow traits to have constants to support emerging use cases
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-243142@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=75060&edit=1 ID: 75060 Updated by: cmb@php.net Reported by: jocrutrisi at ibsats dot com Summary: Allow traits to have constants to support emerging use cases -Status: Suspended +Status: Closed Type: Feature/Change Request Package: Class/Object related Operating System: All PHP Version: 7.2.0beta2 -Assigned To: +Assigned To: cmb Block user comment: N Private report: N New Comment: Constants in traits are available as of PHP 8.2.0[1]. [1] <https://wiki.php.net/rfc/constants_in_traits> Previous Comments: ------------------------------------------------------------------------ [2020-06-21 01:10:59] jake at qzdesign dot co dot uk Can this please be considered for inclusion in PHP 8.0? There is still time. The specific limitation seems to be unfounded and impedes good OO design (where multiple inheritance is not available, by language design, and traits provide and enforce a clearer design pattern). The following comment on [Stack Overflow](https://stackoverflow.com/questions/24357985/php-traits-defining-generic-constants#comment-49583022) has received 73 upvotes, the most I've ever seen for a SO comment: > So interfaces can have constants...but traits can't? PHP gets weirder and weirder. Clearly there is strong demand for this issue to be addressed. ------------------------------------------------------------------------ [2017-08-11 11:17:16] cmb@php.net Related To: Bug #70986 ------------------------------------------------------------------------ [2017-08-11 11:16:21] cmb@php.net Thank you for your interest in PHP and for submitting a feature request. Please be aware that due to the magnitude of change this request requires, it would be necessary to discuss it on PHP Internals list (internals@lists.php.net) as an RFC. Please read the guide about creating RFCs here: <https://wiki.php.net/rfc/howto>. If you haven't had experience with writing RFCs before, it is advised to seek guidance on the Internals list (<http://php.net/mailing-lists.php>) and/or solicit help from one of the experienced developers. Please do not consider this comment as a negative view on the merits of your proposal – every proposal which requires changes of certain magnitude, even the very successful and widely supported ones, must be done through the RFC process. This helps make the process predictable, transparent and accessible to all developers. ------------------------------------------------------------------------ [2017-08-10 18:43:03] jocrutrisi at ibsats dot com Description: ------------ I want to preface this with a disclaimer that I'm aware that "traits" in other languages are even more conservative than PHP is - they don't allow properties, while PHP does. But what we have in PHP is still a useful variation of traits, called "mixins". A mixin is a slice of a class that has properties, methods, constants and so it can contain everything needed for implementing a standalone "slice" of functionality for reuse in classes. But while PHP allows properties, it doesn't allow constants in traits. The reasons for this decision are unclear. After traits were introduced in PHP 5.4, we've seen the roles, purpose and use scenarios for constants increasingly grow over time: 1. PHP 5.6 allowed for array constants, which made constants handy for constant look-up maps etc. 2. PHP 7.0 introduced opcache as a built-in feature, and it places constants in shared memory, which makes them especially performant for big look-up maps. 3. PHP 7.1 introduced private/protected constants, which means constants can now be used as an internal implementation detail, and not necessarily a public constant that can be specified in a separate class or interface. Unfortunately traits still don't allow constants... it's easy to see use cases for them, here's a very basic example: trait ColorTrait { protected $color; protected const COLORS = [ 'red' => true, 'green' => true, 'blue' => true ]; function setColor($color) { if (!isset(self::COLORS[$color])) { throw new Exception('Meh'); } $this->color = $color; } } Note, I'm aware of a duplicate of this bug: #70986, but since it's from 2 years ago I wanted to make a better case for the feature, in light of PHP 7.1's improvement on constants. The problem raised in the original bug report is: what happens if different constants of the same name are in different traits? I propose an easy to implement conservative solution: Fatal Error "Cannot use traits with the same constant names". We can always refine the solution now, and reduce the surface of rejected trait combinations later on, but to at least support the basic use cases, which now we're also denied. Test script: --------------- trait Foo { const BAR = 123; } Expected result: ---------------- No errors. Actual result: -------------- Fatal error: Traits cannot have constants ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=75060&edit=1

« previous php.bugs (#243142) next »