]> granicus.if.org Git - php/commitdiff
Added support for JSON_NUMERIC_CHECK option in json_encode() that converts
authorIlia Alshanetsky <iliaa@php.net>
Thu, 20 May 2010 19:37:52 +0000 (19:37 +0000)
committerIlia Alshanetsky <iliaa@php.net>
Thu, 20 May 2010 19:37:52 +0000 (19:37 +0000)
numeric strings to integers.

NEWS
ext/json/json.c
ext/json/php_json.h
ext/json/tests/json_encode_basic.phpt
ext/json/tests/json_encode_numeric.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 96b3e289412c4ca05a6d3eda43a1101f00f44490..fd5de867e4d31cf77a90cd5023954807bde8fa28 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -37,6 +37,8 @@
 - Added iterator support in MySQLi. mysqli_result implements Traversable.
   (Andrey, Johannes)
 - Added scalar typehinting. (Ilia, Derick)
+- Added support for JSON_NUMERIC_CHECK option in json_encode() that converts 
+  numeric strings to integers. (Ilia)
 
 - default_charset if not specified is now UTF-8 instead of ISO-8859-1. (Rasmus)
 
index 069ad3d21ab0239d718a7112915a818b7230aacc..93445d6b65213fce5820f12f7dbd7895a6c91fae 100644 (file)
@@ -40,15 +40,6 @@ static const char digits[] = "0123456789abcdef";
 
 zend_class_entry *php_json_serializable_ce;
 
-#define PHP_JSON_HEX_TAG       (1<<0)
-#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_OBJECT  (1<<4)
-
-#define PHP_JSON_OUTPUT_ARRAY 0
-#define PHP_JSON_OUTPUT_OBJECT 1
-
 ZEND_DECLARE_MODULE_GLOBALS(json)
 
 /* {{{ arginfo */
@@ -99,6 +90,7 @@ static PHP_MINIT_FUNCTION(json)
        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_NUMERIC_CHECK", PHP_JSON_NUMERIC_CHECK, 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);
@@ -312,6 +304,30 @@ static void json_escape_string(smart_str *buf, char *s, int len, int options TSR
                return;
        }
 
+       if (options & PHP_JSON_NUMERIC_CHECK) {
+               double d;
+               int type;
+               long p;
+
+               if ((type = is_numeric_string(s, len, &p, &d, 0)) != 0) {
+                       if (type == IS_LONG) {
+                               smart_str_append_long(buf, p);
+                       } else if (type == IS_DOUBLE) {
+                               if (!zend_isinf(d) && !zend_isnan(d)) {
+                                       char *tmp;
+                                       int l = spprintf(&tmp, 0, "%.*k", (int) EG(precision), d);
+                                       smart_str_appendl(buf, tmp, l);
+                                       efree(tmp);
+                               } else {
+                                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "double %.9g does not conform to the JSON spec, encoded as 0", d);
+                                       smart_str_appendc(buf, '0');
+                               }
+                       }
+                       return;
+               }
+               
+       }
+
        utf16 = (unsigned short *) safe_emalloc(len, sizeof(unsigned short), 0);
 
        len = utf8_to_utf16(utf16, s, len);
@@ -496,7 +512,7 @@ PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_
                                        smart_str_appendl(buf, d, len);
                                        efree(d);
                                } else {
-                                       zend_error(E_WARNING, "[json] (php_json_encode) double %.9g does not conform to the JSON spec, encoded as 0", dbl);
+                                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "double %.9g does not conform to the JSON spec, encoded as 0", dbl);
                                        smart_str_appendc(buf, '0');
                                }
                        }
@@ -517,7 +533,7 @@ PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_
                        break;
 
                default:
-                       zend_error(E_WARNING, "[json] (php_json_encode) type is unsupported, encoded as null");
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "type is unsupported, encoded as null");
                        smart_str_appendl(buf, "null", 4);
                        break;
        }
index f769020e0361e810cb683747b39ec2f891b16f33..5ff8d1be03429638a08ffee724e88a1981421209 100644 (file)
@@ -51,6 +51,16 @@ PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_
 PHP_JSON_API void php_json_decode(zval *return_value, char *str, int str_len, zend_bool assoc, long depth TSRMLS_DC);
 extern zend_class_entry *php_json_serializable_ce;
 
+#define PHP_JSON_HEX_TAG       (1<<0)
+#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_OBJECT  (1<<4)
+#define PHP_JSON_NUMERIC_CHECK (1<<5)
+
+#define PHP_JSON_OUTPUT_ARRAY 0
+#define PHP_JSON_OUTPUT_OBJECT 1
+
 #endif  /* PHP_JSON_H */
 
 /*
index 4124d06588782dc2b6b7c1d2429c3be972ed88e1..152e24444c00836775f1450064ab83ab7864637c 100644 (file)
@@ -151,7 +151,7 @@ string(4) "null"
 string(4) "null"
 -- Iteration 26 --
 
-Warning: [json] (php_json_encode) type is unsupported, encoded as null in %s on line %d
+Warning: json_encode(): type is unsupported, encoded as null in %s on line %d
 string(4) "null"
 -- Iteration 27 --
 string(82) "{"MyInt":99,"MyFloat":123.45,"MyBool":true,"MyNull":null,"MyString":"Hello World"}"
diff --git a/ext/json/tests/json_encode_numeric.phpt b/ext/json/tests/json_encode_numeric.phpt
new file mode 100644 (file)
index 0000000..5392350
--- /dev/null
@@ -0,0 +1,26 @@
+--TEST--
+Test json_encode() function with numeric flag
+--SKIPIF--
+<?php
+if (!extension_loaded("json")) {
+       die('skip JSON extension not available in this build');
+}       
+?>
+--FILE--
+<?php
+var_dump(
+       json_encode("1", JSON_NUMERIC_CHECK),
+       json_encode("9.4324", JSON_NUMERIC_CHECK),
+       json_encode(array("122321", "3232595.33423"), JSON_NUMERIC_CHECK),
+       json_encode("1"),
+       json_encode("9.4324"),
+       json_encode(array("122321", "3232595.33423"))
+);
+?>
+--EXPECT--
+string(1) "1"
+string(6) "9.4324"
+string(22) "[122321,3232595.33423]"
+string(3) ""1""
+string(8) ""9.4324""
+string(26) "["122321","3232595.33423"]"