繁体   English   中英

PHP json_encode 将数字编码为字符串

[英]PHP json_encode encoding numbers as strings

我对 PHP json_encode 函数有一个问题。 它将数字编码为字符串,例如

array('id' => 3)

变成

"{ ["id": "3", ...)

当 js 遇到这些值时,它会将它们解释为字符串,并且对它们进行数字操作会失败。 有谁知道防止json_encode将数字编码为字符串的方法? 谢谢!

请注意,自PHP 5.3.3起, 有一个自动转换数字的标志 (在PHP 5.3.0中添加了options参数):

$arr = array( 'row_id' => '1', 'name' => 'George' );
echo json_encode( $arr, JSON_NUMERIC_CHECK ); // {"row_id":1,"name":"George"}

我,同样是从DB(PostgreSQL)读取,一切都是字符串。 我们遍历每一行并使用它来构建我们的最终结果数组,所以我使用了

$result_arr[] = array($db_row['name'], (int)$db_row['count']);

在循环内强制它为整数值。 当我现在执行json_encode($result_arr) ,它正确地将其格式化为数字。 这允许您控制来自数据库的数字和不是数字。

编辑:

json_encode()函数还可以使用JSON_NUMERIC_CHECK标志作为它的第二个参数动态执行此操作。 您需要小心使用它,但如文档中的此用户示例所示(复制如下): http//uk3.php.net/manual/en/function.json-encode.php#106641

<?php
// International phone number
json_encode(array('phone_number' => '+33123456789'), JSON_NUMERIC_CHECK);
?>

然后你得到这个JSON:

{"phone_number":33123456789}

我做了一个非常快速的测试:

$a = array(
    'id' => 152,
    'another' => 'test',
    'ananother' => 456,
);
$json = json_encode($a);
echo $json;

如果我没有弄错的话,这似乎就像你描述的那样?

我得到了输出:

{"id":152,"another":"test","ananother":456}

因此,在这种情况下,整数尚未转换为字符串。


不过,这可能取决于我们使用的PHP版本:已经纠正了几个与json_encode相关的错误,具体取决于PHP的版本...

这个测试是用PHP 5.2.6完成的; 我在PHP 5.2.9和5.3.0中得到了同样的东西; 我没有另外的5.2.x版本来测试,但:-(

您使用的是哪个版本的PHP? 或者您的测试用例比您发布的示例更复杂?

也许http://bugs.php.net/上的一个错误报告可能有关系? 例如, Bug#40503:json_encode整数转换与PHP不一致


也许Bug#38680也会引起你的兴趣, 顺便问一下?

我遇到了同样的问题(PHP-5.2.11 / Windows)。 我正在使用此解决方法

$json = preg_replace( "/\"(\d+)\"/", '$1', $json );

它用数字本身替换用引号括起来的所有(非负数,整数)数字('“42”'变成'42')。

另请参阅PHP手册中的此注释

尝试$arr = array('var1' => 100, 'var2' => 200);
$json = json_encode( $arr, JSON_NUMERIC_CHECK);
$arr = array('var1' => 100, 'var2' => 200);
$json = json_encode( $arr, JSON_NUMERIC_CHECK);

但它只适用于PHP 5.3.3。 看看这个PHP json_encode更改日志http://php.net/manual/en/function.json-encode.php#refsect1-function.json-encode-changelog

以下测试确认将类型更改为字符串会导致json_encode()将数字作为JSON字符串返回(即,用双引号括起来)。 使用settype(arr [“var”],“integer”)或settype($ arr [“var”],“float”)来修复它。

<?php

class testclass {
    public $foo = 1;
    public $bar = 2;
    public $baz = "Hello, world";
}

$testarr = array( 'foo' => 1, 'bar' => 2, 'baz' => 'Hello, world');

$json_obj_txt = json_encode(new testclass());
$json_arr_txt = json_encode($testarr);

echo "<p>Object encoding:</p><pre>" . $json_obj_txt . "</pre>";
echo "<p>Array encoding:</p><pre>" . $json_arr_txt . "</pre>";

// Both above return ints as ints. Type the int to a string, though, and...
settype($testarr["foo"], "string");
$json_arr_cast_txt = json_encode($testarr);
echo "<p>Array encoding w/ cast:</p><pre>" . $json_arr_cast_txt . "</pre>";

?>

所以Pascal MARTIN在这里没有得到足够的信任。 对于具有数百个服务器端功能的现有项目,检查每个JSON返回的数值是不可行的。

我用php-mysqlnd替换了php-mysql,问题就消失了。 数字是数字,字符串是字符串,布尔值是布尔值。

为了完整起见(因为我还无法添加评论),我还要将此细节添加为另一个答案:

(编辑:在意识到源数据(即在OP的情况下,数据库结果集)可能是问题(通过将数字列作为字符串返回)后读取,并且json_encode()实际上不是问题的根源)

mysql_fetch_array ”的手册页:

返回与获取的行对应的字符串数组

...和“ mysql_ fetch_ row ”:

返回与获取的行对应的数字字符串数组

明确指出; 返回数组中的条目将是字符串。

(我在phpBB2中使用了DB类(是的,我知道,它已经过时了!),并且该类的“sql_fetchrow()”方法使用“mysql_fetch_array()”)

没有意识到这一点,我也最终找到了这个问题,并理解了这个问题! :)

