I'm personally unconvinced of the value of this, and would probably propose
it was blocked by coding standards in my team if it was added, because its
meaning is so ambiguous.
That's perfectly reasonable. Do you also block use of casting to a string
with (string) $foo as well? I ask because this proposal is simply on par
with the idea behind string casting for objects.
I have seen valid uses of __toString(), but I would certainly approach it
cautiously. For a complex object, it's not at all obvious if (string)$foo
will give you a debug representation, a JSON serialisation, an HTML
rendering, etc.
Most objects do not have a single "natural"/"canonical" array
representation
I think the same could be said about "__toString()". But with that, some
classes can be boiled down to a single representation, such as the
Ramsey\Uuid https://github.com/ramsey/uuid/ package.
Indeed it could. I think the difference is that a "one-dimensional" object,
like a UUID, probably does lend itself to a single canonical string
representation. You wouldn't expect it to return XML, or JSON, or any other
string format, so (string)$uuid is fairly unambiguous.
The same is with arrays. You can have a single entity such as person to
where its array representation can be first name, last name, age, race,
gender, email, etc...,
This is exactly the kind of place I would not want a simple toArray()
function. Should (array)$person (or $person->toArray()) return
['firstName'=>'Rowan', 'lastName'=>'Collins'], or ['name' => 'Rowan
Collins'], or ['name' => ['Rowan', 'Collins']]? What date format should
'dateOfBirth' be formatted to? If 'address' is an object, should that be
converted to an object as well, and into what format? The answers to these
questions are going to be different in different contexts, and it doesn't
make sense for the Person class to determine the "one true array
representation" - the only canonical representation is the object itself.
or you can have a collection of items, to where in that representation as
an array, you have control over what information is returned and what
isn't.
This is a more reasonable case; given that objects can't completely mimic
arrays, I can see value in a custom List class implementing an array cast
as a quick "back door" for using existing array functionality.
As a thought experiment, imagine a similar method which allowed you to
overload (object)$foo. Although (array)$foo tells you slightly more than
that, I'm not convinced it tells you enough that you're not just hiding
meaning behind cute syntax.
I'm confused by example, as there's no real need to overload casting to an
object as a class is already an object. Whereas, a class is not already an
array.
Sure, it's extra vague because "return $this" would be a valid response,
but imagine there was something other than objects - structs, or custom
resources, or whatever - and there was special syntax to say "give me an
object based on this thing". The immediate question would surely be "what
object? what are you using it for?" I feel the same way about "give me an
array based on this object" - it tells me very little about what you
actually want, and why.
It's not about "cute syntax", it's honestly about providing a simple
clutter free helper for developers to take control over how their classes
are transformed to array representations.
If it's not recursive, it's just syntactic sugar - which can be fine, if it
serves a common use case, but it adds an extra "trick" that readers need to
know about. It doesn't let you do anything you can't already - (array)$foo
would just be a funny way of spelling $foo->__toArray()
JsonSerializable actually suffers from similar problems, and is IMO useful
only because it's automatically recursive. I presume the proposed mechanism
would not be, i.e. return [$foo] would not be interpreted as return
[(array)$foo].
You bring up a good point. Could you for a moment pretend like you're
behind this proposal and expand upon this question? If PHP were to have a
__toArray() method, would you see it as being recursive? In your opinion,
how should/would it react?
A recursive method would certainly have more value, because it actually
does something more than translate one syntax to another. On the other
hand, the use case that comes to mind is serialization, and we already have
more specific methods and systems for that.
I guess that's what it comes down to, what specific use cases would this
feature be intended to help with? Is there some code of your own that
inspired you to propose it, or something you've seen publically that would
benefit from it?
Regards,
Rowan Collins
[IMSoP]