Hi there,
I've tried to come up with a solution for
Formatting option for json_encode
http://bugs.php.net/bug.php?id=44331
Any comments are highly welcome :)
the patch is against the PHP_5_3 branch as HEAD changes quite some
unicode stuff.
Greetings,
Florian
--- ext/json/json.c.orig 2009-12-09 22:15:33.000000000 +0100
+++ ext/json/json.c 2009-12-09 22:48:04.000000000 +0100
@@ -42,6 +42,7 @@
#define PHP_JSON_HEX_APOS (1<<2)
#define PHP_JSON_HEX_QUOT (1<<3)
#define PHP_JSON_FORCE_OBJECT (1<<4)
+#define PHP_JSON_FORMAT_OUTPUT (1<<5)
#define PHP_JSON_OUTPUT_ARRAY 0
#define PHP_JSON_OUTPUT_OBJECT 1
@@ -81,6 +82,7 @@
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_OBJECT", PHP_JSON_FORCE_OBJECT,
CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("JSON_FORMAT_OUTPUT", PHP_JSON_FORMAT_OUTPUT,
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);
@@ -172,9 +174,10 @@
}
/* }}} */
-static void json_encode_array(smart_str *buf, zval **val, int options
TSRMLS_DC) /* {{{ */
+static void json_encode_array(smart_str *buf, zval **val, int options, int
nesting_level TSRMLS_DC) /* {{{ */
{
- int i, r;
+ int i, r, fmt;
+ int ii = 0;
HashTable *myht;
if (Z_TYPE_PP(val) == IS_ARRAY) {
@@ -184,6 +187,7 @@
myht = Z_OBJPROP_PP(val);
r = PHP_JSON_OUTPUT_OBJECT;
}
+ fmt = ( options & PHP_JSON_FORMAT_OUTPUT) ? 1 : 0;
if (myht && myht->nApplyCount > 1) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion
detected");
@@ -195,6 +199,9 @@
smart_str_appendc(buf, '[');
} else {
smart_str_appendc(buf, '{');
+ if (fmt) {
+ smart_str_appendc(buf, '\n');
+ }
}
i = myht ? zend_hash_num_elements(myht) : 0;
@@ -227,8 +234,7 @@
} else {
need_comma = 1;
}
-
- php_json_encode(buf, *data, options
TSRMLS_CC);
+ php_json_encode_ex(buf, *data, options,
nesting_level+1 TSRMLS_CC);
} else if (r == PHP_JSON_OUTPUT_OBJECT) {
if (i == HASH_KEY_IS_STRING) {
if (key[0] == '\0' &&
Z_TYPE_PP(val) == IS_OBJECT) {
@@ -241,27 +247,43 @@
if (need_comma) {
smart_str_appendc(buf,
',');
+ if (fmt) {
+
smart_str_appendc(buf, '\n');
+ }
} else {
need_comma = 1;
}
+ if (fmt) {
+ for
(ii=0;ii<=nesting_level;ii++) {
+
smart_str_appendc(buf, '\t');
+ }
+ }
json_escape_string(buf, key,
key_len - 1, options TSRMLS_CC);
smart_str_appendc(buf, ':');
- php_json_encode(buf, *data,
options TSRMLS_CC);
+ php_json_encode_ex(buf, *data,
options, nesting_level+1 TSRMLS_CC);
} else {
if (need_comma) {
smart_str_appendc(buf,
',');
+ if (fmt) {
+
smart_str_appendc(buf, '\n');
+ }
} else {
need_comma = 1;
}
+ if (fmt) {
+ for
(ii=0;ii<=nesting_level;ii++) {
+
smart_str_appendc(buf, '\t');
+ }
+ }
smart_str_appendc(buf, '"');
smart_str_append_long(buf,
(long) index);
smart_str_appendc(buf, '"');
smart_str_appendc(buf, ':');
- php_json_encode(buf, *data,
options TSRMLS_CC);
+ php_json_encode_ex(buf, *data,
options, nesting_level+1 TSRMLS_CC);
}
}
@@ -275,6 +297,12 @@
if (r == PHP_JSON_OUTPUT_ARRAY) {
smart_str_appendc(buf, ']');
} else {
+ if (fmt) {
+ smart_str_appendc(buf, '\n');
+ for (ii=0;ii<nesting_level;ii++) {
+ smart_str_appendc(buf, '\t');
+ }
+ }
smart_str_appendc(buf, '}');
}
}
@@ -414,6 +442,12 @@
PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options
TSRMLS_DC) /* {{{ */
{
+ php_json_encode_ex(buf, val, options, 0 TSRMLS_DC);
+}
+/* }}} */
+
+PHP_JSON_API void php_json_encode_ex(smart_str *buf, zval *val, int options,
int nesting_level TSRMLS_DC) /* {{{ */
+{
JSON_G(error_code) = PHP_JSON_ERROR_NONE;
switch (Z_TYPE_P(val))
{
@@ -456,7 +490,7 @@
case IS_ARRAY:
case IS_OBJECT:
- json_encode_array(buf, &val, options TSRMLS_CC);
+ json_encode_array(buf, &val, options, nesting_level
TSRMLS_CC);
break;
default:
@@ -544,6 +578,7 @@
zval *parameter;
smart_str buf = {0};
long options = 0;
+ int nesting_level = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", ¶meter,
&options) == FAILURE) {
return;
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php