如何在PHP中将MySQL中的整数和数字列作为整数和数字返回?

2022-08-30 07:51:42

问题是数据库查询应该在 PHP 中为整数列返回整数数据类型。相反,查询将每列作为字符串类型返回。

我确保“PDO::ATTR_STRINGIFY_FETCHES”如果为假,只是为了确保结果不会被强制转换为字符串。

我看到的答案:

  • 这是无法做到的
    • 不,它正在Mac OS X上安装PHP / MySQL
  • 在代码中对所有值进行类型转换
    • 不,我不会那样做
  • 别担心,PHP是松散类型的
    • 我的数据输出为 JSON,并由许多其他服务使用,有些服务需要正确格式的数据

根据我的研究,我知道这是一个驱动程序实现问题。

许多消息来源声称MySQL本机驱动程序不支持返回数字类型。这似乎不是真的,因为它可以在Mac OS X上运行,除非他们的意思是说“Linux上的MySQL本机驱动程序不支持该功能”。

这意味着我在Mac OS X上安装的驱动程序/环境有一些特殊之处。我一直在尝试识别差异以应用修复程序,但我受到如何检查这些内容的知识的限制。

区别:

  • OS X上的PHP是通过Home Brew编译和安装的
  • Ubuntu 上的 PHP 是通过 “apt-get install php5-dev” 安装的
  • OS X 上的 PHP 正在连接到也在 OS X 上运行的 MySQL 服务器
    • 服务器版本:5.1.71 日志源分发
  • Ubuntu 上的 PHP 正在连接到 Rackspace Cloud Database
    • 服务器版本: 5.1.66-0+squeeze1 (Debian)

乌班图环境

  • 版本: 10.04.1

  • PHP 5.4.21-1+debphp.org~lucid+1 (cli) (建版本: Oct 21 2013 08:14:37)

  • php -i

    pdo_mysql

    适用于 MySQL 的 PDO 驱动程序 = 启用 > 客户端 API 版本 = > 5.1.72

Mac OS X 环境

  • 10.7.5

  • PHP 5.4.16 (cli) (建設: Aug 22 2013 09:05:58)

  • php -i

    pdo_mysql

    适用于 MySQL 的 PDO 驱动程序 = > 启用的客户端 API 版本 => mysqlnd 5.0.10 - 20111026 - $Id: e707c415db32080b3752b232487a435ee0372157 $

使用的 PDO 标志

PDO::ATTR_CASE => PDO::CASE_NATURAL,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
PDO::ATTR_STRINGIFY_FETCHES => false,
PDO::ATTR_EMULATE_PREPARES => false,

答案 1

解决方案是确保您使用的是用于php的mysqlnd驱动程序。

你怎么知道你没有使用mysqlnd?

查看时,不会提到“mysqlnd”。该部分将包含如下内容:php -ipdo_mysql

pdo_mysql

PDO Driver for MySQL => enabled Client API version => 5.1.72

如何安装?

大多数L/A/M/P的安装指南都建议使用,但MySQL的本机驱动程序是由不同的软件包安装的:。我发现这可以通过ppa:ondrej/php5-oldstable获得apt-get install php5-mysqlphp5-mysqlnd

要切换到新的驱动程序(在 Ubuntu 上):

  • 删除旧驱动程序:
    apt-get remove php5-mysql
  • 安装新驱动程序:
    apt-get install php5-mysqlnd
  • 重新启动 apache2:
    service apache2 restart

如何检查驱动程序是否正在使用?

现在将在本节中明确提及“mysqlnd”:php -ipdo_mysql

pdo_mysql

PDO Driver for MySQL => enabled
Client API version => mysqlnd 5.0.10 - 20111026 - $Id:      e707c415db32080b3752b232487a435ee0372157 $

PDO 设置

确保是(检查默认值或设置):PDO::ATTR_EMULATE_PREPARESfalse
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

确保是(检查默认值或设置):PDO::ATTR_STRINGIFY_FETCHESfalse
$pdo->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);

返回值

  • 浮点类型(FLOAT、DOUBLE)作为 PHP 浮点数返回。
  • 整数类型(INTEGER、INT、SMALLINT、TINYINT、MEDIUMINT、BIGINT †)作为 PHP 整数返回。
  • 定点类型(十进制、数字)以字符串形式返回。

†值大于 64 位有符号 int (9223372036854775807) 的 BIGINT 将作为字符串返回(在 32 位系统上为 32 位)

    object(stdClass)[915]
      public 'integer_col' => int 1
      public 'double_col' => float 1.55
      public 'float_col' => float 1.5
      public 'decimal_col' => string '1.20' (length=4)
      public 'bigint_col' => string '18446744073709551615' (length=20)

答案 2

这个被接受的答案有效,并且似乎是Google上对这个问题最受欢迎的答案。我的问题是我需要将应用程序部署到多个环境,并且我并不总是能够安装正确的驱动程序,而且我需要小数是数字,而不是字符串。因此,我创建了一个例程,在JSON编码之前键入大小写,该例程很容易修改以适应。这有点像从轨道上核弹它。

首先,使用“显示列来自”从表中获取列。mysql 查询 “SHOW COLUMNS FROM TABLE,如 'colmunname'”:questions

$query = 'SHOW COLUMNS FROM ' . $table; //run with mysqli or PDO 

然后将类型放入按列名索引的数组中,以便于迭代。假定显示列的结果集位于名为 $columns_from_table 的变量中。http://php.net/manual/en/function.array-column.php

$column_types = array_column( $columns_from_table, 'Type', 'Field');

接下来,我们要从类型中删除括号,这将是类似于varchar(32)或decimal(14,6)的东西。

foreach( $column_types as $col=>$type )
{
    $len = strpos( $type, '(' );
    if( $len !== false )
    {
        $column_types[ $col ] = substr( $type, 0, $len );
    }
}

现在我们有一个关联的数组,其中列名作为索引,格式化类型作为值,例如:

Array
(
    [id] => int
    [name] => varchar
    [balance] => decimal
    ...
)

现在,当您从表中进行选择时,您可以循环访问结果并将值强制转换为适当的类型:

foreach( $results as $index=>$row )
{
    foreach( $row as $col=>$value )
    {
        switch( $column_types[$col] )
        {
            case 'decimal':
            case 'numeric':
            case 'float':
            case 'double':

                $row[ $col ] = (float)$value;
                break;

            case 'integer':
            case 'int':
            case 'bigint':
            case 'mediumint':
            case 'tinyint':
            case 'smallint':

                $row[ $col ] = (int)$value;
                break;
        }

    }
    $results[ $index ] = $row;
}

switch 语句可以很容易地修改以适应,并且可以包括日期函数等。例如,在我的情况下,第三方将货币值作为小数推送到数据库中,但是当我获取该数据并需要将其作为JSON返回时,我需要这些是数字,而不是字符串。

使用 PHP 7、7.2 和 JQuery 2、3 进行测试。


推荐