e.g. $x = object{key: object{'escaped-literal': $v2 }};
(equivalent to $x = (object)['key' => (object)['escaped-literal' => $v2]];)
For example, in JS, non-string key literals are surrounded in [] to unambiguously reference them.
Here, that could be object{[$key]: $value, [MY_CONST]: $other} - but (MY_CONST) would also work
- https://externals.io/message/52990 was mentioned 9 years ago but would potentially conflict with future block expression RFCs
- object{key: $value} is suggested here for similarity to named arguments
Benefits:
- Shorter and more readable code - casting an array to an object is an unintuitive and potentially hard to remember
way to create an object literal
- Make it easier for users to use objects for generic associative data instead of using arrays both for lists and associative data,
in situations where it may result in more usable APIs
For example,
$x = new stdClass{};
$x->prop = new stdClass{};
$x->prop->a = $a;
$x->prop->b = $b;
// Could be shortened to
$x = object{prop: object{a: $a, b: $b}}
// $x = (object)['prop' => (object)['a' => $a, 'b' => $b]]
Creating a new syntax, that is only used in context of \stdClass, feels like overkill. Unfortunately, I cannot come up with a use case for this syntax, outside of the \stdClass context.
I would also debate the point of the new syntax being more readable compared to the
(object) cast, but that very much depends on what the reader is used to. I would however like to point out that shorter isn't always better and sometimes more verbose code is easier to understand. Imho a language shouldn't look like code-golf by recommendation. But I don't want to and hope I didn't sidetrack the discussion.
With regards to the matter at hand I can see where you are coming from.
(object)['prop' => 1, ...] feels very indirect, needlessly creating an array instance just to get an object out of it.
Wouldn't it be opportune to just use named arguments?
$x = new \stdClass(
prop: new \stdClass(
a: $a,
b: $b
)
);
While this isn't as short as the object{} suggestion, it doesn't add any additional language constructs. The signature of \stdClass constructor would change to
\stdClass(...$defaultProperties). Maybe this is the kickoff for variadic property promotion `__constructor(public mixed ...$properties)`.
The following would be true:
new \stdClass(1, 2, 3, prop: 1.2) == (object)[1, 2, 3, 'prop' => 1.2];
On the subject of dynamic/variable property names: I would suggest that a RFC for the syntax
functionA($parameterName: 'value') should be submitted at some point. This would replace the already working
functionA(...[$parameterName => 'value']). Maybe we even find a way of using constants as well, which would could be something like your suggested
functionA([SOME_CONST]: 'value').
This would allow everyone to benefit from the change, not only \stdClass.
Closing I would like to make a short point with regards to the
(object) cast:
Both a cast of \stdClass to
(array) and a cast of arrays to
(object) are common use cases in (JSON-)API development. It is not unheard of for API signatures to contain certain properties of the JSON response object only if some conditions are met. Currently the best way to achieve this is either by dynamically adding properties to an existing \stdClass object, or by populating an array and
(object) casting it later.
- Andreas