php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #47493 Option to force empty arrays to be an empty object for json_encode()
Submitted: 2009-02-24 13:42 UTC Modified: 2009-03-19 16:03 UTC
Votes:2
Avg. Score:3.0 ± 1.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:1 (100.0%)
From: RQuadling at GMail dot com Assigned:
Status: Closed Package: Feature/Change Request
PHP Version: 5.3CVS-2009-02-24 (snap) OS: n/a
Private report: No CVE-ID:
 [2009-02-24 13:42 UTC] RQuadling at GMail dot com
Description:
------------
When you json_encode() an associative array you get an object hash in 
Javascript.

When you json_encode() an array with numeric only keys you get an 
array in Javascript.

So far so good.

But, if you json_encode() an empty array, you get an array in 
Javascript, which, whilst not wrong, it is a pain if the client side 
is expecting an object hash.

It would be nice to have the option to force the output to be thought 
of as an object.

This would compliment the $assoc parameter of the json_decode() 
function.

The flag would only be meaningful for empty arrays (I think), so the 
impact SHOULD be quite low.

And as it is optional, it should not break anything backwards (but 
what do I know!).

I've included below an attempt at this simply patch.


If this was added, could it be added to 5.2+.

As soon as it is added, I can update the docs for this new feature.


Index: json.c
===================================================================
RCS file: /repository/php-src/ext/json/json.c,v
retrieving revision 1.47
diff -u -r1.47 json.c
--- json.c	31 Dec 2008 11:12:32 -0000	1.47
+++ json.c	24 Feb 2009 13:36:23 -0000
@@ -41,6 +41,7 @@
 #define PHP_JSON_HEX_AMP	(1<<1)
 #define PHP_JSON_HEX_APOS	(1<<2)
 #define PHP_JSON_HEX_QUOT	(1<<3)
+#define PHP_JSON_FORCE_HASH     (1<<4)
 
 ZEND_DECLARE_MODULE_GLOBALS(json)
 
@@ -76,6 +77,8 @@
 	REGISTER_LONG_CONSTANT("JSON_HEX_APOS", PHP_JSON_HEX_APOS, 
CONST_CS | CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("JSON_HEX_QUOT", PHP_JSON_HEX_QUOT, 
CONST_CS | CONST_PERSISTENT);
 
+	REGISTER_LONG_CONSTANT("JSON_FORCE_HASH", 
PHP_JSON_FORCE_HASH, CONST_CS | CONST_PERSISTENT);
+
 	REGISTER_LONG_CONSTANT("JSON_ERROR_NONE", 
PHP_JSON_ERROR_NONE, CONST_CS | CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("JSON_ERROR_DEPTH", 
PHP_JSON_ERROR_DEPTH, CONST_CS | CONST_PERSISTENT);
 	REGISTER_LONG_CONSTANT("JSON_ERROR_STATE_MISMATCH", 
PHP_JSON_ERROR_STATE_MISMATCH, CONST_CS | CONST_PERSISTENT);
@@ -172,7 +175,7 @@
 	int i, r;
 	HashTable *myht;
 
-	if (Z_TYPE_PP(val) == IS_ARRAY) {
+	if (Z_TYPE_PP(val) == IS_ARRAY && !(options & 
PHP_JSON_FORCE_HASH)) {
 		myht = HASH_OF(*val);
 		r = json_determine_array_type(val TSRMLS_CC);
 	} else {





Reproduce code:
---------------
<?php
echo json_encode(array(), PHP_JSON_FORCE_HASH);
?>

Expected result:
----------------
[]

Actual result:
--------------
{}

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-02-24 13:56 UTC] rquadling@php.net
In testing of forcing ALL arrays as objects and using FireBug to see 
the results, a PHP array of

$array = array(
 "one",
 "two",
 "three",
);

can be encoded as an array like ...

["one","two","three"]

or as an object like ...

{0:"one",1:"two",2,"three"}

or

{"0":"one","1":"two","2","three"}


quite happily.

Regards,

Richard Quadling.
 [2009-03-02 16:20 UTC] RQuadling at GMail dot com
Patch to unit test if patch is applied.

Index: tests/002.phpt
===================================================================
RCS file: /repository/php-src/ext/json/tests/002.phpt,v
retrieving revision 1.3
diff -u -r1.3 002.phpt
--- tests/002.phpt	27 May 2008 18:16:03 -0000	1.3
+++ tests/002.phpt	2 Mar 2009 16:16:13 -0000
@@ -1,4 +1,4 @@
---TEST--
+&#65279;--TEST--
 json_encode() tests
 --SKIPIF--
 <?php if (!extension_loaded("json")) print "skip"; ?>
@@ -8,8 +8,14 @@
 var_dump(json_encode(""));
 var_dump(json_encode(NULL));
 var_dump(json_encode(TRUE));
+
 var_dump(json_encode(array(""=>"")));
 var_dump(json_encode(array(array(1))));
+var_dump(json_encode(array());
+
+var_dump(json_encode(array(""=>"")), PHP_JSON_FORCE_HASH);
+var_dump(json_encode(array(array(1))),PHP_JSON_FORCE_HASH);
+var_dump(json_encode(array(),PHP_JSON_FORCE_HASH);
 
 var_dump(json_encode(1));
 var_dump(json_encode("&#1088;&#1091;&#1089;&#1089;&#1080;&#1096;"));
@@ -23,6 +29,10 @@
 string(4) "true"
 string(7) "{"":""}"
 string(5) "[[1]]"
+string(2) "[]"
+string(7) "{"":""}"
+string(15) "{"0":{"0":"1"}}"
+string(2) "{}"
 string(1) "1"
 string(38) ""\u0440\u0443\u0441\u0441\u0438\u0448""
 Done
 [2009-03-19 16:03 UTC] rquadling@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.

Fixed in 5.3.0+ and documented.
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Sat Apr 19 19:02:15 2014 UTC