Req #75060 [Sus->Csd]: Allow traits to have constants to support emerging use cases
| From: | cmb@php.net | 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