# Allow objects in define()

- Thread: https://externals.io/message/114863
- Original archive: https://news-web.php.net/php.internals/114863
- Started by Nikita Popov on 2021-06-14T14:35:00+00:00
- Messages: 9
- 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

---

## #114863 — Nikita Popov — 2021-06-14T14:35:00+00:00

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

Hi internals,

With the introduction of enums, it's now possible for constants to hold
objects. However, this works only when using the `const X = Y` syntax, not
when using `define('X', Y)`, which still excludes objects.

I've submitted https://github.com/php/php-src/pull/7149 to relax the
restriction. This means that `define()` would accept everything apart from
recursive arrays.

An alternative here would be to allow `define()` to only accept enum objects
in particular, but not other objects. I would prefer not to do that, as
such a restriction would be rather arbitrary, now that the technical work
to support objects has been done. (PS: Please keep the difference between
mutability and interior mutability in mind.)

Regards,
Nikita

---

## #114864 — Marco Pivetta — 2021-06-14T14:42:40+00:00

URL: https://externals.io/message/114863#114864 · In reply to: #114863

Hey NikiC,



> Hi internals,
>
> With the introduction of enums, it's now possible for constants to hold
> objects. However, this works only when using the `const X = Y` syntax, not
> when using `define('X', Y)`, which still excludes objects.
>
> I've submitted https://github.com/php/php-src/pull/7149 to relax the
> restriction. This means that `define()` would accept everything apart from
> recursive arrays.
>
> An alternative here would be to allow `define()` to only accept enum objects
> in particular, but not other objects. I would prefer not to do that, as
> such a restriction would be rather arbitrary, now that the technical work
> to support objects has been done. (PS: Please keep the difference between
> mutability and interior mutability in mind.)
>

I rarely encounter any code using `define()` for anything more than
extremely minimal environment details these days, and even then, it usually
leads to loading an immutable `Environment` object that is then passed
through dependency injection (container or not) to runtime services.

What are the possible use-cases for this, besides enumeration types?

---

## #114865 — Nikita Popov — 2021-06-14T15:01:43+00:00

URL: https://externals.io/message/114863#114865 · In reply to: #114864

> Hey NikiC,
>
> 
>
> > […]
>
> I rarely encounter any code using `define()` for anything more than
> extremely minimal environment details these days, and even then, it usually
> leads to loading an immutable `Environment` object that is then passed
> through dependency injection (container or not) to runtime services.
>
> What are the possible use-cases for this, besides enumeration types?
>

Not sure about specific use cases, for me the important aspect here is to
avoid arbitrary restrictions. For example, `define()` accepts resources, and
this is used for some core constants like STDIN, STDOUT, STDERR.

In the future, we're going to switch these resources to be objects, so
allowing them in constants would be necessary at that point at least.
Actually, we already encountered this as a BC issue when switching some
other resource types to objects.

I don't think there is any principled argument for why constants would
accept arbitrary resources but not arbitrary objects. There's only the
historical circumstance that objects weren't supported for technical
reasons, which have since been addressed.

Regards,
Nikita

---

## #114867 — Marco Pivetta — 2021-06-14T16:02:03+00:00

URL: https://externals.io/message/114863#114867 · In reply to: #114865

> In the future, we're going to switch these resources to be objects, so
> allowing them in constants would be necessary at that point at least.
> Actually, we already encountered this as a BC issue when switching some
> other resource types to objects.
>

Makes perfect sense, thanks!

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/

---

## #114869 — Larry Garfield — 2021-06-14T18:47:05+00:00

URL: https://externals.io/message/114863#114869 · In reply to: #114863

> Hi internals,
> 
> With the introduction of enums, it's now possible for constants to hold
> objects. However, this works only when using the `const X = Y` syntax, not
> when using `define('X', Y)`, which still excludes objects.
> 
> I've submitted https://github.com/php/php-src/pull/7149 to relax the
> restriction. This means that `define()` would accept everything apart from
> recursive arrays.
> 
> An alternative here would be to allow `define()` to only accept enum objects
> in particular, but not other objects. I would prefer not to do that, as
> such a restriction would be rather arbitrary, now that the technical work
> to support objects has been done. (PS: Please keep the difference between
> mutability and interior mutability in mind.)
> 
> Regards,
> Nikita

Sounds fine to me.  `define()` is runtime anyway so it should support runtime values.

--Larry Garfield

---

## #114873 — Paul Dragoonis — 2021-06-14T23:36:35+00:00

URL: https://externals.io/message/114863#114873 · In reply to: #114869

On Mon, Jun 14, 2021 at 7:47 PM Larry Garfield <larry@garfieldtech.com>
wrote:

> 
> > […]
> not
> > […]
> objects
> > […]
>
> Sounds fine to me.  `define()` is runtime anyway so it should support
> runtime values.
>

Sounds sensible to me too. Good enhancement.


>
> --Larry Garfield
>
> --
> 
> To unsubscribe, visit: https://www.php.net/unsub.php

---

## #114874 — Claude Pache — 2021-06-15T06:44:03+00:00

URL: https://externals.io/message/114863#114874 · In reply to: #114865

> 
> Not sure about specific use cases, for me the important aspect here is to
> avoid arbitrary restrictions. For example, `define()` accepts resources, and
> this is used for some core constants like STDIN, STDOUT, STDERR.
> 

Per the documentation [1], defining resource constants is supposed to “cause unpredictable behavio[u]r” and is “not recommended”. Is this correct or just FUD?

[1]: https://www.php.net/manual/en/function.define.php <https://www.php.net/manual/en/function.define.php>

—Claude

---

## #114875 — Maxime Veber — 2021-06-15T06:56:59+00:00

URL: https://externals.io/message/114863#114875 · In reply to: #114874

> > […]
> and
> > […]
>
> Per the documentation [1], defining resource constants is supposed to
> “cause unpredictable behavio[u]r” and is “not recommended”. Is this correct
> or just FUD?
>
> [1]: https://www.php.net/manual/en/function.define.php <
> https://www.php.net/manual/en/function.define.php>
>
It also states that it is used for STDIN, STDOU and STDERR, which will be
objects in the future but will still need to be defined for BC.

Regards,
Maxime

---

## #114878 — Nikita Popov — 2021-06-15T07:50:49+00:00

URL: https://externals.io/message/114863#114878 · In reply to: #114874

>
>
>
> Not sure about specific use cases, for me the important aspect here is to
> avoid arbitrary restrictions. For example, `define()` accepts resources, and
> this is used for some core constants like STDIN, STDOUT, STDERR.
>
>
> Per the documentation [1], defining resource constants is supposed to
> “cause unpredictable behavio[u]r” and is “not recommended”. Is this correct
> or just FUD?
>

Well, at least I'm not aware of any "unpredictable behavior" it could
cause. I wouldn't recommend it either -- but that's more because I would
recommend against most uses of `define()`, not so much resources in
particular.

Regards,
Nikita
