From cb9c8233fc2d3f30c704b8a96b774aae4559d8b0 Mon Sep 17 00:00:00 2001 From: Adam Harvey Date: Thu, 16 Sep 2010 16:21:15 +0000 Subject: [PATCH] Implement FR #44331 (Formatting option for json_encode). Bikeshedding about the exact form of the JSON pretty printing and brace handling will only be accepted in the form of patches. ;) --- NEWS | 1 + UPGRADING | 1 + ext/json/json.c | 47 +++++++++++++++++++- ext/json/php_json.h | 2 + ext/json/tests/json_encode_pretty_print.phpt | 40 +++++++++++++++++ 5 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 ext/json/tests/json_encode_pretty_print.phpt diff --git a/NEWS b/NEWS index da8139e64c..19094f5c4f 100644 --- a/NEWS +++ b/NEWS @@ -121,6 +121,7 @@ - Implemented FR #49366 (Make slash escaping optional in json_encode()). (Adam) - Implemented FR #48632 (OpenSSL AES support). (yonas dot y at gmail dot com, Pierre) +- Implemented FR #44331 (Formatting option for json_encode). (Adam) - Implemented FR #42060 (Add paged Results support). (ando@OpenLDAP.org, iarenuno@eteo.mondragon.edu, jeanseb@au-fil-du.net, remy.saissy@gmail.com) - Implemented FR #34857 (Change array_combine behaviour when called with empty diff --git a/UPGRADING b/UPGRADING index 11cbaa5a52..8b3befbe84 100755 --- a/UPGRADING +++ b/UPGRADING @@ -235,6 +235,7 @@ UPGRADE NOTES - PHP X.Y f. New global constants + - JSON_PRETTY_PRINT - JSON_UNESCAPED_SLASHES g. New classes diff --git a/ext/json/json.c b/ext/json/json.c index 1836c7f7e2..95766106df 100644 --- a/ext/json/json.c +++ b/ext/json/json.c @@ -94,6 +94,7 @@ static PHP_MINIT_FUNCTION(json) REGISTER_LONG_CONSTANT("JSON_FORCE_OBJECT", PHP_JSON_FORCE_OBJECT, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("JSON_NUMERIC_CHECK", PHP_JSON_NUMERIC_CHECK, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("JSON_UNESCAPED_SLASHES", PHP_JSON_UNESCAPED_SLASHES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("JSON_PRETTY_PRINT", PHP_JSON_PRETTY_PRINT, 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); @@ -113,6 +114,7 @@ static PHP_MINIT_FUNCTION(json) */ static PHP_GINIT_FUNCTION(json) { + json_globals->encoder_depth = 0; json_globals->error_code = 0; } /* }}} */ @@ -189,6 +191,30 @@ static int json_determine_array_type(zval **val TSRMLS_DC) /* {{{ */ } /* }}} */ +/* {{{ Pretty printing support functions */ + +static inline void json_pretty_print_char(smart_str *buf, int options, char c TSRMLS_DC) /* {{{ */ +{ + if (options & PHP_JSON_PRETTY_PRINT) { + smart_str_appendc(buf, c); + } +} +/* }}} */ + +static inline void json_pretty_print_indent(smart_str *buf, int options TSRMLS_DC) /* {{{ */ +{ + int i; + + if (options & PHP_JSON_PRETTY_PRINT) { + for (i = 0; i < JSON_G(encoder_depth); ++i) { + smart_str_appendl(buf, " ", 4); + } + } +} +/* }}} */ + +/* }}} */ + static void json_encode_array(smart_str *buf, zval **val, int options TSRMLS_DC) /* {{{ */ { int i, r; @@ -214,6 +240,9 @@ static void json_encode_array(smart_str *buf, zval **val, int options TSRMLS_DC) smart_str_appendc(buf, '{'); } + json_pretty_print_char(buf, options, '\n' TSRMLS_CC); + ++JSON_G(encoder_depth); + i = myht ? zend_hash_num_elements(myht) : 0; if (i > 0) @@ -241,10 +270,12 @@ static void json_encode_array(smart_str *buf, zval **val, int options TSRMLS_DC) if (r == PHP_JSON_OUTPUT_ARRAY) { if (need_comma) { smart_str_appendc(buf, ','); + json_pretty_print_char(buf, options, '\n' TSRMLS_CC); } else { need_comma = 1; } - + + json_pretty_print_indent(buf, options TSRMLS_CC); php_json_encode(buf, *data, options TSRMLS_CC); } else if (r == PHP_JSON_OUTPUT_OBJECT) { if (i == HASH_KEY_IS_STRING) { @@ -258,26 +289,36 @@ static void json_encode_array(smart_str *buf, zval **val, int options TSRMLS_DC) if (need_comma) { smart_str_appendc(buf, ','); + json_pretty_print_char(buf, options, '\n' TSRMLS_CC); } else { need_comma = 1; } + json_pretty_print_indent(buf, options TSRMLS_CC); + json_escape_string(buf, key, key_len - 1, options TSRMLS_CC); smart_str_appendc(buf, ':'); + json_pretty_print_char(buf, options, ' ' TSRMLS_CC); + php_json_encode(buf, *data, options TSRMLS_CC); } else { if (need_comma) { smart_str_appendc(buf, ','); + json_pretty_print_char(buf, options, '\n' TSRMLS_CC); } else { need_comma = 1; } + json_pretty_print_indent(buf, options TSRMLS_CC); + smart_str_appendc(buf, '"'); smart_str_append_long(buf, (long) index); smart_str_appendc(buf, '"'); smart_str_appendc(buf, ':'); + json_pretty_print_char(buf, options, ' ' TSRMLS_CC); + php_json_encode(buf, *data, options TSRMLS_CC); } } @@ -288,6 +329,10 @@ static void json_encode_array(smart_str *buf, zval **val, int options TSRMLS_DC) } } } + + --JSON_G(encoder_depth); + json_pretty_print_char(buf, options, '\n' TSRMLS_CC); + json_pretty_print_indent(buf, options TSRMLS_CC); if (r == PHP_JSON_OUTPUT_ARRAY) { smart_str_appendc(buf, ']'); diff --git a/ext/json/php_json.h b/ext/json/php_json.h index c321ad292a..7b1c7b72ff 100644 --- a/ext/json/php_json.h +++ b/ext/json/php_json.h @@ -38,6 +38,7 @@ extern zend_module_entry json_module_entry; #endif ZEND_BEGIN_MODULE_GLOBALS(json) + int encoder_depth; int error_code; ZEND_END_MODULE_GLOBALS(json) @@ -60,6 +61,7 @@ extern zend_class_entry *php_json_serializable_ce; #define PHP_JSON_FORCE_OBJECT (1<<4) #define PHP_JSON_NUMERIC_CHECK (1<<5) #define PHP_JSON_UNESCAPED_SLASHES (1<<6) +#define PHP_JSON_PRETTY_PRINT (1<<7) /* Internal flags */ #define PHP_JSON_OUTPUT_ARRAY 0 diff --git a/ext/json/tests/json_encode_pretty_print.phpt b/ext/json/tests/json_encode_pretty_print.phpt new file mode 100644 index 0000000000..43b93aafe6 --- /dev/null +++ b/ext/json/tests/json_encode_pretty_print.phpt @@ -0,0 +1,40 @@ +--TEST-- +json_encode() with JSON_PRETTY_PRINT +--SKIPIF-- + +--FILE-- + +--EXPECT-- +[ + 1, + 2, + 3, + [ + 1, + 2, + 3 + ] +] +Match: 1 +{ + "a": 1, + "b": [ + 1, + 2 + ], + "c": { + "d": 42 + } +} +Match: 1 -- 2.40.0