rfc:final_class_const

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Last revisionBoth sides next revision
rfc:final_class_const [2021/04/23 09:51] kocsismaterfc:final_class_const [2021/06/14 07:48] nikic
Line 2: Line 2:
   * Date: 2021-04-23   * Date: 2021-04-23
   * Author: Máté Kocsis <kocsismate@php.net>   * Author: Máté Kocsis <kocsismate@php.net>
-  * Status: Under discussion+  * Status: Accepted
   * Implementation: https://github.com/php/php-src/pull/6878   * Implementation: https://github.com/php/php-src/pull/6878
 +  * Target Version: PHP 8.1
  
 ===== Introduction ===== ===== Introduction =====
Line 11: Line 12:
 First of all, the engine can't optimize class constant references when late static binding is involved, so it has to pessimistically assume that ''FOO'' is overridden in case of ''static::FOO'' or ''$this::FOO'' invocations. First of all, the engine can't optimize class constant references when late static binding is involved, so it has to pessimistically assume that ''FOO'' is overridden in case of ''static::FOO'' or ''$this::FOO'' invocations.
  
-But more importantly, one cannot make sure that class constant value is really constant.+What'more important is that class constants are not guaranteed to stay constant. Even if the declaring class always references them by using ''self::'', doing so won't prevent a child class from changing their value or even their type, unless the parent is a final class. Although constants not being constants is usually considered only as a theoretical problem, being able to add a ''final'' modifier would make the intention explicit that child classes shouldn't try to override them (e.g. because the parent doesn't use late static binding). 
 + 
 +A related interesting fact is that interface constants are already ''final'': 
 + 
 +<code php> 
 +interface I 
 +
 +    public const X = "i"; 
 +
 + 
 +class C implements I 
 +
 +    public const X = "bar"; 
 +
 + 
 +// Fatal error: Cannot inherit previously-inherited or override constant X from interface I 
 +</code> 
 + 
 +This leads to a weird inconsistencyBy introducing an intermediate class, overriding still becomes possible: 
 + 
 +<code php> 
 +interface I 
 +
 +    public const X = "i"; 
 +
 + 
 +class C implements I 
 +
 +
 + 
 +class D extends C  
 +
 +    public const X = "d"; 
 +
 + 
 +// No error 
 +</code>
  
  
 ===== Proposal ===== ===== Proposal =====
  
-The final modifier can be added to class constants. Doing so prevents a constant to be overridden in a child class:+The final modifier can be added to class constants. Doing so prevents overriding of a constant:
  
 <code php> <code php>
Line 32: Line 69:
 </code> </code>
  
-Besides, interface constants would become overridable by default:+Besides, interface constants would become overridable by default, and the ''final'' modifier could be used to retain the original behavior.
  
 <code php> <code php>
Line 43: Line 80:
 class C implements I class C implements I
 { {
-    public const X = "c"; // Overriding I::X is not possible+    public const X = "c"; // Overriding I::X is possible
     public const Y = "c"; // Overriding I::Y is not possible     public const Y = "c"; // Overriding I::Y is not possible
 } }
Line 52: Line 89:
 ===== Reflection ===== ===== Reflection =====
  
-A ''ReflectionClassConstant::isFinal()''method is added in order to be able to retrieve if a constant is final.+A ''ReflectionClassConstant::isFinal()'' method is added in order to be able to retrieve if a constant is final.
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
Line 60: Line 97:
 ===== Vote ===== ===== Vote =====
  
-Add support for final class constants? The vote requires 2/3 majority to be accepted.+Voting started on 2021-05-19 08:00 UTC and ends 2021-06-02 08:00 UTC. The vote requires 2/3 majority to be accepted. 
 + 
 +<doodle title="Add support for final class constants?" auth="kocsismate" voteType="single" closed="true"> 
 +   * Yes 
 +   * No 
 +</doodle>
  
  
  
rfc/final_class_const.txt · Last modified: 2021/07/06 20:52 by kocsismate