Allow objects in define()

php.internals

Nikita Popov

5 years ago
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

Marco Pivetta

5 years ago
Hey NikiC, On Mon, Jun 14, 2021, 16:35 Nikita Popov <nikita.ppv@gmail.com> wrote:
> 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?

Nikita Popov

5 years ago
On Mon, Jun 14, 2021 at 4:42 PM Marco Pivetta <ocramius@gmail.com> wrote:
> Hey NikiC, > > On Mon, Jun 14, 2021, 16:35 Nikita Popov <nikita.ppv@gmail.com> wrote: > >> 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? >
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

Marco Pivetta

5 years ago
On Mon, Jun 14, 2021 at 5:02 PM Nikita Popov <nikita.ppv@gmail.com> wrote:
> 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/

Claude Pache

5 years ago
> > 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

Maxime Veber

5 years ago
> > 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> >
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

Nikita Popov

5 years ago
On Tue, Jun 15, 2021 at 8:44 AM Claude Pache <claude.pache@gmail.com> wrote:
> > > > 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

Larry Garfield

5 years ago
On Mon, Jun 14, 2021, at 9:35 AM, Nikita Popov wrote:
> 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

Paul Dragoonis

5 years ago
On Mon, Jun 14, 2021 at 7:47 PM Larry Garfield <larry@garfieldtech.com> wrote:
> On Mon, Jun 14, 2021, at 9:35 AM, Nikita Popov wrote: > > 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. >
Sounds sensible to me too. Good enhancement.