Skip to content

Commit ea3a653

Browse files
author
Ilia Alshanetsky
committed
Added support for JSON_NUMERIC_CHECK option in json_encode() that converts
numeric strings to integers.
1 parent 3bdc751 commit ea3a653

File tree

4 files changed

+41
-13
lines changed

4 files changed

+41
-13
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ PHP NEWS
44
- Upgraded bundled sqlite to version 3.6.23.1. (Ilia)
55
- Upgraded bundled PCRE to version 8.02. (Ilia)
66

7+
- Added support for JSON_NUMERIC_CHECK option in json_encode() that converts
8+
numeric strings to integers. (Ilia)
79
- Added stream_set_read_buffer, allows to set the buffer for read operation.
810
(Pierre).
911
- Added stream filter support to mcrypt extension (ported from

ext/json/json.c

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,6 @@ static PHP_FUNCTION(json_last_error);
3737

3838
static const char digits[] = "0123456789abcdef";
3939

40-
#define PHP_JSON_HEX_TAG (1<<0)
41-
#define PHP_JSON_HEX_AMP (1<<1)
42-
#define PHP_JSON_HEX_APOS (1<<2)
43-
#define PHP_JSON_HEX_QUOT (1<<3)
44-
#define PHP_JSON_FORCE_OBJECT (1<<4)
45-
46-
#define PHP_JSON_OUTPUT_ARRAY 0
47-
#define PHP_JSON_OUTPUT_OBJECT 1
48-
4940
ZEND_DECLARE_MODULE_GLOBALS(json)
5041

5142
/* {{{ arginfo */
@@ -81,6 +72,7 @@ static PHP_MINIT_FUNCTION(json)
8172
REGISTER_LONG_CONSTANT("JSON_HEX_APOS", PHP_JSON_HEX_APOS, CONST_CS | CONST_PERSISTENT);
8273
REGISTER_LONG_CONSTANT("JSON_HEX_QUOT", PHP_JSON_HEX_QUOT, CONST_CS | CONST_PERSISTENT);
8374
REGISTER_LONG_CONSTANT("JSON_FORCE_OBJECT", PHP_JSON_FORCE_OBJECT, CONST_CS | CONST_PERSISTENT);
75+
REGISTER_LONG_CONSTANT("JSON_NUMERIC_CHECK", PHP_JSON_NUMERIC_CHECK, CONST_CS | CONST_PERSISTENT);
8476

8577
REGISTER_LONG_CONSTANT("JSON_ERROR_NONE", PHP_JSON_ERROR_NONE, CONST_CS | CONST_PERSISTENT);
8678
REGISTER_LONG_CONSTANT("JSON_ERROR_DEPTH", PHP_JSON_ERROR_DEPTH, CONST_CS | CONST_PERSISTENT);
@@ -294,6 +286,30 @@ static void json_escape_string(smart_str *buf, char *s, int len, int options TSR
294286
return;
295287
}
296288

289+
if (options & PHP_JSON_NUMERIC_CHECK) {
290+
double d;
291+
int type;
292+
long p;
293+
294+
if ((type = is_numeric_string(s, len, &p, &d, 0)) != 0) {
295+
if (type == IS_LONG) {
296+
smart_str_append_long(buf, p);
297+
} else if (type == IS_DOUBLE) {
298+
if (!zend_isinf(d) && !zend_isnan(d)) {
299+
char *tmp;
300+
int l = spprintf(&tmp, 0, "%.*k", (int) EG(precision), d);
301+
smart_str_appendl(buf, tmp, l);
302+
efree(tmp);
303+
} else {
304+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "double %.9g does not conform to the JSON spec, encoded as 0", d);
305+
smart_str_appendc(buf, '0');
306+
}
307+
}
308+
return;
309+
}
310+
311+
}
312+
297313
utf16 = (unsigned short *) safe_emalloc(len, sizeof(unsigned short), 0);
298314

299315
len = utf8_to_utf16(utf16, s, len);
@@ -445,7 +461,7 @@ PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_
445461
smart_str_appendl(buf, d, len);
446462
efree(d);
447463
} else {
448-
zend_error(E_WARNING, "[json] (php_json_encode) double %.9g does not conform to the JSON spec, encoded as 0", dbl);
464+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "double %.9g does not conform to the JSON spec, encoded as 0", dbl);
449465
smart_str_appendc(buf, '0');
450466
}
451467
}
@@ -461,7 +477,7 @@ PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_
461477
break;
462478

463479
default:
464-
zend_error(E_WARNING, "[json] (php_json_encode) type is unsupported, encoded as null");
480+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "type is unsupported, encoded as null");
465481
smart_str_appendl(buf, "null", 4);
466482
break;
467483
}

ext/json/php_json.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@ ZEND_END_MODULE_GLOBALS(json)
5050
PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_DC);
5151
PHP_JSON_API void php_json_decode(zval *return_value, char *str, int str_len, zend_bool assoc, long depth TSRMLS_DC);
5252

53+
#define PHP_JSON_HEX_TAG (1<<0)
54+
#define PHP_JSON_HEX_AMP (1<<1)
55+
#define PHP_JSON_HEX_APOS (1<<2)
56+
#define PHP_JSON_HEX_QUOT (1<<3)
57+
#define PHP_JSON_FORCE_OBJECT (1<<4)
58+
#define PHP_JSON_NUMERIC_CHECK (1<<5)
59+
60+
#define PHP_JSON_OUTPUT_ARRAY 0
61+
#define PHP_JSON_OUTPUT_OBJECT 1
62+
5363
#endif /* PHP_JSON_H */
5464

5565
/*

ext/json/tests/json_encode_basic.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,8 @@ string(4) "null"
151151
string(4) "null"
152152
-- Iteration 26 --
153153

154-
Warning: [json] (php_json_encode) type is unsupported, encoded as null in %s on line %d
154+
Warning: json_encode(): type is unsupported, encoded as null in %s on line %d
155155
string(4) "null"
156156
-- Iteration 27 --
157157
string(82) "{"MyInt":99,"MyFloat":123.45,"MyBool":true,"MyNull":null,"MyString":"Hello World"}"
158-
===Done===
158+
===Done===

0 commit comments

Comments
 (0)