# Access property of object stored in a constant

- Thread: https://externals.io/message/120917
- Original archive: https://news-web.php.net/php.internals/120917
- Started by Ilija Tovilo on 2023-08-18T15:27:32+00:00
- Messages: 5
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #120917 — Ilija Tovilo — 2023-08-18T15:27:32+00:00

URL: https://externals.io/message/120917#120917

Hi everyone

Since https://wiki.php.net/rfc/new_in_initializers we can store
objects in global constants. However, we may not actually read or
write to the properties of those objects without first fetching the
constant into a local variable.

const a = new stdClass;
a->b = 42; // Fatal error: Cannot use temporary expression in write context
$a = a;
$a->b = 42; // Works fine

This issue was reported twice, so it seems like this code is generally
expected to work.
https://github.com/php/php-src/issues/10497
https://github.com/php/php-src/issues/11781

I have created a patch here to add support for this syntax:
https://github.com/php/php-src/pull/11788

Since this is a language change I would like to ask for feedback
before merging. As always, if there are concerns I will create a small
RFC instead. I will also only merge this for 8.4, as feature freeze
for 8.3 has long passed.

Ilija

---

## #120918 — Juliette Reinders Folmer — 2023-08-19T00:18:37+00:00

URL: https://externals.io/message/120917#120918 · In reply to: #120917

> Hi everyone
>
> Since https://wiki.php.net/rfc/new_in_initializers we can store
> objects in global constants. However, we may not actually read or
> write to the properties of those objects without first fetching the
> constant into a local variable.
>
> const a = new stdClass;
> a->b = 42; // Fatal error: Cannot use temporary expression in write context
> $a = a;
> $a->b = 42; // Works fine
>
> This issue was reported twice, so it seems like this code is generally
> expected to work.
> https://github.com/php/php-src/issues/10497
> https://github.com/php/php-src/issues/11781
>
> I have created a patch here to add support for this syntax:
> https://github.com/php/php-src/pull/11788
>
> Since this is a language change I would like to ask for feedback
> before merging. As always, if there are concerns I will create a small
> RFC instead. I will also only merge this for 8.4, as feature freeze
> for 8.3 has long passed.
>
> Ilija
>

I totally understand that people are trying to do this, but this still 
very much feels like scope creep.

IIRC the new in initializers feature was _intended_ only for enums 
(which can't take properties). Now suddenly a "constant" would no longer 
be constant... In which case, what's the point of declaring it as a 
constant ?

Smile,
Juliette

---

## #120919 — Ilija Tovilo — 2023-08-19T08:48:06+00:00

URL: https://externals.io/message/120917#120919 · In reply to: #120918

Hi Juliette

> > […]
>
> I totally understand that people are trying to do this, but this still
> very much feels like scope creep.
>
> IIRC the new in initializers feature was _intended_ only for enums
> (which can't take properties). Now suddenly a "constant" would no longer
> be constant... In which case, what's the point of declaring it as a
> constant ?

This patch doesn't change the mutability of objects in constants, as
they already don't offer interior immutability. https://3v4l.org/s7rHE
This is analogous to `const` in JavaScript or `readonly` properties in
PHP, where we can't change the value of the variable (or const in this
case), but we can modify the properties of the object it's pointing
to.

I believe the main motivation for `new` in constant expressions was to
support nested attributes. Enums have their own mechanism for
instantiating cases. Since it was decided to expand the support for
`new` to global constants, I would expect it to work with other
language constructs, unless there's a good reason for it not to.

Ilija

---

## #120920 — Claude Pache — 2023-08-19T09:21:50+00:00

URL: https://externals.io/message/120917#120920 · In reply to: #120918

> Le 19 août 2023 à 02:18, Juliette Reinders Folmer <php-internals_nospam@adviesenzo.nl> a écrit :
> 
> 
> I totally understand that people are trying to do this, but this still very much feels like scope creep.
> 
> IIRC the new in initializers feature was _intended_ only for enums (which can't take properties). Now suddenly a "constant" would no longer be constant... In which case, what's the point of declaring it as a constant ?
> 
> Smile,
> Juliette

Hi,

It might not be the original intended use. But people are entitled to use features if they find them handy for their purpose. (It was the reason I end up using PHP rather than Java: because it solved problems <https://www.npopov.com/2012/06/29/PHP-solves-problems-Oh-and-you-can-program-with-it-too.html>.)

At the time I filed https://github.com/php/php-src/issues/10497, I was merely exploring the potential of the new ability to have an object in a constant. The potential use I had back in my head was the following. Currently, I store some settings in global constants. I was contemplating replacing those by properties of a readonly object stored in a global constant. (A fatal issue I discovered later in my journey is that readonly properties can only be initialised by code inside the class itself.)

But in any case, it is good to have regularity in the language. The fact that an object is stored in a constant is completely orthogonal with the fact that the object is mutable, and the proposed patch does not add new capability. (Conversely, the current limitation does not remove any capability.)

—Claude

---

## #120921 — Larry Garfield — 2023-08-19T16:54:36+00:00

URL: https://externals.io/message/120917#120921 · In reply to: #120920

> At the time I filed https://github.com/php/php-src/issues/10497, I was 
> merely exploring the potential of the new ability to have an object in 
> a constant. The potential use I had back in my head was the following. 
> Currently, I store some settings in global constants. I was 
> contemplating replacing those by properties of a readonly object stored 
> in a global constant. (A fatal issue I discovered later in my journey 
> is that readonly properties can only be initialised by code inside the 
> class itself.)

As a tangent here, that has a workaround:

https://peakd.com/hive-168588/@crell/php-tricks-access-control-bypass

Which I make use of in Crell/Serde, which is then used by my own config library to produce exactly what you describe:

https://github.com/Crell/Config

--Larry Garfield
