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

时间:2011-03-16 09:20:09

标签: 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);

我收到了一个字符串。这不应该是一个整数吗?

16 个答案:

答案 0 :(得分:117)

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

$id = (int) $row['userid'];

或者使用函数intval()

$id = intval($row['userid']);

答案 1 :(得分:68)

使用mysqlnd(本机驱动程序)for php。

如果您使用的是Ubuntu:

sudo apt-get install php5-mysqlnd
sudo service apache2 restart

如果您使用Centos:

sudo yum install php-mysqlnd
sudo service httpd restart

本机驱动程序适当地返回整数类型。

编辑:

正如@Jeroen指出的那样,这种方法只能为PDO开箱即用 正如@LarsMoelleken指出的那样,如果你还将MY​​SQLI_OPT_INT_AND_FLOAT_NATIVE选项设置为true,这个方法将适用于mysqli。

示例:

$mysqli = mysqli_init();
$mysqli->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, TRUE);

答案 2 :(得分:17)

我的解决方案是传递查询结果$rs并获取转换数据的关联数组作为返回:

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;
}

使用示例:

$dbconn = mysqli_connect('localhost','user','passwd','tablename');
$rs = mysqli_query($dbconn, "SELECT * FROM Matches");
$matches = cast_query_results($rs);
// $matches is now a assoc array of rows properly casted to ints/floats/strings

答案 3 :(得分:15)

我发现最简单的解决方案:

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

json_encode($data, JSON_NUMERIC_CHECK) 

(自PHP 5.3.3起)。

或者您可以将您的ID转换为int。

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

答案 4 :(得分:13)

没有。无论表中定义的数据类型如何,PHP的MySQL驱动程序始终将行值作为字符串提供。

您需要将您的ID转换为int。

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

答案 5 :(得分:5)

我喜欢Chad的回答,特别是当查询结果将在浏览器中传递给javascript时。 Javascript干净利用数字实体作为数字处理,但需要额外的工作来处理类似数字的实体作为字符串。即必须在它们上使用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中生成数字类型并正确识别该类型,因此浮点数不会被截断为整数。

答案 6 :(得分:2)

在我的项目中,我通常使用一个外部函数来“过滤”用mysql_fetch_assoc检索的数据。

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

例如,您可以为每个数字字段添加特殊后缀: 如果useridINT(11),则可以将其重命名为userid_i,如果是UNSIGNED INT(11),则可以重命名userid_u。 此时,您可以编写一个简单的PHP函数,该函数接收关联数组(使用mysql_fetch_assoc检索)作为输入,并将转换应用于存储有这些特殊“键”的“值”。

答案 7 :(得分:2)

你可以用......

来做到这一点
  1. mysql_fetch_field()
  2. mysqli_result::fetch_field_direct
  3. PDOStatement::getColumnMeta()
  4. ...取决于您要使用的扩展程序。不建议使用第一个,因为不推荐使用mysql扩展。第三个仍然是实验性的。

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

    一些框架也抽象了这一点(CodeIgniter提供$this->db->field_data())。

    您也可以进行猜测 - 例如循环生成的行并在每个行上使用is_numeric()。类似的东西:

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

    这会把看起来像数字的东西变成一个......绝对不是完美的。

答案 8 :(得分:1)

如果使用预准备语句,则类型将在适当的位置为int。此代码返回一个行数组,其中每一行都是一个关联数组。就像是为所有行调用了fetch_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;
}

答案 9 :(得分:1)

MySQL拥有许多其他语言的驱动程序,将数据转换为字符串“标准化”数据,并将其留给用户,以便将值转换为int或其他语言

答案 10 :(得分:1)

在我的案例中已安装mysqlnd.so扩展程序。但我没有pdo_mysqlnd.so。因此,通过将pdo_mysql.so替换为pdo_mysqlnd.so来解决问题。

答案 11 :(得分:1)

PDO::ATTR_EMULATE_PREPARES在连接上设置为true时会发生这种情况。

答案 12 :(得分:1)

$mysqli->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, TRUE);

尝试一下-为我工作。

答案 13 :(得分:0)

我喜欢mastermind's technique,但是编码可以更简单:

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的自动类型转换。但是,如果要查询大量数据,然后执行算术计算,则应预先将最佳类型强制转换为最佳类型。

答案 14 :(得分:0)

仅适用于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;
    }
  }

答案 15 :(得分:-1)

在变量之前加上一个加号也可以解决问题,

$a = "120";
$b = +$a;
echo gettype($b);

显然不是最好的方式,但是当你无法访问环境以安装更好的驱动程序时,它会起作用。