Hi everybody
I'd like to propose a change to stdClass so that it can satisfy the
iterable parameter/return type.
Firstly I acknowledge that this isn't an ideal solution, but I think it
gets us to a better state than we're in today. It shouldn't be necessary,
but while we have such a common function (json_decode) returning stdClass
we should make it easy/unsurprising to work with.
https://wiki.php.net/rfc/iterable-stdclass
Thanks,
Craig
Hi Duncan,
I quite strongly dislike the idea, as it sounds like this solution is
a hack for a particular use case, and that use case doesn't seem to be
particularly important to me.
I say it's not particularly important to me, as you could solve it right now by:
i) asking json_decode to return an array rather than an object.
ii) converting the result from json_decode into an object that
implements traversable.
iii) By accepted that PHP's type system isn't powerful enough to make
all programs trivially type-safe, and so to not use the iterable
parameter type here. This won't make your program any more or less
correct, it will just be slightly more annoying to debug.
Those seem to be better than special casing StdClass.
I say it's a hack as you're forcing the language to fit a particular
need with the available tools now, rather than thinking through what
best end-goal would be.
I think the correct long-term solution for this would be for us to
revisit the union type RFC (https://wiki.php.net/rfc/union_types) and
so be able to define a type like:
type foreachable = object|iterable;
The union types RFC would support the problem you're trying to solve,
as well as other use cases without introducing special cases.
cheers
Dan
Ack
Hi everybody
I'd like to propose a change to stdClass so that it can satisfy the
iterable parameter/return type.Firstly I acknowledge that this isn't an ideal solution, but I think it
gets us to a better state than we're in today. It shouldn't be necessary,
but while we have such a common function (json_decode) returning stdClass
we should make it easy/unsurprising to work with.https://wiki.php.net/rfc/iterable-stdclass
Thanks,
Craig
Hi Duncan,
[...] great points
I was about to reply to Craig when Dans' email hit the list.
I couldn't agree with Dan more.
The expanded use of stdClass feels wrong to me, as in: wrong solution to
a problem best solved differently. Dan gave ample examples about that.
I think one more approach not mentioned is that you could also (array) $yourStdClassVar
. Of course you didn't ask for it, but nevertheless:
stdClass is already a weird thing on its own and I wouldn't want to see
it getting more attention to increase the encourage to use it.
cheers,
- Markus
I think the correct long-term solution for this would be for us to
revisit the union type RFC (https://wiki.php.net/rfc/union_types) and
so be able to define a type like:type foreachable = object|iterable;
This argument makes sense to me in a pre-iterable world, but as we already
have an iterable type I don't understand why it shouldn't accept stdClass
as well as array.
What about an array is more iterable than a stdClass object?
What about an array is more iterable than a stdClass object?
An array is the structure PHP provides to represent a list, or an ordered
collection of arbitrary key-value pairs; an object, whether stdClass or
otherwise, is neither of these things.
I would instead ask: what about a stdClass object is more iterable than an
object created from a user-defined class?
Regards,
Rowan Collins
[IMSoP]
Hi everybody
I'd like to propose a change to stdClass so that it can satisfy the
iterable parameter/return type.Firstly I acknowledge that this isn't an ideal solution, but I think it
gets us to a better state than we're in today. It shouldn't be necessary,
but while we have such a common function (json_decode) returning stdClass
we should make it easy/unsurprising to work with.https://wiki.php.net/rfc/iterable-stdclass
Thanks,
Craig
Rather than implementing Traversable, I think it would be much better to
implement IteratorAggregate and provide a proper getIterator()
implementation. Objects that only implement Traversable are a PITA to work
with and lots of code assumes that anything Traversable will either be
Iterator or IteratorAggregate. For userland code this is strictly enforced,
but internal code can avoid this. However, the current exceptions to this
are rather niche, while stdClass is somewhat commonly used.
I'm in favor of the general change here. What I mainly have in mind is that
we should stop allowing iteration over arbitrary objects in the future (we
did the first step by excluding them from "iterable") and instead require
the use of an explicit PropertyIterator, or similar. However, we'd probably
still want to allow direct iteration of stdClass and the cleanest way to do
that is to make it Traversable (via IteratorAggregate).
Nikita
Rather than implementing Traversable, I think it would be much better to
implement IteratorAggregate and provide a proper getIterator()
implementation. Objects that only implement Traversable are a PITA to work
with and lots of code assumes that anything Traversable will either be
Iterator or IteratorAggregate. For userland code this is strictly enforced,
but internal code can avoid this. However, the current exceptions to this
are rather niche, while stdClass is somewhat commonly used.
That makes sense, if the RFC passes I'll pick up these implementation
points before proceeding, thanks
Rather than implementing Traversable, I think it would be much better to
implement IteratorAggregate and provide a proper getIterator()
implementation.
I think adding behaviour to stdClass is a precedent we should approach with
extreme caution.
Currently, it has no methods, and matches no type checks other than itself
and "object"; in a sense, it doesn't even have any properties, just the
ability to add them dynamically. To me, that makes sense: it's the
"classless object", the absolute bare minimum any object could be.
What I mainly have in mind is that
we should stop allowing iteration over arbitrary objects in the future (we
did the first step by excluding them from "iterable") and instead require
the use of an explicit PropertyIterator, or similar.
I agree that this should be explicit, and it could probably be implemented
as a very light wrapper.
However, we'd probably still want to allow direct iteration of stdClass
Why? What do you consider the role of stdClass to be, that means having it
opt in to this behaviour would always be appropriate?
If you want something iterable, you can convert your stdClass object to an
array, wrap it an iterator that accepts any object, or convert it however
you want into a "proper" object where you can define what behaviour you
want.
Regards,
Rowan Collins
[IMSoP]
Currently, it has no methods, and matches no type checks other than itself
and "object"; in a sense, it doesn't even have any properties, just the
ability to add them dynamically. To me, that makes sense: it's the
"classless object", the absolute bare minimum any object could be.
Apologies for the multiple replies, but it just occurred to me that with
anonymous classes, we can define something even more minimal:
$foo = new class {};
$bar = new stdClass;
Given that stdClass is returned as a "default structureless object" by a
lot of internal functions, what is the justification for $foo and $bar here
behaving differently?
Regards,
Rowan Collins
[IMSoP]
On Mon, Jan 14, 2019 at 3:48 PM Rowan Collins rowan.collins@gmail.com
wrote:
Rather than implementing Traversable, I think it would be much better to
implement IteratorAggregate and provide a proper getIterator()
implementation.I think adding behaviour to stdClass is a precedent we should approach
with extreme caution.Currently, it has no methods, and matches no type checks other than itself
and "object"; in a sense, it doesn't even have any properties, just the
ability to add them dynamically. To me, that makes sense: it's the
"classless object", the absolute bare minimum any object could be.What I mainly have in mind is that
we should stop allowing iteration over arbitrary objects in the future (we
did the first step by excluding them from "iterable") and instead require
the use of an explicit PropertyIterator, or similar.I agree that this should be explicit, and it could probably be implemented
as a very light wrapper.However, we'd probably still want to allow direct iteration of stdClass
Why? What do you consider the role of stdClass to be, that means having it
opt in to this behaviour would always be appropriate?
The way I see it, stdClass is basically an array in object notation (and
object passing semantics). It carries data in the form of key value pairs
and has no associated logic. The only things you can do with it are access
keys (properties) and ... iterate over them.
Mind you, stdClass is an anti-pattern. Instead of stdClass you should
just be using an array. We should never have added stdClass. But now that
we do have it, and with the way it is typically being used, I think it's
fully appropriate to iterate over it.
That is much unlike most other (non-Traversable) objects, where iterating
over them is only reasonable in a few rather specific scenarios (say, a
serializer, cloner, hydrator or whatever -- something that explicitly is
interested in inspecting properties of objects as a matter of
representation).
Nikita
If you want something iterable, you can convert your stdClass object to an
array, wrap it an iterator that accepts any object, or convert it however
you want into a "proper" object where you can define what behaviour you
want.Regards,
Rowan Collins
[IMSoP]
The way I see it, stdClass is basically an array in object notation (and
object passing semantics). It carries data in the form of key value pairs
and has no associated logic. The only things you can do with it are access
keys (properties) and ... iterate over them.[...] But now that we do have it, and with the way it is typically being
used, I think it's fully appropriate to iterate over it.
I think it's the assumption about "the way it is typically being used"
where I differ from you. I generally see stdClass being used where people
want to access specific keys using -> notation, and maybe to get the
pass-by-pointer semantics. I'm not convinced that iterating over it as an
ordered collection is a sufficiently universal use case that it should be
an exception to the proposed rule of "objects aren't iterable unless
iteration logic has been defined".
I can see it might be convenient occasionally, but it feels like an
unnecessary special case, on top of a feature which I agree should be
discouraged anyway.
Regards,
Rowan Collins
[IMSoP]
We should never have added stdClass.
Why not deprecate it then, instead of extending it and giving it more
legitimacy?
This would remove some of the "2 ways of doing the same thing", such as
json_decode()
.
Ben
On Mon, Jan 14, 2019 at 3:48 PM Rowan Collins rowan.collins@gmail.com
wrote:Rather than implementing Traversable, I think it would be much better to
implement IteratorAggregate and provide a proper getIterator()
implementation.I think adding behaviour to stdClass is a precedent we should approach
with extreme caution.Currently, it has no methods, and matches no type checks other than
itself
and "object"; in a sense, it doesn't even have any properties, just the
ability to add them dynamically. To me, that makes sense: it's the
"classless object", the absolute bare minimum any object could be.What I mainly have in mind is that
we should stop allowing iteration over arbitrary objects in the future
(we
did the first step by excluding them from "iterable") and instead
require
the use of an explicit PropertyIterator, or similar.I agree that this should be explicit, and it could probably be
implemented
as a very light wrapper.However, we'd probably still want to allow direct iteration of stdClass
Why? What do you consider the role of stdClass to be, that means having
it
opt in to this behaviour would always be appropriate?The way I see it, stdClass is basically an array in object notation (and
object passing semantics). It carries data in the form of key value pairs
and has no associated logic. The only things you can do with it are access
keys (properties) and ... iterate over them.Mind you, stdClass is an anti-pattern. Instead of stdClass you should
just be using an array. We should never have added stdClass. But now that
we do have it, and with the way it is typically being used, I think it's
fully appropriate to iterate over it.That is much unlike most other (non-Traversable) objects, where iterating
over them is only reasonable in a few rather specific scenarios (say, a
serializer, cloner, hydrator or whatever -- something that explicitly is
interested in inspecting properties of objects as a matter of
representation).Nikita
If you want something iterable, you can convert your stdClass object to
an
array, wrap it an iterator that accepts any object, or convert it however
you want into a "proper" object where you can define what behaviour you
want.Regards,
Rowan Collins
[IMSoP]
On Mon, Jan 14, 2019 at 4:09 PM Benjamin Morel benjamin.morel@gmail.com
wrote:
We should never have added stdClass.
Why not deprecate it then, instead of extending it and giving it more
legitimacy?
This would remove some of the "2 ways of doing the same thing", such as
json_decode()
.Ben
This.
stdClass
can't die due to a lot of backwards compatibility in existing
code (wordpress loves it), but in any code I've written over the past 5
years, the first thing I'd do with it is get rid of it as fast as possible.
Making it more powerful will just make the problem bigger.
Marco Pivetta
stdClass
can't die due to a lot of backwards compatibility in existing
code (wordpress loves it)
I, personally, would LOVE to see PHP break things on each release of a
major version!
I fail to see how upgrading could be painful, with a good changelog and the
right E_DEPRECATED
notices for a minor release or two, enough time to make
it run in dev and even production, and working on deprecation notices as
they appear in the log; this would make the language move much faster
towards a better language.
But I digress.
On Mon, Jan 14, 2019 at 4:09 PM Benjamin Morel benjamin.morel@gmail.com
wrote:We should never have added stdClass.
Why not deprecate it then, instead of extending it and giving it more
legitimacy?
This would remove some of the "2 ways of doing the same thing", such as
json_decode()
.Ben
This.
stdClass
can't die due to a lot of backwards compatibility in existing
code (wordpress loves it), but in any code I've written over the past 5
years, the first thing I'd do with it is get rid of it as fast as possible.Making it more powerful will just make the problem bigger.
Marco Pivetta