欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

mysqli 和 pdo 查询出来的类型转换

程序员文章站 2022-05-18 13:30:33
...
  1. 一直有一个问题,就是PHP用mysqli还是pdo,查询出来的结果都是int类型的数据会自动变成string类型,PHP本身弱类型。但是现在写api,直接从数据库里查出来的结果,然后json_encode 返回给客户端是不行的。java 和 oc 都是强类型 数字就是数字,字符串就是字符串。123 != "123"

这个是程序代码,用的mysqli类
mysqli 和 pdo 查询出来的类型转换

这个是表结构
mysqli 和 pdo 查询出来的类型转换

这个是查询 出来的结果
mysqli 和 pdo 查询出来的类型转换

  1. google 了好多说法,pdo倒是有解决的方法pdo查询int转换成string的问题。但是mysqli没找到,而且不知道这个究竟是什么问题。或者是有没有一些现成的类库,可以自动转换的。

回复内容:

  1. 一直有一个问题,就是PHP用mysqli还是pdo,查询出来的结果都是int类型的数据会自动变成string类型,PHP本身弱类型。但是现在写api,直接从数据库里查出来的结果,然后json_encode 返回给客户端是不行的。java 和 oc 都是强类型 数字就是数字,字符串就是字符串。123 != "123"

这个是程序代码,用的mysqli类
mysqli 和 pdo 查询出来的类型转换

这个是表结构
mysqli 和 pdo 查询出来的类型转换

这个是查询 出来的结果
mysqli 和 pdo 查询出来的类型转换

  1. google 了好多说法,pdo倒是有解决的方法pdo查询int转换成string的问题。但是mysqli没找到,而且不知道这个究竟是什么问题。或者是有没有一些现成的类库,可以自动转换的。

关闭模拟预处理时,能保持数据类型,但某些类型,输出的数据跟数据库里的值不一致:
比如float(9,2)类型的字段,字段内容为32.10,PDO关闭模拟预处理时读到的值为32.099998474121,类型为float.
也就是说开启PDO模拟预处理(默认),返回的数据类型都是string,值跟数据库存储的内容一致.
MySQL服务器没有使用预处理时,返回的是string类型的数据.

MySQLi不使用prepare查询返回的字段类型全部是string,值跟数据库存储的内容一致.
使用prepare时跟pdo_mysql关闭模拟预处理一样,返回对应类型的数据(decimal类型依旧是字符串),而且float类型的值也存在不一致.

所以,数据库中带有小数点的数据,建议使用字符串类型或decimal类型保存.

类型转换:
settype($foo, "array");
settype($foo, "bool");
settype($foo, "boolean");
settype($foo, "float");
settype($foo, "int");
settype($foo, "integer");
settype($foo, "null");
settype($foo, "object");
settype($foo, "string");
$foo = (array)$foo;
$foo = (b)$foo; // from PHP 5.2.1
$foo = (binary)$foo; // from PHP 5.2.1
$foo = (bool)$foo;
$foo = (boolean)$foo;
$foo = (double)$foo;
$foo = (float)$foo;
$foo = (int)$foo;
$foo = (integer)$foo;
$foo = (object)$foo;
$foo = (real)$foo;
$foo = (string)$foo;

可以用mysqli_result对象的fetch_field方法来获得字段的元数据。参见:PHP: mysqli_result::fetch_field - Manual。

相关方法还有fetch_fieldsfetch_field_direct

给个示例吧:

//获取到$result之后
$types = array();
while ( $finfo = $result->fetch_field() ) {
    if ( in_array( $finfo->type, array(
        MYSQLI_TYPE_BIT,
        MYSQLI_TYPE_TINY,
        MYSQLI_TYPE_SHORT,
        MYSQLI_TYPE_LONG,
        MYSQLI_TYPE_LONGLONG,
        MYSQLI_TYPE_INT24
    ) ) {
        $type = 'int';
    } else if ( in_array( $finfo->type, array( 
        MYSQLI_TYPE_FLOAT,
        MYSQLI_TYPE_DOUBLE,
        MYSQLI_TYPE_DECIMAL,
        MYSQLI_TYPE_NEWDECIMAL
     ) ) {
         $type = 'float';
     } else {
         //其他需要转换的类型请自行研究
         //类型常量请参见http://php.net/manual/zh/mysqli.constants.php,MYSQLI_TYPE开头的那些就是
         $type = 'string';
     }
     $types[$finfo->name] = $type;
}

$result = $result->fetch_assoc();

foreach ( $result as $name => &$value ) {
    settype($value, $types[$name]);
}

//现在$result里的数据类型已经符合要求了