Hi internals,
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]]
This proposal is only for stdClass - there was not much interest in https://wiki.php.net/rfc/compact-object-property-assignment
and the combination of named properties and constructor property promotion helps with the readability of other classes.
Thanks,
- Tyson
Hi internals,
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 beobject{[$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 RFCsobject{key: $value}
is suggested here for similarity to named
argumentsBenefits:
- 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 APIsFor 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]]
This proposal is only for stdClass - there was not much interest in
https://wiki.php.net/rfc/compact-object-property-assignment
and the combination of named properties and constructor property
promotion helps with the readability of other classes.Thanks,
- Tyson
The only data structure worse than an associative array -- from the point of view of performance, self-documentation, or usability -- is stdClass. :-) I can't recall using it in the last decade at least, and my code has been better for it.
Especially now with constructor promotion and named properties, I'd prefer to just forget that stdClass exists and encourage others to do so as well.
--Larry Garfield
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 beobject{[$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 argumentsBenefits:
- 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 APIsFor 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