On Sat, Sep 25, 2021 at 5:45 PM tyson andre <tysonandre...@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 `(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 `__set_state`
> (which is not yet allowed). Instead, `(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

Reply via email to