Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL整数字段在PHP中以字符串形式返回_Php_Mysql_Types_Int_Gettype - Fatal编程技术网

MySQL整数字段在PHP中以字符串形式返回

MySQL整数字段在PHP中以字符串形式返回,php,mysql,types,int,gettype,Php,Mysql,Types,Int,Gettype,我在MySQL数据库中有一个表字段: userid INT(11) 因此,我通过以下查询将其调用到我的页面: "SELECT userid FROM DB WHERE name='john'" 然后,为了处理结果,我会: $row=$result->fetch_assoc(); $id=$row['userid']; 现在如果我这样做: echo gettype($id); 我得到一根绳子。这不是一个整数吗?当您使用PHP从MySQL数据库中选择数据时,数据类型将始终转换为字符串

我在MySQL数据库中有一个表字段:

userid INT(11)
因此,我通过以下查询将其调用到我的页面:

"SELECT userid FROM DB WHERE name='john'"
然后,为了处理结果,我会:

$row=$result->fetch_assoc();

$id=$row['userid'];
现在如果我这样做:

echo gettype($id);

我得到一根绳子。这不是一个整数吗?

当您使用PHP从MySQL数据库中选择数据时,数据类型将始终转换为字符串。可以使用以下代码将其转换回整数:

$id = (int) $row['userid'];
或者使用函数
intval()


不需要。不管表中定义的数据类型如何,PHP的MySQL驱动程序总是将行值作为字符串提供

您需要将ID转换为int

$row = $result->fetch_assoc();
$id = (int) $row['userid'];
$row = $result->fetch_assoc();
$id = (int) $row['userid'];

在我的项目中,我通常使用一个外部函数来“过滤”通过
mysql\u fetch\u assoc
检索的数据

您可以重命名表中的字段,以便直观地了解存储的数据类型

例如,可以为每个数字字段添加特殊后缀: 如果
userid
INT(11)
可以重命名
userid\u i
或者如果它是
未签名INT(11)
可以重命名
userid\u

