json_encode() and Generators / RFC Karma

php.internals

Philip Hofstetter

2 years ago
Hello, In the aftermath of an internal refactoring of an internal code-base to turn something eager into something more lazy using Generators, it occurred to me that while PHP refuses to serialize() a Generator, accidentally running json_encode() over a Generator produces the worst possible result: It silently encodes generators as {}. I would like to write an RFC to first deprecating and later disallowing to json_encode Generators. If you think this is a worthwhile thing to do an RFC for, I would kindly ask for somebody to grant me RFC karma, so I can start working on one. Regards Philip

Ilija Tovilo

2 years ago
Hi Philip On Fri, Aug 30, 2024 at 9:37 AM Philip Hofstetter <phofstetter@sensational.ch> wrote:
> > If you think this is a worthwhile thing to do an RFC for, I would kindly ask for somebody to grant me RFC karma, so I can start working on one.
To grant you RFC karma, I need to know your wiki.php.net username. Ilija

Philip Hofstetter

2 years ago
Hi Ilija, On Aug 30, 2024 at 09:49:14, Ilija Tovilo <tovilo.ilija@gmail.com> wrote:
> > To grant you RFC karma, I need to know your wiki.php.net username. >
Username is pilif Thank you Philip Hofstetter

Ilija Tovilo

2 years ago
On Fri, Aug 30, 2024 at 12:19 PM Philip Hofstetter <phofstetter@sensational.ch> wrote:
> > Username is pilif
RFC karma was granted. Good luck with the RFC!

Claude Pache

2 years ago
> Le 30 août 2024 à 09:36, Philip Hofstetter <phofstetter@sensational.ch> a écrit : > > Hello, > > In the aftermath of an internal refactoring of an internal code-base to turn something eager into something more lazy using Generators, it occurred to me that while PHP refuses to serialize() a Generator, accidentally running json_encode() over a Generator produces the worst possible result: > > It silently encodes generators as {}. > > I would like to write an RFC to first deprecating and later disallowing to json_encode Generators. >
Hi, Note that the issue is not limited to Generators. For instance a Closure object is also json-encodable but not serialisable. IMO, every internal class (not just Generator) that is marked as non-serialisable, should also be non-json-encodable. —Claude

Philip Hofstetter

1 year ago
Hi, On Aug 30, 2024 at 16:47:43, Claude Pache <claude.pache@gmail.com> wrote:
> > Note that the issue is not limited to Generators. For instance a Closure > object is also json-encodable but not serialisable. > > IMO, every internal class (not just Generator) that is marked as > non-serialisable, should also be non-json-encodable. >
Thank you for brining this up. When working on the implementation to link to the RFC, I came across ZEND_ACC_NOT_SERIALIZABLE and its usage with serialize() and it occurred to me that there’s probably some sense in making json_encode look at that flag in general. Of course this would greatly increase the amount of possible deprecation warnings thrown and other objects flagged with ZEND_ACC_NOT_SERIALIZABLE (resource handles, reflection, and, yes, Closure) are not as likely to cause harm as Generators do because refactoring something from arrays to Generators is a relatively common operation which also is mostly transparent to the majority of callers, so a deprecation warning and later error will provide actual value in this case whereas json_encode() over an accidentally present, say, CurlHandle is of no consequence for a user, so little value is provided by the eventually thrown exception. Implementation-wise, I can say that using ZEND_ACC_NOT_SERIALIZABLE is super simple and turning this into a 2 line patch (plus a few lines of test code), but I’m a bit concerned about the large BC surface, even though I do agree that conceptionally ZEND_ACC_NOT_SERIALIZABLE should be used. I will write the RFC based on ZEND_ACC_NOT_SERIALIZABLE and if it turns out in discussion or in the voting phase that the BC concerns are too grave, I will find and propose an implementation that’s more specific to Generators. Philip