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", &parameter, 
&options) == FAILURE) {
                return;
-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to