summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Harvey <aharvey@php.net>2010-09-16 16:21:15 +0000
committerAdam Harvey <aharvey@php.net>2010-09-16 16:21:15 +0000
commitcb9c8233fc2d3f30c704b8a96b774aae4559d8b0 (patch)
tree16ad474edcf7527247bc4a8ab7ba12a03ddef0cc
parentd8b8d22a0d1ae85b24beeab7707c2e4e8217ee07 (diff)
downloadphp-git-cb9c8233fc2d3f30c704b8a96b774aae4559d8b0.tar.gz
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. ;)
-rw-r--r--NEWS1
-rwxr-xr-xUPGRADING1
-rw-r--r--ext/json/json.c47
-rw-r--r--ext/json/php_json.h2
-rw-r--r--ext/json/tests/json_encode_pretty_print.phpt40
5 files changed, 90 insertions, 1 deletions
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--
+<?php if (!extension_loaded("json")) print "skip"; ?>
+--FILE--
+<?php
+function encode_decode($json) {
+ $struct = json_decode($json);
+ $pretty = json_encode($struct, JSON_PRETTY_PRINT);
+ echo "$pretty\n";
+ $pretty = json_decode($pretty);
+ printf("Match: %d\n", $pretty == $struct);
+}
+
+encode_decode('[1,2,3,[1,2,3]]');
+encode_decode('{"a":1,"b":[1,2],"c":{"d":42}}');
+?>
+--EXPECT--
+[
+ 1,
+ 2,
+ 3,
+ [
+ 1,
+ 2,
+ 3
+ ]
+]
+Match: 1
+{
+ "a": 1,
+ "b": [
+ 1,
+ 2
+ ],
+ "c": {
+ "d": 42
+ }
+}
+Match: 1