Re: [PHP-DEV] Proposal for a RFC

This is only part of a thread. view whole thread
  105596
May 5, 2019 14:59 ben@benramsey.com (Ben Ramsey)
> On May 4, 2019, at 09:58, Steven Wade <stevenwadejr@gmail.com> wrote: > > Hi Internals team! > > I have an idea for a feature that I'd love to see in the language one day and wanted to run the idea by you all. > > The idea is to add a new magic method "__toArray()" that would allow a developer to specifiy how a class is cast to an array. The idea is the same mentality of __toString(), but, for arrays. > > I would personally love this feature and those I've run it by were also excited by the idea. So I'm soliciting feedback in hopes that things go well and I can officially write the RFC. As for implementation, Sara Golemon is awesome and while chatting a few months back, knocked out a proof-of-concept implementation <https://github.com/sgolemon/php-src/tree/experimental.toarray>. There's still work to be done if this proposal gets to the RFC phase, but again, just gauging interest here. > > I appreciate any feedback you all can provide. > > Thanks, > > - Steven Wade
Using existing language functionality, would it satisfy the similar needs if you implement IteratorAggregate and return an ArrayIterator from the getIterator() method? Obviously, the (array) cast wouldn’t use this, but you could do $object->getIterator()->getArrayCopy(). I’m not against the proposal. I’m mainly asking if there are other ways in the language today to accomplish similar things. I would prefer to see interfaces used over more magic methods (something like ArraySerializable). -Ben
  105598
May 6, 2019 14:37 stevenwadejr@gmail.com (Steven Wade)
> On May 5, 2019, at 10:59 AM, Ben Ramsey <ben@benramsey.com> wrote: > > >> On May 4, 2019, at 09:58, Steven Wade <stevenwadejr@gmail.com> wrote: >> >> Hi Internals team! >> >> I have an idea for a feature that I'd love to see in the language one day and wanted to run the idea by you all. >> >> The idea is to add a new magic method "__toArray()" that would allow a developer to specifiy how a class is cast to an array. The idea is the same mentality of __toString(), but, for arrays. >> >> I would personally love this feature and those I've run it by were also excited by the idea. So I'm soliciting feedback in hopes that things go well and I can officially write the RFC. As for implementation, Sara Golemon is awesome and while chatting a few months back, knocked out a proof-of-concept implementation <https://github.com/sgolemon/php-src/tree/experimental.toarray>. There's still work to be done if this proposal gets to the RFC phase, but again, just gauging interest here. >> >> I appreciate any feedback you all can provide. >> >> Thanks, >> >> - Steven Wade > > Using existing language functionality, would it satisfy the similar needs if you implement IteratorAggregate and return an ArrayIterator from the getIterator() method? Obviously, the (array) cast wouldn’t use this, but you could do $object->getIterator()->getArrayCopy(). > > I’m not against the proposal. I’m mainly asking if there are other ways in the language today to accomplish similar things. I would prefer to see interfaces used over more magic methods (something like ArraySerializable).
PHP already has the magic built in. The proposal is really just a way to control the magic. We already have "(string) $foo" and "__toString()", so the idea of implementing a "__toArray()" method is bringing a feature more inline with what's already there. I think it reads easier and cleaner "(array) $foo", and a simpler as a developer to implement than a mix of chained methods and interfaces. That being said, adding an interface like `ArraySerializable` might be nice too. I'm seeing technical arguments against adding magic casts, but (just spit-balling here), what if a class implemented a new `ArraySerializable` interace with whatever method it demands, and if that is attempted to be cast to an array either manually by calling "(array) $foo" or PHP attempting to, then the array serialize method is called. ¯\_(ツ)_/¯
  105599
May 6, 2019 14:45 ben@benramsey.com (Ben Ramsey)
> On May 6, 2019, at 09:37, Steven Wade <stevenwadejr@gmail.com> wrote: > > That being said, adding an interface like `ArraySerializable` might be nice too. I'm seeing technical arguments against adding magic casts, but (just spit-balling here), what if a class implemented a new `ArraySerializable` interace with whatever method it demands, and if that is attempted to be cast to an array either manually by calling "(array) $foo" or PHP attempting to, then the array serialize method is called. ¯\_(ツ)_/¯
That’s how I would prefer to see it work. BTW, I’m not suggesting `ArraySerializable` as the name. I used that to make a connection to `JsonSerializable`, which I think did a good job of using an interface for this kind of thing (even though it’s not quite the same because there’s no cast for a JSON type). In some of my open source projects, I’ve had to add `__toString()` to the interfaces to ensure that implementers implement it. It would be nice for my interfaces to instead extend an internal interface like `Stringable`. -Ben
  105616
May 7, 2019 12:25 stevenwadejr@gmail.com (Steven Wade)
> I’m not against the proposal. I’m mainly asking if there are other ways in the language today to accomplish similar things. I would prefer to see interfaces used over more magic methods (something like ArraySerializable).
A Twitter user pointed out that 7.4 is adding two new magic methods <https://wiki.php.net/rfc/custom_object_serialization> - __serialize() and __unserialize(). So adding more magic methods to PHP isn't unprecedented. On the same note, casting is already magical, so controling the implementation via a magic method is more in line with current functionality. -- Steven Wade stevenwadejr@gmail.com
  105622
May 7, 2019 12:58 ocramius@gmail.com (Marco Pivetta)
Hey Steven,


On Tue, 7 May 2019, 14:25 Steven Wade, <stevenwadejr@gmail.com> wrote:

> > I’m not against the proposal. I’m mainly asking if there are other ways > in the language today to accomplish similar things. I would prefer to see > interfaces used over more magic methods (something like ArraySerializable). > > A Twitter user pointed out that 7.4 is adding two new magic methods < > https://wiki.php.net/rfc/custom_object_serialization> - __serialize() and > __unserialize(). So adding more magic methods to PHP isn't unprecedented. > > On the same note, casting is already magical, so controling the > implementation via a magic method is more in line with current > functionality. >
With your current proposal so far, I'd simply have to throw an exception: `if (method_exists($object, '__toArray')) { throw UnsupportedObject::from($object); }` The alternative is to expand the reflection API with an array cast operation in there, and then migrate existing userland usages to that to retain BC. In addition to that, as someone that used to write a lot of `__toString()` (and now doesn't do that anymore), a clear API and interfaced (non-magic) `toArray()` is more powerful and useful. Greets, Marco
  105623
May 7, 2019 13:08 stevenwadejr@gmail.com (Steven Wade)
Hi Marco,

> The alternative is to expand the reflection API with an array cast operation in there, and then migrate existing userland usages to that to retain BC.
That's an interesting proposal - adding new reflection abilities. Hm..
> In addition to that, as someone that used to write a lot of `__toString()` (and now doesn't do that anymore), a clear API and interfaced (non-magic) `toArray()` is more powerful and useful.
I see you and I hear you. After 12 years, still like the magic of PHP. I like that casting is quick, simple, and is less verbose when writing/reading. But I'm not opposed to further discussing possible solutions. If this gets to the RFC stage, I'd prefer it be the best option for the language and most likely to pass. -- Steven Wade stevenwadejr@gmail.com