php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #76186 ArrayObject should be able to be Json encoded as an Array
Submitted: 2018-04-05 14:01 UTC Modified: 2018-04-05 14:39 UTC
From: lionel at lionelmartin dot eu Assigned:
Status: Open Package: SPL related
PHP Version: 7.1 OS: Linux
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2018-04-05 14:01 UTC] lionel at lionelmartin dot eu
Description:
------------
When using json_encode on an ArrayIterator (or ArrayObject), the result is always an object contrary to its json_encoded array representation.

Test script:
---------------
$array = ['my', 'test', 'array'];
$arrayObject = new \ArrayObject($array);
$arrayIterator = $arrayObject->getIterator();

echo json_encode($array);
echo json_encode($arrayObject);
echo json_encode($arrayIterator);


Expected result:
----------------
["my","test","array"]
["my","test","array"]
["my","test","array"]

Actual result:
--------------
["my","test","array"]
{"0":"my","1":"test","2":"array"}
{"0":"my","1":"test","2":"array"}

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-04-05 14:14 UTC] fractalesque at gmail dot com
I fail to understand the "bug" part of your issue. It really is expected that an ArrayObject representation of an array be encoded as an object in json. 

The contrary would be quite unsettling, actually.
 [2018-04-05 14:39 UTC] requinix@php.net
-Summary: ArrayIterator is always Json encoded as an Object +Summary: ArrayObject should be able to be Json encoded as an Array -Type: Bug +Type: Feature/Change Request -PHP Version: 5.6.35 +PHP Version: 7.1
 [2018-04-05 14:39 UTC] requinix@php.net
In both cases you can use iterator_to_array(). https://3v4l.org/09dT1

ArrayObject is an object so this behavior makes sense, but having it implement JsonSerializable sounds reasonable.
@fractalesque: I think the idea is that an array and an ArrayObject both containing the same data should be serialized the same way. Yes, the class would have special handling just for this case. I assume internally it could just be a matter of adding a JsonSerializable::jsonSerialize() that returns the private $storage array.

However ArrayIterator isn't as easy because it's an iterator, so keys (and values) are not known ahead of time. That would mean processing the iterator twice: once to identify whether it can constitute a JSON array, then again to actually serialize the data. Of course the first pass would have to store the values in a temporary array in case the iterator being serialized can't run again, and that temporary array would be what gets serialized in the second pass.
Which makes it all the same as using iterator_to_array().

In my opinion, iterators should always be serialized as objects, for simplicity, and if the developer knows the data is suitable then they can/should use iterator_to_array() explicitly. But I think it's a topic debatable enough to warrant discussing on the internals mailing list, if you'd like to start that. http://php.net/mailing-lists.php
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Mon Sep 28 13:01:23 2020 UTC