正如Pascal Martin在后续评论中所述,我相信一个解决方案可以解决源上的“错误类型”问题(即通过使用“ mysql_field_type() ”函数并在获取后立即执行转换,(或者其他获取方法,如“对象”?))一般会更好。

$rows = array();
while($r = mysql_fetch_assoc($result)) {
    $r["id"] = intval($r["id"]); 
    $rows[] = $r;
}
print json_encode($rows);  

这是php版本的问题,有同样的问题升级我的php版本到5.6解决了问题

将值转换为int或float似乎可以解决它。 例如:

$coordinates => array( 
    (float) $ap->latitude,
    (float) $ap->longitude 
);

如果出现任何问题,您可以使用(int)!! 它会工作正常。

我在处理数据库中的数据时遇到了同样的问题。 基本上问题是数组中要转换为json的类型被PHP识别为字符串而不是整数。 在我的情况下,我做了一个查询,从DB列计数行返回数据。 PDO驱动程序不将列识别为int,而是将其识别为字符串。 我通过在受影响的列中执行强制转换来解决问题。

我在 curl 发送 json 时遇到了这个问题,它需要一些字段是整数,而其他字段是字符串,但是字符串字段的一些值实际上是数字,所以 JSON_NUMERIC_CHECK 不起作用,因为它将所有看起来像数字的东西转换为数字。 我找到的解决方案是在表示字符串值的字段中添加代表未来双引号的字符,在我的情况下,我使用 @ 因为我知道在我的数据中不可能有这个字符

$analysis = array(

'SampleAnalysisId'  => $record[3],
'DisplayValue' => '@'.$record[4].'@',
'MeasurementUnit' => '@'.$record[5].'@',
'SampleAnalysisConclusionId'  => $record[6],
'Uncertaint' => '@'.$record[7].'@',
'K' => '',
'QuantificationLimit' => '@'.$record[8].'@',
'DetectionLimit' => '@'.$record[9].'@',
'Veff' => ''

);

然后在编码后,我将双引号替换为空,然后将“@”替换为双引号。

$str = json_encode($analysis,JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES );
$str = str_replace('@','"',str_replace('",',',',str_replace(':"',':',$str)));

根据我的需要生成格式化的json

[{"SampleAnalysisId":10479,"DisplayValue":"6,3","MeasurementUnit":"mg/L","SampleAnalysisConclusionId":1,"Uncertaint":"0,194463","K":,"QuantificationLimit":"1","DetectionLimit":"0,30","Veff":"}]

好吧,PHP json_encode()返回一个字符串。

您可以在js代码中使用parseFloat()或parseInt():

parseFloat('122.5'); // returns 122.5
parseInt('22'); // returns 22
parseInt('22.5'); // returns 22

只是遇到同样的问题,数据库将值作为字符串返回。

我用这个作为解决方法:

$a = array(
    'id' => $row['id'] * 1,
    'another' => ...,
    'ananother' => ...,
);
$json = json_encode($a);

即将该值乘以1以将其转换为数字

希望能帮助别人

json_encode序列化一些JSON格式的数据结构,以便通过网络发送。 因此,所有内容都是字符串类型。 就像从$ _POST或$ _GET收到一些参数一样。

如果必须对发送的值进行数值运算,只需将它们首先转换为int(使用PHP中的intval()函数或Javascript中的parseInt())然后执行操作。

就像oli_arborum说的那样,我认为你可以使用preg_replace来完成这项工作。 只需像这样更改命令:

$json = preg_replace('#:"(\d+)"#', ':$1', $json);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM