php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #38680 json_decode won't decode json_encode
Submitted: 2006-09-01 11:42 UTC Modified: 2008-07-22 16:56 UTC
From: RQuadling at GMail dot com Assigned: iliaa (profile)
Status: Closed Package: JSON related
PHP Version: 5.2 OS:
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: RQuadling at GMail dot com
New email:
PHP Version: OS:

 

 [2006-09-01 11:42 UTC] RQuadling at GMail dot com
Description:
------------
Hi.

I might be widly wrong but I would have thought that json_decode would quite happily reverse a json_encode.

This seems to work fine for arrays and null (not tested with objects), but doesn't work at all with strings, integers or booleans.

Though I think the NULL working is just a fluke.

I can allow for the integer to not match as there is no type  info as far as I can tell.

The documentation DOES say that ...

"Returns a string containing the JSON representation of value. 

Parameters
value 
The value being encoded. Can be __any__ type except a resource. 

Return Values
Returns a JSON encoded string on success."

Note __any__ type.


Amendment after trying to submit bug : I see that bug#38440 relates to this. And as this has been fixed in CVS, then I suspect this is now a documentation issue.

Reproduce code:
---------------
<?php
$a_Originals = array
	(
	'SimpleString' => 'This is a string',
	'Array' => array ('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5),
	'Integer' => 1234,
	'Boolean_True' => True,
	'Boolean_False' => False,
	'NULL' => NULL,
	);

foreach($a_Originals as $s_Type => $m_Data)
	{
	$s_JS_Encoded = json_encode($m_Data);
	$m_JS_Decoded_Array = json_decode($s_JS_Encoded, True);
	echo "\n========================================\nEncoding $s_Type : ";
	var_dump($m_Data);
	echo "Encoded : ";
	var_dump($s_JS_Encoded);
	echo "Decoded : ";
	var_dump($m_JS_Decoded_Array);
	echo (serialize($m_Data) === serialize($m_JS_Decoded_Array)) ? "\nMatches\n" : "\n**** DOES NOT MATCH ****\n";
	}
?>

Expected result:
----------------
========================================
Encoding SimpleString : string(16) "This is a string"
Encoded : string(18) ""This is a string""
Decoded : string(16) "This is a string"

Matches

========================================
Encoding Array : array(5) {
  ["a"]=>
  int(1)
  ["b"]=>
  int(2)
  ["c"]=>
  int(3)
  ["d"]=>
  int(4)
  ["e"]=>
  int(5)
}
Encoded : string(31) "{"a":1,"b":2,"c":3,"d":4,"e":5}"
Decoded : array(5) {
  ["a"]=>
  int(1)
  ["b"]=>
  int(2)
  ["c"]=>
  int(3)
  ["d"]=>
  int(4)
  ["e"]=>
  int(5)
}

Matches

========================================
Encoding Integer : int(1234)
Encoded : string(4) "1234"
Decoded : string(1234)

**** DOES NOT MATCH ****

========================================
Encoding Boolean_True : bool(true)
Encoded : string(4) "true"
Decoded : bool(true)

Matches

========================================
Encoding Boolean_False : bool(false)
Encoded : string(5) "false"
Decoded : bool(false)

Matches

========================================
Encoding NULL : NULL
Encoded : string(4) "null"
Decoded : NULL

Matches

Actual result:
--------------
========================================
Encoding SimpleString : string(16) "This is a string"
Encoded : string(18) ""This is a string""
Decoded : NULL

**** DOES NOT MATCH ****

========================================
Encoding Array : array(5) {
  ["a"]=>
  int(1)
  ["b"]=>
  int(2)
  ["c"]=>
  int(3)
  ["d"]=>
  int(4)
  ["e"]=>
  int(5)
}
Encoded : string(31) "{"a":1,"b":2,"c":3,"d":4,"e":5}"
Decoded : array(5) {
  ["a"]=>
  int(1)
  ["b"]=>
  int(2)
  ["c"]=>
  int(3)
  ["d"]=>
  int(4)
  ["e"]=>
  int(5)
}

Matches

========================================
Encoding Integer : int(1234)
Encoded : string(4) "1234"
Decoded : NULL

**** DOES NOT MATCH ****

========================================
Encoding Boolean_True : bool(true)
Encoded : string(4) "true"
Decoded : NULL

**** DOES NOT MATCH ****

========================================
Encoding Boolean_False : bool(false)
Encoded : string(5) "false"
Decoded : NULL

**** DOES NOT MATCH ****

========================================
Encoding NULL : NULL
Encoded : string(4) "null"
Decoded : NULL

Matches

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-09-01 13:30 UTC] bjori@php.net
Omar: really a doc issue?
 [2006-09-01 14:25 UTC] omar@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

This is a documentation issue...

true/false/null/numerics in raw form are not valid JSON structures, so json_decode will reject them and output NULL.

Basically, if JSON_checker (http://www.json.org/JSON_checker/) says something is invalid JSON, then json_decode will return NULL.

json_encode emits true/false/etc as any other way makes even less sense. :)
 [2006-09-01 14:43 UTC] RQuadling at GMail dot com
I'm not sure I follow. I'm reading the PHP doc and json_encode says it can encode _ANY_ type except resource.

json_decode says it "takes a JSON encoded string and converts it into a PHP variable".

So, 

$m_var = json_decode(json_decode($m_original_var));

$m_var == $m_original_var.
Maybe NOT ===, but at least ==


So, there are several issues here.

json_encode says ANY type. Not just objects or arrays. Admittedly, an array with int/bool/null in all work fine as does a multi-dimensional array.

If the dox said JUST arrays and objects, then that would be fine too. You could then emit a warning when the types supplied wasn't an array or an object.


But, as it stands, the dox say __ANY__, so, it is VERY reasonable to assume that encoding boolean/integers/null via json_encode will produce something usable.


AND json_decode says it will decode any json_encoded string. Now, at this stage, I'm not even using the data, I'm just encoding it and then instantly decoding it. Not via a browser or JS. Just all in PHP. And this is not working.


In your reply you say that "true/false/null/numerics in raw form are not valid JSON structures, so json_decode will reject them and output NULL" - Fair enough, but not what my bug report is about.

I'm saying that json_encode is NOT producing correctly encoded structures for json_decode, NOT that I'm manually creating these structures and expecting them to work.

<?php
var_dump(json_decode(json_encode(True)));
var_dump(json_decode(json_encode(False)));
var_dump(json_decode(json_encode(Null)));
var_dump(json_decode(json_encode(pi())));
var_dump(json_decode(json_encode(phpversion())));
?>

produces 

NULL
NULL
NULL
NULL
NULL

Very much NOT what would be expected!
 [2006-09-04 08:55 UTC] RQuadling at GMail dot com
Why is this bogus? I've reopened it as the PHP Dox makes no mention of the restriction that only objects and arrays are encodable/decodable. And if the json_encode only dealt with arrays & objects rather than all types except resources, then the code would be cleaner and give less issue.
 [2006-09-24 00:21 UTC] philip@php.net
This is a documentation issue that must (should) be resolved before PHP 5.2 is released. The current docs were taken straight out of the README that's within the json extension sources. 

Please summarize exactly what needs to be changed here.
 [2006-09-24 18:41 UTC] bjori@php.net
reclassified & assigned to Ilia
 [2006-11-03 13:16 UTC] iliaa@php.net
This bug has been fixed in CVS.

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/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed Nov 13 15:01:29 2024 UTC