Both sides previous revisionPrevious revisionNext revision | Previous revision |
rfc:fetch_property_in_const_expressions [2022/06/23 11:00] – Typo ilutov | rfc:fetch_property_in_const_expressions [2022/07/18 21:57] (current) – Move to implemented ilutov |
---|
* Date: 2022-05-27 | * Date: 2022-05-27 |
* Author: Ilija Tovilo <ilutov@php.net> | * Author: Ilija Tovilo <ilutov@php.net> |
* Status: Under discussion | * Status: Implemented |
* Proposed Version: PHP 8.2 | * Proposed Version: PHP 8.2 |
* Implementation: https://github.com/php/php-src/pull/8625 | * Implementation: https://github.com/php/php-src/pull/8625 |
// The rhs of -> allows other constant expressions | // The rhs of -> allows other constant expressions |
const VALUE = 'value'; | const VALUE = 'value'; |
| |
class C { | class C { |
const C = E::Foo->{VALUE}; | const C = E::Foo->{VALUE}; |
===== Semantics ===== | ===== Semantics ===== |
| |
The semantics of ''->'' in constant expressions are identical to outside of constant expressions, including access on non-object warnings, undefined property warnings, etc. One exception is that in constant expressions the operators may only be used on enums. The rationale for this decision is in "Supporting all objects". | The semantics of ''->'' in constant expressions are identical to outside of constant expressions, including access on non-object warnings, undefined property warnings, etc. One exception is that in constant expressions the operators may only be used on enums. The rationale for this decision is described in [[https://wiki.php.net/rfc/fetch_property_in_const_expressions#supporting_all_objects|Supporting all objects]]. |
| |
<PHP> | <PHP> |
class A {} | class A {} |
| |
// Warning: Undefined property: A::$c | // Warning: Undefined property: E::$c |
const C = E::Foo->c; // NULL | const C = E::Foo->c; // NULL |
// Note that this will change to an error in PHP 9 https://wiki.php.net/rfc/undefined_property_error_promotion | // Note that this will change to an error in PHP 9 https://wiki.php.net/rfc/undefined_property_error_promotion |
| |
- Order of evaluation | - Order of evaluation |
- Cache invalidation | - Caching of constant expression values |
| |
| Once we have a solution for these two problems we can extend support of ''->'' in constant expressions to all objects. |
| |
==== Order of evaluation ==== | ==== Order of evaluation ==== |
</blockquote> | </blockquote> |
| |
The ''->'' suffers from the same problem as it may invoke the ''%%__get%%'' magic method with arbitrary side-effects. I incorrectly assumed this wasn't possible because ''%%__get%%'' can only be invoked in combination with ''new'' (as enums don't allow ''%%__get%%'') which are disallowed in these contexts. This assumption was incorrect though as the LHS of the ''->'' operator might be another constant which might be an object. | The ''->'' operator suffers from the same problem as it may invoke the ''%%__get%%'' magic method with arbitrary side-effects. I incorrectly assumed this wasn't possible because ''%%__get%%'' can only be invoked in combination with ''new'' (as enums don't allow ''%%__get%%'') which are disallowed in these contexts. This assumption was incorrect though as the LHS of the ''->'' operator might be another constant which might be an object. |
| |
<PHP> | <PHP> |
[1] Ref-counted values consist of non-interned strings, arrays, resources and objects. | [1] Ref-counted values consist of non-interned strings, arrays, resources and objects. |
| |
==== Allow all ''readonly'' properties ==== | ==== Allow all readonly properties ==== |
| |
It was suggested that, instead of restricting ''->'' to be used on all non-enums to restrict access to just non-''readonly'' properties. Unfortunately, this doesn't solve the caching problem described above as ''readonly'' properties can be initialized after object construction and thus becomes non-pure. | It was suggested that instead of restricting ''->'' to be used on all non-enums to restrict access to just non-''readonly'' properties. Unfortunately, this doesn't solve the caching problem described above as ''readonly'' properties can be initialized after object construction and thus becomes non-pure. The enum ''name'' and ''value'' properties are automatically initialized by the engine and thus are truly immutable. |
| |
<PHP> | <PHP> |
===== Vote ===== | ===== Vote ===== |
| |
Voting opened on xxx and closes on xxx. | Voting opened on 2022-07-01 and closes on 2022-07-15. |
| |
<doodle title="Add support for fetching properties of enums in constant expressions?" auth="ilutov" voteType="single" closed="true"> | <doodle title="Add support for fetching properties of enums in constant expressions?" auth="ilutov" voteType="single" closed="true"> |