Re: Allowing `(object)['key' => 'value']` in initializers?
| From: | Nikita Popov | Date: | Mon, 04 Oct 2021 09:09:59 +0000 |
| Subject: | Re: Allowing `(object)['key' => 'value']` in initializers? | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-116209@lists.php.net to get a copy of this message | ||
On Sat, Sep 25, 2021 at 5:45 PM tyson andre <tysonandre775@hotmail.com>
wrote:
>
> Hi internals,
>
> In PHP 8.1, it is possible to allow constructing any class name in an
> initializer, after the approval of
> https://wiki.php.net/rfc/new_in_initializers
>
> ```
> php > static $x1 = new ArrayObject(['key' => 'value']);
> php > static $x2 = new stdClass();
> php > static $x3 = (object)['key' => 'value'];
>
> Fatal error: Constant expression contains invalid operations in php shell
> code on line 1
> ```
>
> What are your thoughts on allowing the
> (which is not yet allowed). Instead,
(object) cast in
> initializer
> types where new was already allowed, but only when followed by
> an array
> literal node. (e.g. continue to forbid (object)SOME_CONSTANT)
> (see
> https://wiki.php.net/rfc/new_in_initializers)
>
> stdClass has never implemented a factory method such as (object)[] or the
> (object)array()
> shorthand is typically used when a generic object literal is needed. This
> is also how php represents objects in var_export.
>
> ```
> php > var_export(new stdClass());
> (object) array(
> )
> ```
>
> Reasons:
> - The ability to construct empty stdClass instances but not non-empty ones
> is something users would find surprising,
> and a lack of support for (object)[] be even more
> inconsistent if
> factory methods were allowed in the future.
> - stdClass is useful for some developers, e.g. in unit tests, when using
> libraries requiring it for parameters,
> when you need to ensure data is encoded as a JSON {} rather
> than [],
> etc.
> - It would help developers write a clearer api contract for methods,
> e.g. function setData(stdClass $default = (object)['key' =>
> 'value'])
> is clearer than `function setData(?stdClass $default = null) { $default
> ??= (object)['key' => 'value']; `
> - stdClass may be the only efficient built-in way to represent objects
> with arbitrary names if RFCs such as
> https://externals.io/message/115800
> passed
>
I'm not super convinced about the usefulness of (object)[] in particular,
but I also think that we shouldn't artificially limit the types of
expressions supported in constant expressions -- if there's no strong
reason why something should be forbidden, it should be allowed.
From that perspective, I think the root issue here is that constant
expressions currently don't support casts at all. It's not just a matter of
being unable to write (object)[], you also can't write (int)X (but you can
write +X). I think it's perfectly reasonable to support casts in constant
expressions, and if we do, then I don't think we need to go out of the way
to forbid object casts either, so support for (object)[] should just fall
out as a special case.
Regards,
Nikita