使用正确的类型将mysql结果转换为json

时间:2015-02-01 10:14:27

标签: php mysql json

我知道如何获取mysql-row并将其转换为json:

$row = mysqli_fetch_assoc(mysqli_query($db, "SELECT * FROM table WHERE id=1"));
echo json_encode($row); // it's an ajax-call

但:

db-row有不同的类型,如int,float,string。 通过使用json_encode()转换它,所有结果都是字符串。

是否有更好的方法来纠正类型:

$row['floatvalue1'] = 0+$row['floatvalue1'];
$row['floatvalue2'] = 0+$row['floatvalue2'];
$row['intvalue1'] = 0+$row['intvalue1'];

我想循环键并添加0因为:

  • 第一个编码规则:DRY - 不要重复自己

但我不能因为:

  • 行还有其他类型而不是数字(字符串,日期)
  • 有很多列
  • 设计在dev中,因此列名经常更改

提前致谢并原谅我糟糕的英语: - )

编辑(回答Casimir et Hippolyte的评论问题):

我使用ajax调用这个php代码来获取动态的sql值。在我的javascript代码中,我使用如下结果:

result['intvalue1'] += 100;

假设intval1的json-result为50,计算结果为:

“50100”,而不是150

4 个答案:

答案 0 :(得分:9)

以下代码只是一个概念证明。它需要在函数/方法中进行封装,并在生产中使用它之前进行一些抛光(在循环中调用mysqli_fetch_field()并在处理任何行之前存储它返回的对象,而不是每行一次)。

它使用函数mysqli_fetch_field()来获取有关结果集的每一列的信息,并将那些具有数字类型的列转换为数字。 MYSQLI_TYPE_*常量的值可以在Mysqli predefined constants的文档页面中找到。

// Get the data
$result = mysqli_query($db, "SELECT * FROM table WHERE id=1");
$row    = mysqli_fetch_assoc($result);

// Fix the types    
$fixed = array();
foreach ($row as $key => $value) {
    $info = mysqli_fetch_field($result);
    if (in_array($info->type, array(
            MYSQLI_TYPE_TINY, MYSQLI_TYPE_SHORT, MYSQLI_TYPE_INT24,    
            MYSQLI_TYPE_LONG, MYSQLI_TYPE_LONGLONG,
            MYSQLI_TYPE_DECIMAL, 
            MYSQLI_TYPE_FLOAT, MYSQLI_TYPE_DOUBLE
    ))) {
        $fixed[$key] = 0 + $value;
    } else {
        $fixed[$key] = $value;
    }
}

// Compare the results
echo('all strings: '.json_encode($row)."\n");
echo('fixed types: '.json_encode($fixed)."\n");

答案 1 :(得分:0)

如果您只是想确保您的值可以根据其类型进行操作,则需要先正确投射其类型。

除非你需要服务器端,否则我会直接将json传递给前端并在那里完成工作。

在Javascript中,您可以尝试像这样编译数字:

function tryNumber(string){

    return !isNaN( parseInt(string) ) ? parseInt(string) : string;

}

function tryDate(string){

    return !isNaN( new Date(string).getTime() ) ? new Date(string) : string;

}

tryNumber('foo'); // "hello"
tryNumber('24'); // 24
tryDate('bar'); // "bar"
tryDate('December 17, 1995'); // "Sun Dec 17 1995 00:00:00 GMT+0000 (GMT)"

这两行试图将值转换为Date / Number。如果他们无法投票,他们将保持String

答案 2 :(得分:0)

类似

$row['floatvalue1'] = reset( sscanf ( $row['floatvalue1']  , "%f" ));
$row['floatvalue2'] = reset( sscanf ( $row['floatvalue2']  , "%f" ));
$row['intvalue1'] = reset( sscanf ( $row['intvalue1']  , "%d" ));
json_encode($row);

答案 3 :(得分:0)

一个基于@axiac答案的MySQLi OO版本,它生成一个包含所有记录的JSON数组($ jsnAll)。在此代码段中,调用了FixSQLType方法来修复一行。注意,应该将其包装在try {} catch {}块中,并且已经实例化了“ objMySQLi”:

         $lcAllRows = array();

         // Make an SQL SELECT statement 
         $SQL = "SELECT * FROM $lcName WHERE $lcWhere";

         // Run the query
         $this->sqlResult =  $this->objMySQLi->query($SQL);

         // Fetch the result
         while( $row = $this->sqlResult->fetch_assoc()){
             $lcCount = count($lcAllRows) ;

             // Call to fix, row 
             $fixedRow = $this->FixSQLType($row);
             $lcAllRows[$lcCount]= $fixedRow;
         }

         $jsnAll = json_encode($lcAllRows);

FixSQLType方法。除了对$ this-> sqlResult-> fetch_field_direct($ i)的调用外,这几乎与@axiac的答案相同。使用“ fetch_field_direct”克服了这个问题,“ fetch_field”似乎迷失了。

    private function FixSQLType($pRow){
    // FROM https://stackoverflow.com/a/28261996/7571029

    // Fix the types    
    $fixed = array();
    $i = 0;
    foreach ($pRow as $key => $value) {
        $info = $this->sqlResult->fetch_field_direct($i);
        $i++;

        if (in_array($info->type, array(
                MYSQLI_TYPE_TINY, MYSQLI_TYPE_SHORT, MYSQLI_TYPE_INT24,    
                MYSQLI_TYPE_LONG, MYSQLI_TYPE_LONGLONG,
                MYSQLI_TYPE_DECIMAL, 
                MYSQLI_TYPE_FLOAT, MYSQLI_TYPE_DOUBLE
        ))) {
            $fixed[$key] = 0 + $value;
        } else {
            $fixed[$key] = $value;
        }

    }

    return $fixed;
}