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

发布于 2024-10-21 23:05:36 字数 375 浏览 9 评论 0原文

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

userid INT(11)

所以我用这个查询将它调用到我的页面:

"SELECT userid FROM DB WHERE name='john'"

然后为了处理结果,我这样做:

$row=$result->fetch_assoc();

$id=$row['userid'];

现在如果我这样做:

echo gettype($id);

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

I have a table field in a MySQL database:

userid INT(11)

So I am calling it to my page with this query:

"SELECT userid FROM DB WHERE name='john'"

Then for handling the result I do:

$row=$result->fetch_assoc();

$id=$row['userid'];

Now if I do:

echo gettype($id);

I get a string. Shouldn't this be an integer?

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

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

发布评论

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

评论(17

生寂 2024-10-28 23:05:36

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

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

或者使用函数 intval()

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

When you select data from a MySQL database using PHP the datatype will always be converted to a string. You can convert it back to an integer using the following code:

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

Or by using the function intval():

$id = intval($row['userid']);
悲凉≈ 2024-10-28 23:05:36

使用 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_AND_FLOAT_NATIVE 选项设置为 true,则此方法将适用于 mysqli。

例子:

$mysqli->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, TRUE);

Use the mysqlnd (native driver) for php.

If you're on Ubuntu:

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

If you're on Centos:

sudo yum install php-mysqlnd
sudo service httpd restart

The native driver returns integer types appropriately.

As @Jeroen has pointed out, this method will only work out-of-the-box for PDO.
As @LarsMoelleken has pointed out, this method will work with mysqli if you also set the MYSQLI_OPT_INT_AND_FLOAT_NATIVE option to true.

Example:

$mysqli->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, TRUE);
徒留西风 2024-10-28 23:05:36

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

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

json_encode($data, JSON_NUMERIC_CHECK) 

自 PHP 5.3.3 起)。

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

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

Easiest Solution I found:

You can force json_encode to use actual numbers for values that look like numbers:

json_encode($data, JSON_NUMERIC_CHECK) 

(since PHP 5.3.3).

Or you could just cast your ID to an int.

$row = $result->fetch_assoc();
$id = (int) $row['userid'];
顾北清歌寒 2024-10-28 23:05:36

我的解决方案是传递查询结果 $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

My solution is to pass the query result $rs and get a assoc array of the casted data as the return:

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

Example usage:

$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
南薇 2024-10-28 23:05:36

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

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

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

No. Regardless of the data type defined in your tables, PHP's MySQL driver always serves row values as strings.

You need to cast your ID to an int.

$row = $result->fetch_assoc();
$id = (int) $row['userid'];
笑,眼淚并存 2024-10-28 23:05:36

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

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

This happens when PDO::ATTR_EMULATE_PREPARES is set to true on the connection.

Careful though, setting it to false disallows the use of parameters more than once. I believe it also affects the quality of the error messages coming back.

影子是时光的心 2024-10-28 23:05:36

我喜欢 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 中生成数字类型,并正确识别该类型,因此浮点数不会被截断为整数。

I like Chad's answer, especially when the query results will be passed on to javascript in a browser. Javascript deals cleanly with numeric like entities as numbers but requires extra work to deal with numeric like entities as strings. i.e. must use parseInt or parseFloat on them.

Building on Chad's solution I use this and it is often exactly what I need and creates structures that can be JSON encoded for easy dealing with in 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;
    }
}

Adding a numeric string to 0 produces a numeric type in PHP and correctly identifies the type so floating point numbers will not be truncated into integers.

裸钻 2024-10-28 23:05:36

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

For mysqlnd only:

 mysqli_options($conn, MYSQLI_OPT_INT_AND_FLOAT_NATIVE, true);

Otherwise:

  $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;
    }
  }
盗琴音 2024-10-28 23:05:36

如果使用准备好的语句,则在适当的情况下类型将为 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;
}

If prepared statements are used, the type will be int where appropriate. This code returns an array of rows, where each row is an associative array. Like if fetch_assoc() was called for all rows, but with preserved type info.

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;
}
a√萤火虫的光℡ 2024-10-28 23:05:36

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

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

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

In my project I usually use an external function that "filters" data retrieved with mysql_fetch_assoc.

You can rename fields in your table so that is intuitive to understand which data type is stored.

For example, you can add a special suffix to each numeric field:
if userid is an INT(11) you can rename it userid_i or if it is an UNSIGNED INT(11) you can rename userid_u.
At this point, you can write a simple PHP function that receive as input the associative array (retrieved with mysql_fetch_assoc), and apply casting to the "value" stored with those special "keys".

栖迟 2024-10-28 23:05:36

就我而言,mysqlnd.so 扩展已安装。但我没有pdo_mysqlnd.so。因此,通过将 pdo_mysql.so 替换为 pdo_mysqlnd.so 解决了该问题。

In my case mysqlnd.so extension had been installed. BUT i hadn't pdo_mysqlnd.so. So, the problem had been solved by replacing pdo_mysql.so with pdo_mysqlnd.so.

在巴黎塔顶看东京樱花 2024-10-28 23:05:36

