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
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: lionel at lionelmartin dot eu
New email:
PHP Version: OS:

 

 [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-2021 The PHP Group
All rights reserved.
Last updated: Thu Apr 22 17:01:24 2021 UTC