Wow! I notice that ArrayObject already does everything we would need for json_encode().
assert(json_encode(new ArrayObject([5])) === '{"0":5}'); However, it does so in a very strange way, not using any of the public methods, but also not using dynamic properties. It seems there is a hard-coded internal implementation when calling json_encode() or converting to array. https://3v4l.org/rAc4K I think we would want something more clean and transparent. On Wed, 8 Sept 2021 at 21:58, Andreas Hennings <andr...@dqxtech.net> wrote: > > On Wed, 8 Sept 2021 at 18:33, Lynn <kja...@gmail.com> wrote: > > > > On Wed, Sep 8, 2021 at 5:38 PM Mike Schinkel <m...@newclarity.net> wrote: > > > > > A couple more things; add a `JSON_OUTPUT_DYNAMIC_OBJECT` flag to output to > > > DynamicObject for `json_decode()`, add a 3rd parameter for flags to > > > var_export() for the same reason, a `'return_dynamic_object'` option for > > > `unserialize()`, and so on. > > > > > > > It would also be interesting to enter a user-defined class here to work as > > a reversed JsonSerializable. Could be a static factory method for all I > > care, and would omit the requirement of serialization libraries for > > "simple" things where you still want decent object typing. Could also work > > together with interfaces accepting properties, effectively making the > > result of json_decode an anonymous class that still adheres to an > > interface. In case of the custom 'deserialization' you can throw exceptions > > if the format is not correct. In the case of an anonymous class with an > > interface it could throw an exception if the structure doesn't match > > (possibly controlled by flags?). > > I think we want round-trips of json_decode() + json_encode() to work > loss-free, without any custom classes or extra parameters. > > Currently, '{}' and '[]' have different results with json_decode(). > > assert(json_encode(json_decode('{}')) === '{}'); // Perfect round-trip. > assert(json_encode(json_decode('{}', JSON_OBJECT_AS_ARRAY)) === '[]'); > // Lossy round-trip. > > This can only work if we have a built-in data transfer object, > distinct from arrays. > Currently this is \stdClass, using the dynamic property mechanism. > > But one could easily imagine a different kind of data transfer object, > which would use a different mechanism instead of dynamic properties. > > A native implementation of JsonSerializable does not really work here, > because ->jsonSerialize() would have to return \stdClass to result in > '{}'. > Instead, what about something with a "->getData(): array" method, but > then json_decode() would encode it as '{}'? > > assert(json_decode('{}') instanceof DataTransferObject); > assert(json_decode('{}')->getData() === []); > assert(json_encode(json_decode('{}')->getData()) === '[]'); > assert(json_encode(json_decode('{}')) === '{}'); > > For the proposed rename: > - If we can fully deprecate and replace dynamic properties long-term, > I would rather keep the name \stdClass until it dies. > - Instead of an alias or rename, I would rather have a new data > transfer object class which would not rely on dynamic properties, but > on a new mechanism. > > Imo, creating an alias won't actually make life easier for anyone, > unless we can fully remove and replace \stdClass. > It would mean that developers need to learn both names, and understand > how aliases work - something you don't really need to learn otherwise. > Think of the silly wtfs that can occur if people don't fully > understand aliases, or are not aware that DynamicObject is just an > alias, while \ReflectionClass and get_class() still return 'stdClass' > as the class name. > > -- Andreas -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php