我喜欢 mastermind 的技术,但编码可以更简单:

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的自动类型转换。但如果查询大量数据,然后执行算术计算,明智的做法是预先转换为最佳类型。

I like mastermind's technique, but the coding can be simpler:

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

I also added checking for query returning false rather than a result-set.
And checking for a row with a field that has a null value.
And if the desired type is a string, I don't waste any time on it - its already a string.


I don't bother using this in most php code; I just rely on php's automatic type conversion. But if querying a lot of data, to then perform arithmetic computations, it is sensible to cast to the optimal types up front.

绝情姑娘 2024-10-28 23:05:36

从 PHP 8.1 开始,您可以使用相应的数据类型检索整数浮点数,而不是转换为字符串。

当使用模拟准备语句时,结果集中的整数和浮点数现在将使用本机 PHP 类型而不是字符串返回。这与本机准备好的语句的行为相匹配。可以通过启用 PDO::ATTR_STRINGIFY_FETCHES 选项来恢复以前的行为。

https://www.php.net/手册/en/migration81.inknown.php#migration81.inknown.pdo.mysql

Since PHP 8.1 you're able to retrieve integers and floats with the according datatype instead of beeing converted to a string.

Integers and floats in result sets will now be returned using native PHP types instead of strings when using emulated prepared statements. This matches the behavior of native prepared statements. The previous behaviour can be restored by enabling the PDO::ATTR_STRINGIFY_FETCHES option.

https://www.php.net/manual/en/migration81.incompatible.php#migration81.incompatible.pdo.mysql

青巷忧颜 2024-10-28 23:05:36

就像advait上面的答案一样,PDO驱动程序可以按预期执行行为(整数数据库列在PHP中作为整数数据类型检索) )与 mysqlnd 驱动程序。我在托管服务器上遇到了这个问题,显然默认情况下没有使用 mysqlnd 。我没有 root 访问权限来通过包管理器安装包。相反,cPanel 上的 PHP 选择器允许我通过启用 nd_pdo_mysql 来安装驱动程序。 (看起来 mysqli 有一个等效的驱动程序:nd_mysqli)。

在我看来,Michiel Pater关于如何将值转换回整数的答案(目前是最佳答案)是一项工作-周围并没有解决方案。

Like advait's answer above, the PDO driver can perform the behavior as expected (Integer database columns get retrieved as integer data types in PHP) with the mysqlnd driver. I was having this issue on a managed server where apparently mysqlnd wasn't being used by default. I didn't have root access to install the package via the package manager. Instead the PHP selector on cPanel allowed me to install the driver by enabling nd_pdo_mysql. (Looks like there was an equivalent driver for mysqli: nd_mysqli).

In my opinion, Michiel Pater's answer (currently the top answer), about how to cast values back to integers is a work-around and not a solution.

梦中的蝴蝶 2024-10-28 23:05:36

你可以用...

  1. mysql_fetch_field()
  2. 来做到这一点mysqli_result::fetch_field_direct
  3. PDOStatement::getColumnMeta()

...取决于您要使用的扩展。不推荐第一个,因为 mysql 扩展已被弃用。第三个仍处于实验阶段。

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

一些框架也对此进行了抽象(CodeIgniter 提供了 $this->db-> ;field_data())。

您还可以进行猜测 - 例如循环遍历结果行并使用 is_numeric()< /a> 每个。就像这样:

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

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

You can do this with...

  1. mysql_fetch_field()
  2. mysqli_result::fetch_field_direct or
  3. PDOStatement::getColumnMeta()

...depending on the extension you want to use. The first is not recommended because the mysql extension is deprecated. The third is still experimental.

The comments at these hyperlinks do a good job of explaining how to set your type from a plain old string to its original type in the database.

Some frameworks also abstract this (CodeIgniter provides $this->db->field_data()).

You could also do guesswork--like looping through your resulting rows and using is_numeric() on each. Something like:

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

This would turn anything that looks like a number into one...definitely not perfect.

凝望流年 2024-10-28 23:05:36

如果您使用类/对象来存储数据库数据,您可以对其属性进行类型转换,因此它将转换为正确的类型:

<?php
  class User
  {
    public int $id; // use type casting in class definition
  }
  
  $user1 = new User();
  $user1->id = $row['userid'];
  echo gettype($user1->id); // integer
?>

注意:我想指出上面的 Charlie 解决方案在我的 Windows 环境中工作,但更改了当我尝试在 Linux 服务器上部署我的项目时,PDO::ATTR_EMULATE_PREPARES 为 false 不起作用。我仍然得到字符串而不是数字。

If you are using classes/objects to store your db data, you can type cast its attributes, so it would be converted to the right type:

<?php
  class User
  {
    public int $id; // use type casting in class definition
  }
  
  $user1 = new User();
  $user1->id = $row['userid'];
  echo gettype($user1->id); // integer
?>

note: I would like to point out that Charlie solution above worked in my windows environment but changing the PDO::ATTR_EMULATE_PREPARES to false did not work when I tried to deploy my project on a linux server. I still got strings instead of numbers.

南街女流氓 2024-10-28 23:05:36

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

MySQL has drivers for many other languages, converting data to string "standardizes" data and leaves it up to the user to type-cast values to int or others

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