rfc:readonly_classes

Differences

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

Link to this comparison view

Next revision
Previous revision
rfc:readonly_classes [2021/08/05 08:54] – created kocsismaterfc:readonly_classes [2022/08/21 08:47] (current) kocsismate
Line 2: Line 2:
   * Date: 2021-08-04   * Date: 2021-08-04
   * Author: Máté Kocsis <kocsismate@php.net>   * Author: Máté Kocsis <kocsismate@php.net>
-  * Status: Draft+  * Status: Accepted
   * Target Version: PHP 8.2   * Target Version: PHP 8.2
   * Implementation: https://github.com/php/php-src/pull/7305   * Implementation: https://github.com/php/php-src/pull/7305
Line 8: Line 8:
 ===== Introduction ===== ===== Introduction =====
  
-PHP 8.1 added support for ''readonly'' properties via [[rfc:readonly_properties_v2|PHP RFC: Readonly properties 2.0]].+PHP 8.1 added support for readonly properties via [[rfc:readonly_properties_v2|PHP RFC: Readonly properties 2.0]]. However, it's still not easy to declare (quasi-)immutable classes, especially if they contain many properties. Therefore, this RFC proposes to add support for ''readonly'' classes.
  
 ===== Proposal ===== ===== Proposal =====
Line 20: Line 20:
 </PHP> </PHP>
  
-Doing so will implicitly mark all typed instance properties of a class as readonly. Furthermore, it will prevent the usage of dynmacic properties.+Doing so will implicitly mark all instance properties of a class as readonly. Furthermore, it will prevent the creation of dynamic properties. 
 + 
 +<PHP> 
 +readonly class Foo 
 +
 +    public int $bar; 
 + 
 +    public function __construct() { 
 +        $this->bar = 1; 
 +    } 
 +
 + 
 +$foo = new Foo(); 
 +$foo->bar = 2; 
 +// Fatal Error: Uncaught Error: Cannot modify readonly property Foo::$bar 
 + 
 +$foo->baz = 1; 
 +// Fatal Error: Uncaught Error: Cannot create dynamic property Foo::$baz 
 +</PHP> 
 + 
 +[[rfc:deprecate_dynamic_properties|PHP RFC: Deprecate dynamic properties]] added support for the ''#[AllowDynamicProperties]'' attribute which makes it possible to create dynamic properties without triggering errors. In order not to violate the read-only constraint, marking readonly classes with the above attribute is a compile-time error: 
 + 
 +<PHP> 
 +#[AllowDynamicProperties] 
 +readonly class Foo { 
 +
 + 
 +// Fatal error: Cannot apply #[AllowDynamicProperties] to readonly class Foo 
 +</PHP> 
  
 ==== Restrictions ==== ==== Restrictions ====
  
-A readonly class can only have typed properties.+As neither untyped, nor static properties are covered by the [[rfc:readonly_properties_v2#restrictions|Readonly properties RFC]], 
 +readonly classes cannot declare them either:
  
-Readonly static properties are not supported. This is a technical limitation, in that it is not possible to implement readonly static properties non-intrusively. In conjunction with the questionable usefulness of readonly static properties, this is not considered worthwhile at this time.+<PHP> 
 +readonly class Foo 
 +
 +    public $bar; 
 +
 + 
 +// Fatal error: Readonly property Foo::$bar must have type 
 +</PHP> 
 + 
 +<PHP> 
 +readonly class Foo 
 +
 +    public static int $bar; 
 +
 + 
 +// Fatal error: Readonly class Foo cannot declare static properties 
 +</PHP>
  
 ==== Inheritance ==== ==== Inheritance ====
  
-Similarly how overriding of readonly properties workonly a readonly class can extend a readonly class:+Similarly how overriding of readonly properties works, a readonly class can only extend a readonly parent:
  
 <PHP> <PHP>
-class A {} +readonly class A {} 
-readonly class B extends A {}+readonly class B extends A {} // valid
 </PHP> </PHP>
  
-Both of the following are illegal:+But both of the following are illegal:
  
 <PHP> <PHP>
 readonly class A {} readonly class A {}
 class B extends A {} class B extends A {}
 +// Fatal error: Non-readonly class B cannot extend readonly class A
 </PHP> </PHP>
  
Line 47: Line 94:
 class A {} class A {}
 readonly class B extends A {} readonly class B extends A {}
 +// Fatal error: Readonly class B cannot extend non-readonly class A
 </PHP> </PHP>
  
 ==== Reflection ==== ==== Reflection ====
  
-A ''ReflectionClass::isReadOnly()'' method is added, which reports whether a class is declared as read-only. ''ReflectionClass::getModifiers()'' will also report a ''ReflectionClass::IS_READONLY'' flag.+A ''ReflectionClass::isReadOnly()'' method is added, which reports whether a class is declared as read-only. Additionally, ''ReflectionClass::getModifiers()'' will also include the ''ReflectionClass::IS_READONLY'' flag.
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
  
 None. None.
 +
 +===== Errata =====
 +
 +  * [[https://github.com/php/php-src/issues/9285|https://github.com/php/php-src/issues/9285]]: It used to be possible to add non-readonly properties to readonly classes via traits. As on PHP 8.2 RC 1, traits cannot be used by readonly classes if they define any non-readonly property, otherwise a compilation error is emitted.
  
 ===== Vote ===== ===== Vote =====
  
-Add readonly classes as proposed?+Voted started on 2022-04-27, ending on 2022-05-11 
 + 
 +<doodle title="Add readonly classes as proposed?" auth="kocsismate" voteType="single" closed="true"> 
 +   * Yes 
 +   * No 
 +</doodle>
  
rfc/readonly_classes.1628153644.txt.gz · Last modified: 2021/08/05 08:54 by kocsismate