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