此时,您可以编写一个简单的PHP函数,接收关联数组作为输入(使用mysql\u fetch\u assoc检索),并对使用这些特殊“键”存储的“值”应用强制转换

  • …取决于要使用的扩展名。不推荐使用第一种,因为mysql扩展已不推荐使用。第三个仍然是实验性的

    这些超链接上的注释很好地解释了如何将您的类型从普通的旧字符串设置为数据库中的原始类型

    一些框架也对此进行了抽象(CodeIgniter提供)

    您还可以进行猜测——比如循环遍历生成的行并在每个行上使用。比如:

    foreach($result as &$row){
     foreach($row as &$value){
      if(is_numeric($value)){
       $value = (int) $value;
      }       
     }       
    }
    

    这将把任何看起来像一个数字的东西变成一…绝对不是完美的。

    如果使用准备好的语句,类型将在适当的地方为int。这段代码返回一个行数组,其中每一行都是一个关联数组。例如,如果为所有行调用了
    fetch\u assoc()
    ,但保留了类型信息

    function dbQuery($sql) {
        global $mysqli;
    
        $stmt = $mysqli->prepare($sql);
        $stmt->execute();
        $stmt->store_result();
    
        $meta = $stmt->result_metadata();
        $params = array();
        $row = array();
    
        while ($field = $meta->fetch_field()) {
          $params[] = &$row[$field->name];
        }
    
        call_user_func_array(array($stmt, 'bind_result'), $params);
    
        while ($stmt->fetch()) {
          $tmp = array();
          foreach ($row as $key => $val) {
            $tmp[$key] = $val;
          }
          $ret[] = $tmp;
        }
    
        $meta->free();
        $stmt->close();
    
        return $ret;
    }
    

    我的解决方案是传递查询结果
    $rs
    ,并获得一个casted数据的assoc数组作为返回:

    function cast_query_results($rs) {
        $fields = mysqli_fetch_fields($rs);
        $data = array();
        $types = array();
        foreach($fields as $field) {
            switch($field->type) {
                case 3:
                    $types[$field->name] = 'int';
                    break;
                case 4:
                    $types[$field->name] = 'float';
                    break;
                default:
                    $types[$field->name] = 'string';
                    break;
            }
        }
        while($row=mysqli_fetch_assoc($rs)) array_push($data,$row);
        for($i=0;$i<count($data);$i++) {
            foreach($types as $name => $type) {
                settype($data[$i][$name], $type);
            }
        }
        return $data;
    }
    
    使用php的mysqlnd(本机驱动程序)

    如果你在Ubuntu上:

    sudo apt-get install php5-mysqlnd
    sudo service apache2 restart
    
    如果您在Centos上:

    sudo yum install php-mysqlnd
    sudo service httpd restart
    
    本机驱动程序适当地返回整数类型

    正如@Jeroen所指出的,这种方法只适用于PDO。
    正如@LarsMoelleken所指出的,如果您还将mysqli_OPT_INT_和_FLOAT_NATIVE选项设置为true,那么这个方法将与mysqli一起工作

    例如:

    $mysqli->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, TRUE);
    

    我喜欢Chad的回答,尤其是当查询结果将在浏览器中传递给javascript时。Javascript干净地将类似数字的实体作为数字处理,但将类似数字的实体作为字符串处理需要额外的工作。i、 e.必须在其上使用parseInt或parseFloat

    在Chad的解决方案的基础上,我使用它,它通常正是我所需要的,并创建可以用JSON编码的结构,以便在javascript中轻松处理

    while ($row = $result->fetch_assoc()) {
        // convert numeric looking things to numbers for javascript
        foreach ($row as &$val) {
            if (is_numeric($val))
                $val = $val + 0;
        }
    }
    

    将数字字符串添加到0会在PHP中生成一个数字类型,并正确标识该类型,因此浮点数不会被截断为整数。

    MySQL具有许多其他语言的驱动程序,可以将数据转换为字符串“标准化”数据,并让用户将强制转换值键入int或其他值

    我找到的最简单的解决方案:

    您可以强制json_encode对看起来像数字的值使用实际数字:

    json_encode($data, JSON_NUMERIC_CHECK) 
    
    (从PHP 5.3.3开始)

    或者你可以把你的ID转换成int

    $row = $result->fetch_assoc();
    $id = (int) $row['userid'];
    
    $row = $result->fetch_assoc();
    $id = (int) $row['userid'];
    

    在我的例子中,
    mysqlnd.so
    扩展已经安装。但是我没有pdo_mysqlnd.so。因此,通过将
    pdo_mysqlnd.So
    替换为
    pdo_mysqlnd.So

    解决了这个问题。当连接上的
    pdo::ATTR_EMULATE_PREPARES
    设置为
    true
    时,就会发生这种情况

    但是要小心,将其设置为
    false
    会禁止多次使用参数。我相信这也会影响返回的错误消息的质量。

    我喜欢,但编码可以更简单:

    function cast_query_results($result): array
    {
        if ($result === false)
          return null;
    
        $data = array();
        $fields = $result->fetch_fields();
        while ($row = $result->fetch_assoc()) {
          foreach ($fields as $field) {
            $fieldName = $field->name;
            $fieldValue = $row[$fieldName];
            if (!is_null($fieldValue))
                switch ($field->type) {
                  case 3:
                    $row[$fieldName] = (int)$fieldValue;
                    break;
                  case 4:
                    $row[$fieldName] = (float)$fieldValue;
                    break;
                  // Add other type conversions as desired.
                  // Strings are already strings, so don't need to be touched.
                }
          }
          array_push($data, $row);
        }
    
        return $data;
    }
    
    我还添加了对返回false而不是结果集的查询的检查。
    以及检查具有空值字段的行。
    如果想要的类型是一个字符串,我不会在上面浪费时间——它已经是一个字符串了


    我不会在大多数php代码中使用这个;我只是依靠php的自动类型转换。但是,如果查询大量数据,然后执行算术计算,那么最好先转换为最佳类型

    $mysqli->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, TRUE);
    
    试试这个-对我有用。

    仅适用于mysqlnd:

     mysqli_options($conn, MYSQLI_OPT_INT_AND_FLOAT_NATIVE, true);
    
    否则:

      $row = $result->fetch_assoc();
    
      while ($field = $result->fetch_field()) {
        switch (true) {
          case (preg_match('#^(float|double|decimal)#', $field->type)):
            $row[$field->name] = (float)$row[$field->name];
            break;
          case (preg_match('#^(bit|(tiny|small|medium|big)?int)#', $field->type)):
            $row[$field->name] = (int)$row[$field->name];
            break;
          default:
            $row[$field->name] = $row[$field->name];
            break;
        }
      }
    

    MySQL查询提供的是行值,而不是行类型或任何其他相关信息。只是每个表单元格中的原始数据。您必须在PHPIf中对此进行说明。如果您需要列类型,请参见此处,以供读者阅读,选择的答案涉及迭代结果。但有一个更好的解决办法@DanHanly-从技术上讲,MYSQL查询(在PHP中)返回单元格值的字符串表示形式-存储在数据库中的32位整数的实际单元格值是。。。32位整数,不是数字字符串。对我来说,当我使用
    $conn->query(“您的查询”)
    时,我将整数字段作为字符串,但当我使用
    $conn->prepare(“您的查询”)时
    我得到了数据库中的参数。我从Postgres后台来到MySQL,我觉得有必要说这是一个巨大的痛苦。在Postgres中获取行时,可以确保行数组中的元素具有适当的数据类型。现在我必须编写代码,手动将每个元素转换为我期望的数据类型