php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73991 JSON_OBJECT_AS_ARRAY flag does not function.
Submitted: 2017-01-25 11:38 UTC Modified: 2017-03-17 22:39 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: kruithne at gmail dot com Assigned: pollita (profile)
Status: Closed Package: JSON related
PHP Version: 7.1.1 OS: All
Private report: No CVE-ID: None
 [2017-01-25 11:38 UTC] kruithne at gmail dot com
Description:
------------
The documentation states that the fourth parameter for json_decode() is a bit-mask value, it goes on to list two possible flags: JSON_OBJECT_AS_ARRAY and JSON_BIGINT_AS_STRING.

Despite being redundant (superseded by the second parameter), the JSON_OBJECT_AS_ARRAY flag has no effect on the decoded result when supplied.

Test script:
---------------
<?php
    $json = '{"test": "From there to here, and here to there, funny things are everywhere.", "number": 12345678901234567890}';
    
    // Prove json_decode is working by default.
    // Expected: object(stdClass) (2) {["test"] => string(67) ["number"] => float()}
    // Result: object(stdClass) (2) {["test"] => string(67) ["number"] => float()}
    $decoded = json_decode($json);
    var_dump($decoded);
    
    // Prove that passing bit-mask options works.
    // Expected: object(stdClass) (2) {["test"] => string(67) ["number"] => string(20)}
    // Result: object(stdClass) (2) {["test"] => string(67) ["number"] => string(20)}
    $decoded = json_decode($json, false, 512, JSON_BIGINT_AS_STRING);
    var_dump($decoded);
    
    // Prove that the second parameter works for associative conversion.
    // Expected: array(2) {["test"] => string(67) ["number"] => string(20)}
    // Result: array(2) {["test"] => string(67) ["number"] => string(20)}
    $decoded = json_decode($json, true, 512, JSON_BIGINT_AS_STRING);
    var_dump($decoded);
    
    // Attempt to use JSON_OBJECT_AS_ARRAY for associative conversion fails.
    // Expected: array(2) {["test"] => string(67) ["number"] => string(20)}
    // Result: object(stdClass) (2) {["test"] => string(67) ["number"] => string(20)}
    $decoded = json_decode($json, false, 512, JSON_OBJECT_AS_ARRAY);
    var_dump($decoded);

Expected result:
----------------
object(stdClass) (2) {["test"] => string(67) ["number"] => float()}
object(stdClass) (2) {["test"] => string(67) ["number"] => string(20)}
array(2) {["test"] => string(67) ["number"] => string(20)}
array(2) {["test"] => string(67) ["number"] => string(20)}

Actual result:
--------------
object(stdClass) (2) {["test"] => string(67) ["number"] => float()}
object(stdClass) (2) {["test"] => string(67) ["number"] => string(20)}
array(2) {["test"] => string(67) ["number"] => string(20)}
object(stdClass) (2) {["test"] => string(67) ["number"] => string(20)}

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-01-25 12:20 UTC] requinix@php.net
-Assigned To: +Assigned To: pollita
 [2017-01-25 12:20 UTC] requinix@php.net
$assoc always overrides the OBJECT_AS_ARRAY flag, so in that fourth test PHP deliberately unsets it because you passed $assoc=false.

I don't know the reasoning behind that (which came from @pollita back in 2010 and PHP 5.4.0) but while removing the unsetting behavior makes sense to me, I'd be wary of changing anything now.
 [2017-01-25 14:39 UTC] kruithne at gmail dot com
While a very minor thing, I feel it would make more sense to have the associative behavior activated based on EITHER the $assoc (second parameter) or the $options flag (JSON_OBJECT_AS_ARRAY) being true, rather than having the $assoc take undocumented precedence over the activation.
 [2017-03-17 22:26 UTC] pollita@php.net
Best as I can recall, the thinking was that internally, options would replace the usage of the separate (zend_bool assoc) flag. Externally.... I'm not sure why we actually exposed the constant :/

As a BC-safe compromise, I'll parse the bool $assoc param as nullable, json_decode($json, null, $options) will then respect the use of JSON_OBJECT_AS_ARRAY in $options.  An explicit true/false however will still override the $options integer.
 [2017-03-17 22:39 UTC] pollita@php.net
-Status: Assigned +Status: Closed
 [2017-03-17 22:39 UTC] pollita@php.net
The fix for this bug has been committed.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Nov 19 01:31:42 2017 UTC