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
rfc:final_class_const [2021/04/23 09:51] kocsismaterfc:final_class_const [2021/07/06 20:52] (current) kocsismate
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: Implemented
   * 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.1619171505.txt.gz · Last modified: 2021/04/23 09:51 by kocsismate