数据库中的 JSON 编码浮点数是否应该用引号引起来?

发布于 2024-10-25 08:53:23 字数 851 浏览 3 评论 0原文

我有以下代码:

$stmt = $db->prepare("SELECT LATITUDE, LONGITUDE FROM NODEGEOLOCATION WHERE NODEID = $i");
$stmt->execute();
$path[] = $stmt->fetch(PDO::FETCH_ASSOC);

并且我使用 json_encode 将其转换为 JSON 格式。但是,我收到以下 JSON:

[{"route":[{"LATITUDE":"32.224519","LONGITUDE":"-110.947325"},{"LATITUDE":"32.227820","LONGITUDE":"-110.947293"},{"LATITUDE":"32.227843","LONGITUDE":"-110.943865"},{"LATITUDE":"32.230618","LONGITUDE":"-110.943919"},{"LATITUDE":"32.231755","LONGITUDE":"-110.943927"},{"LATITUDE":"32.233836","LONGITUDE":"-110.943963"},{"LATITUDE":"32.233850","LONGITUDE":"-110.946061"},{"LATITUDE":"32.236035","LONGITUDE":"-110.946061"},{"LATITUDE":"32.235993","LONGITUDE":"-110.948083"},{"LATITUDE":"32.235977","LONGITUDE":"-110.952433"}]

我不希望 LATITUDE 和 LONGITUDE 的值括在引号中。这可能吗?

I have the following code:

$stmt = $db->prepare("SELECT LATITUDE, LONGITUDE FROM NODEGEOLOCATION WHERE NODEID = $i");
$stmt->execute();
$path[] = $stmt->fetch(PDO::FETCH_ASSOC);

and I use json_encode to convert this to a JSON format. However, I am getting the following JSON:

[{"route":[{"LATITUDE":"32.224519","LONGITUDE":"-110.947325"},{"LATITUDE":"32.227820","LONGITUDE":"-110.947293"},{"LATITUDE":"32.227843","LONGITUDE":"-110.943865"},{"LATITUDE":"32.230618","LONGITUDE":"-110.943919"},{"LATITUDE":"32.231755","LONGITUDE":"-110.943927"},{"LATITUDE":"32.233836","LONGITUDE":"-110.943963"},{"LATITUDE":"32.233850","LONGITUDE":"-110.946061"},{"LATITUDE":"32.236035","LONGITUDE":"-110.946061"},{"LATITUDE":"32.235993","LONGITUDE":"-110.948083"},{"LATITUDE":"32.235977","LONGITUDE":"-110.952433"}]

I don't want the value of LATITUDE and LONGITUDE to be enclosed in quotes. Is this even possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烂柯人 2024-11-01 08:53:24

看起来 PDO 总是 以字符串形式返回数据库结果,即使它们是数字或浮点数。

PHP 的 JSON 编码器不执行任何类型嗅探:如果值保存在 PHP 字符串中,则会将其放在引号中,即使它可以表示为整数或浮点数。

您可以通过两种方式处理这个问题。

  1. 在使用 json_encode 之前将值明确转换为浮点数。
  2. 在使用 JSON 之前,请更改 JSON 的使用者以将值转换为浮点数。

下面是一个基于 getColumnMeta 自动转换的示例。首先,我们创建一个虚拟数据库并插入一些数据。

php > $pdo = new PDO('sqlite::memory:');
php > $pdo->exec('create table foo(a integer, b float, c text)');
php > $sh = $pdo->prepare('insert into foo(a, b, c) values(?, ?, ?)');
php > $sh->execute(array(1, 2.2, 'Three'));
php > $sh->execute(array(4, 5.55, 'Six'));
php > $sh->execute(array(7, 88.888, 'Nine'));

现在,我们将在演示中证明数据存在:

php > $sh = $pdo->prepare('select * from foo where a = 4');
php > $sh->execute();
php > $row = $sh->fetch(PDO::FETCH_ASSOC);
php > var_dump($row);
array(3) {
  ["a"]=>
  string(1) "4"
  ["b"]=>
  string(4) "5.55"
  ["c"]=>
  string(3) "Six"
}

让我们看看 PDO 将告诉我们有关第一列的信息。

php > print_r($sh->getColumnMeta(0));
Array
(
    [native_type] => integer
    [sqlite:decl_type] => integer
    [flags] => Array
        (
        )

    [name] => a
    [len] => 4294967295
    [precision] => 0
    [pdo_type] => 2
)

美丽的。我也对第 1 列和第 2 列执行了此操作,分别返回“double”和“string”。现在让我们构建一个列名映射来输入:

php > $cols = count($row);
php > $col_types = array(); 
php > while($cols-- > 0) { 
          $col_info = $sh->getColumnMeta($cols);
          $col_types[ $col_info['name'] ] = $col_info['native_type']; 
      }
php > print_r($col_types);
Array
(
    [c] => string
    [b] => double
    [a] => integer
)

是的,它是相反的,没关系!现在让我们转换行。

php > foreach($row as $k => $v) {
          if($col_types[$k] == 'double')
              $row[$k] = (float)$v;
          if($col_types[$k] == 'integer')
              $row[$k] = (int)$v;
      }
php > var_dump($row);
array(3) {
  ["a"]=>
  int(4)
  ["b"]=>
  float(5.55)
  ["c"]=>
  string(3) "Six"
}
php > echo json_encode($row);
{"a":4,"b":5.55,"c":"Six"}

田田!您可能想要用一种方便的方法来包装它,每次都手动完成有点麻烦。我还可以使用 columnCount 来获取结果集而不是计数$row


杀伤力大吗?这是一个未经测试的示例,它针对特定的列名称并在此过程中手动构建哈希数组。

$results = array();
$convert_columns = array( 'b' );
$sh = $pdo->prepare('select * from foo where a = 1');
$sh->execute();
while($row = $sh->fetch(PDO::FETCH_ASSOC)) {
    foreach($convert_columns as $colname)
        $row[$colname] = (float)$row[$colname];
    $results[] = $row;
}

It looks like PDO always returns database results as strings, even when they are numbers or floats.

PHP's JSON encoder doesn't perform any variety of type sniffing: if the value is held in a PHP string, it gets put in quotes, even if it could be represented as an integer or float.

You can deal with this in two ways.

  1. Expressly cast the value to a float before using json_encode.
  2. Alter the consumer of the JSON to cast the value to a float before working with it.

Here's an example of automatic casting based on getColumnMeta. First let's create a dummy database and insert some data.

php > $pdo = new PDO('sqlite::memory:');
php > $pdo->exec('create table foo(a integer, b float, c text)');
php > $sh = $pdo->prepare('insert into foo(a, b, c) values(?, ?, ?)');
php > $sh->execute(array(1, 2.2, 'Three'));
php > $sh->execute(array(4, 5.55, 'Six'));
php > $sh->execute(array(7, 88.888, 'Nine'));

Now we'll prove that the data is there, for our demo:

php > $sh = $pdo->prepare('select * from foo where a = 4');
php > $sh->execute();
php > $row = $sh->fetch(PDO::FETCH_ASSOC);
php > var_dump($row);
array(3) {
  ["a"]=>
  string(1) "4"
  ["b"]=>
  string(4) "5.55"
  ["c"]=>
  string(3) "Six"
}

Let's see what PDO will tell us about the first column.

php > print_r($sh->getColumnMeta(0));
Array
(
    [native_type] => integer
    [sqlite:decl_type] => integer
    [flags] => Array
        (
        )

    [name] => a
    [len] => 4294967295
    [precision] => 0
    [pdo_type] => 2
)

Beautiful. I did this for columns 1 and 2 as well, which returned "double" and "string" respectively. Now let's build a map of column name to type:

php > $cols = count($row);
php > $col_types = array(); 
php > while($cols-- > 0) { 
          $col_info = $sh->getColumnMeta($cols);
          $col_types[ $col_info['name'] ] = $col_info['native_type']; 
      }
php > print_r($col_types);
Array
(
    [c] => string
    [b] => double
    [a] => integer
)

Yeah, it's in reverse, doesn't matter! Now let's convert our row.

php > foreach($row as $k => $v) {
          if($col_types[$k] == 'double')
              $row[$k] = (float)$v;
          if($col_types[$k] == 'integer')
              $row[$k] = (int)$v;
      }
php > var_dump($row);
array(3) {
  ["a"]=>
  int(4)
  ["b"]=>
  float(5.55)
  ["c"]=>
  string(3) "Six"
}
php > echo json_encode($row);
{"a":4,"b":5.55,"c":"Six"}

Tada! You're probably going to want to wrap this in a convenience method, it's a bit hairy to do every single time by hand. I could also have used columnCount to get the number of columns in the result set rather than counting $row.


Overkill much? Here's an untested example that targets the specific column names and builds the array of hashes by hand in the process.

$results = array();
$convert_columns = array( 'b' );
$sh = $pdo->prepare('select * from foo where a = 1');
$sh->execute();
while($row = $sh->fetch(PDO::FETCH_ASSOC)) {
    foreach($convert_columns as $colname)
        $row[$colname] = (float)$row[$colname];
    $results[] = $row;
}
酸甜透明夹心 2024-11-01 08:53:24

我相信这取决于它们在数据库中的类型。

如果它们是数据库中的 varchar 或 string,则它们将被视为字符串。

如果它们是 FLOATDOUBLE 的,则它们不应该有引号。

It depends on their type in the database I believe.

If they are varchars or string in the database they are treated as strings.

If they are FLOAT's DOUBLE's, they shouldn't have quotes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文