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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: kruithne at gmail dot com
New email:
PHP Version: OS:

 

 [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

Pull Requests

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-2024 The PHP Group
All rights reserved.
Last updated: Sat Nov 23 07:01:29 2024 UTC