ID: 46363
Updated by: [EMAIL PROTECTED]
Reported By: 191919 at gmail dot com
Status: Open
Bug Type: Feature/Change Request
Operating System: *
PHP Version: 5.2.6
New Comment:
As a workaround you can always change the precision:
C:\php\src>php -r "var_dump(json_decode('{\"a\":
1232487234.97323948}'));"
object(stdClass)#1 (1) {
["a"]=>
float(1232487234.9732)
}
C:\php\src>php -d precision=24 -r "var_dump(json_decode('{\"a\":
1232487234.9732
3948}'));"
object(stdClass)#1 (1) {
["a"]=>
float(1232487234.97323942184448)
}
:), but I would still like a feature like this
Previous Comments:
------------------------------------------------------------------------
[2008-10-22 10:17:37] 191919 at gmail dot com
New patch
---
diff -u json_old/JSON_parser.c json/JSON_parser.c
--- json_old/JSON_parser.c 2007-06-14 01:56:41.000000000 +0800
+++ json/JSON_parser.c 2008-10-22 18:10:26.000000000 +0800
@@ -278,10 +278,15 @@
}
-static void json_create_zval(zval **z, smart_str *buf, int type)
+static void json_create_zval(zval **z, smart_str *buf, int type, int
num_as_string)
{
ALLOC_INIT_ZVAL(*z);
+ if (num_as_string && (type == IS_LONG || type == IS_DOUBLE))
+ {
+ type = IS_STRING;
+ }
+
if (type == IS_LONG)
{
double d = zend_strtod(buf->c, NULL);
@@ -399,7 +404,7 @@
machine with a stack.
*/
int
-JSON_parser(zval *z, unsigned short p[], int length, int assoc
TSRMLS_DC)
+JSON_parser(zval *z, unsigned short p[], int length, int assoc, int
num_as_string TSRMLS_DC)
{
int b; /* the next character */
int c; /* the next character class */
@@ -501,7 +506,7 @@
zval *mval;
smart_str_0(&buf);
- json_create_zval(&mval, &buf, type);
+ json_create_zval(&mval, &buf, type,
num_as_string);
if (!assoc)
{
@@ -573,7 +578,7 @@
zval *mval;
smart_str_0(&buf);
- json_create_zval(&mval, &buf, type);
+ json_create_zval(&mval, &buf, type,
num_as_string);
add_next_index_zval(JSON(the_zstack)[JSON(the_top)], mval);
buf.len = 0;
JSON_RESET_TYPE();
@@ -626,7 +631,7 @@
JSON(the_stack[JSON(the_top)]) == MODE_ARRAY))
{
smart_str_0(&buf);
- json_create_zval(&mval, &buf, type);
+ json_create_zval(&mval, &buf, type,
num_as_string);
}
switch (JSON(the_stack)[JSON(the_top)]) {
diff -u json/JSON_parser.h json/JSON_parser.h
--- json_old/JSON_parser.h 2006-07-20 00:17:15.000000000 +0800
+++ json/JSON_parser.h 2008-10-22 16:32:56.000000000 +0800
@@ -3,4 +3,4 @@
#include "php.h"
#include "ext/standard/php_smart_str.h"
-extern int JSON_parser(zval *z, unsigned short p[], int length, int
assoc TSRMLS_DC);
+extern int JSON_parser(zval *z, unsigned short p[], int length, int
assoc, int num_as_string TSRMLS_DC);
diff -u json/json.c json/json.c
--- json_old/json.c 2007-12-31 15:20:07.000000000 +0800
+++ json/json.c 2008-10-22 16:33:53.000000000 +0800
@@ -411,10 +411,11 @@
char *parameter;
int parameter_len, utf16_len;
zend_bool assoc = 0; /* return JS objects as PHP objects by
default */
+ zend_bool num_as_string = 0; /* don't decode integers and doubles
as strings */
zval *z;
unsigned short *utf16;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b",
¶meter, ¶meter_len, &assoc) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bb",
¶meter, ¶meter_len, &assoc, &num_as_string) == FAILURE) {
return;
}
@@ -437,7 +438,7 @@
}
ALLOC_INIT_ZVAL(z);
- if (JSON_parser(z, utf16, utf16_len, assoc TSRMLS_CC))
+ if (JSON_parser(z, utf16, utf16_len, assoc, num_as_string
TSRMLS_CC))
{
*return_value = *z;
------------------------------------------------------------------------
[2008-10-22 08:57:16] 191919 at gmail dot com
Description:
------------
json_decode lacks a 'num_as_string' feature. I made a patch which adds
a third optional 'num_as_string' parameter to json_decode to force it to
decode all numbers as strings.
diff -u json_orig/JSON_parser.c json/JSON_parser.c
--- json_orig/JSON_parser.c 2007-06-14 01:56:41.000000000 +0800
+++ json/JSON_parser.c 2008-10-22 16:33:32.000000000 +0800
@@ -278,10 +278,15 @@
}
-static void json_create_zval(zval **z, smart_str *buf, int type)
+static void json_create_zval(zval **z, smart_str *buf, int type, int
num_as_string)
{
ALLOC_INIT_ZVAL(*z);
+ if (num_as_string)
+ {
+ type = IS_STRING;
+ }
+
if (type == IS_LONG)
{
double d = zend_strtod(buf->c, NULL);
@@ -399,7 +404,7 @@
machine with a stack.
*/
int
-JSON_parser(zval *z, unsigned short p[], int length, int assoc
TSRMLS_DC)
+JSON_parser(zval *z, unsigned short p[], int length, int assoc, int
num_as_string TSRMLS_DC)
{
int b; /* the next character */
int c; /* the next character class */
@@ -501,7 +506,7 @@
zval *mval;
smart_str_0(&buf);
- json_create_zval(&mval, &buf, type);
+ json_create_zval(&mval, &buf, type,
num_as_string);
if (!assoc)
{
@@ -573,7 +578,7 @@
zval *mval;
smart_str_0(&buf);
- json_create_zval(&mval, &buf, type);
+ json_create_zval(&mval, &buf, type,
num_as_string);
add_next_index_zval(JSON(the_zstack)[JSON(the_top)], mval);
buf.len = 0;
JSON_RESET_TYPE();
@@ -626,7 +631,7 @@
JSON(the_stack[JSON(the_top)]) == MODE_ARRAY))
{
smart_str_0(&buf);
- json_create_zval(&mval, &buf, type);
+ json_create_zval(&mval, &buf, type,
num_as_string);
}
switch (JSON(the_stack)[JSON(the_top)]) {
diff -u json/JSON_parser.h json/JSON_parser.h
--- json_orig/JSON_parser.h 2006-07-20 00:17:15.000000000 +0800
+++ json/JSON_parser.h 2008-10-22 16:32:56.000000000 +0800
@@ -3,4 +3,4 @@
#include "php.h"
#include "ext/standard/php_smart_str.h"
-extern int JSON_parser(zval *z, unsigned short p[], int length, int
assoc TSRMLS_DC);
+extern int JSON_parser(zval *z, unsigned short p[], int length, int
assoc, int num_as_string TSRMLS_DC);
diff -u json/json.c json/json.c
--- json_orig/json.c 2007-12-31 15:20:07.000000000 +0800
+++ json/json.c 2008-10-22 16:33:53.000000000 +0800
@@ -411,10 +411,11 @@
char *parameter;
int parameter_len, utf16_len;
zend_bool assoc = 0; /* return JS objects as PHP objects by
default */
+ zend_bool num_as_string = 0; /* don't decode integers and doubles
as strings */
zval *z;
unsigned short *utf16;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b",
¶meter, ¶meter_len, &assoc) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bb",
¶meter, ¶meter_len, &assoc, &num_as_string) == FAILURE) {
return;
}
@@ -437,7 +438,7 @@
}
ALLOC_INIT_ZVAL(z);
- if (JSON_parser(z, utf16, utf16_len, assoc TSRMLS_CC))
+ if (JSON_parser(z, utf16, utf16_len, assoc, num_as_string
TSRMLS_CC))
{
*return_value = *z;
Reproduce code:
---------------
<?
$json = '{"a":1232487234.97323948}';
var_dump(json_decode($json, true));
?>
Expected result:
----------------
array(1) {
["a"]=>
string(19) "1232487234.97323948"
}
Actual result:
--------------
array(1) {
["a"]=>
float(1232487234.9732)
}
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=46363&edit=1