|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2017-08-11 11:16 UTC] cmb@php.net
-Status: Open
+Status: Suspended
[2017-08-11 11:16 UTC] cmb@php.net
[2020-06-21 01:10 UTC] jake at qzdesign dot co dot uk
[2022-12-14 14:07 UTC] cmb@php.net
-Status: Suspended
+Status: Closed
-Assigned To:
+Assigned To: cmb
[2022-12-14 14:07 UTC] cmb@php.net
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sun Oct 26 07:00:01 2025 UTC |
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