PHP MySQL PDO:如何保留0填充列的前导零


PHP MySQL PDO: how to preserve leading zeros of zerofill int columns

在从旧的mysql_*()函数迁移到新的PDO类的过程中,我又遇到了一个障碍:我有一个下面的表格:

CREATE TABLE `test` (
  `Id` tinyint(4) unsigned zerofill NOT NULL,
  `UserName` varchar(4) NOT NULL,
  `TestDecimal` decimal(6,0) unsigned zerofill DEFAULT NULL,
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

注意IdTestDecimal字段填零

如果我运行以下代码,使用旧的mysql_*()函数:

$SqlQuery = "SELECT * FROM test";
$Sql_Result = mysql_query($SqlQuery);
var_dump(mysql_fetch_array($Sql_Result));

我得到以下输出,正确地填零Id:

array (size=6)
  0 => string '0001' (length=4)
  'Id' => string '0001' (length=4)
  1 => string 'alex' (length=4)
  'UserName' => string 'alex' (length=4)
  2 => string '000002' (length=6)
  'TestDecimal' => string '000002' (length=6)

但是,如果我使用PDO做同样的事情,像这样:

$SqlQuery = "SELECT * FROM test";
$SqlResult = $MysqlPDO->prepare($SqlQuery);
$SqlResult->execute();
var_dump($SqlResult->fetch(PDO::FETCH_BOTH));

我得到了这个输出,其中不正确地非零填充Id:

array (size=6)
  'Id' => int 1
  0 => int 1
  'UserName' => string 'alex' (length=4)
  1 => string 'alex' (length=4)
  'TestDecimal' => string '000002' (length=6)
  2 => string '000002' (length=6)
在PHP中,PDO类似乎正在查看列类型并返回匹配的变量类型(在这种情况下为整数)。经过一些搜索,我发现了关于PDO::ATTR_STRINGIFY_FETCHES属性,可以设置为强制所有MYSQL结果作为字符串返回,而这似乎是工作的(我得到一个字符串而不是int),它仍然不返回前导零:
array (size=6)
  'Id' => string '1' (length=1)
  0 => string '1' (length=1)
  'UserName' => string 'alex' (length=4)
  1 => string 'alex' (length=4)
  'TestDecimal' => string '000002' (length=6)
  2 => string '000002' (length=6)

它似乎与decimal(6,0) zerofill字段正确工作,但不与tinyint(4) zerofill字段…是否有任何方法可以使此工作,或者我将不得不检查我的代码库并找出这个更改的中断(我已经确定了一些不再工作的东西…)?

演示代码。

您可以使用LPAD ?

try this: SELECT *, LPAD( Id, 3, '0') AS zero_Fill_Id FROM test

应该改变3根据int大小:也许4在这种情况下?

更新:

我不认为将整型改为十进制是一个好的做法,为什么我不深入讨论这个,你可以在这个主题上搜索。

我认为你使用mysqlnd驱动程序,我发现它(检查是否启用如何知道MySQLnd是否是活动驱动程序?):

使用mysqlnd for PDO的优点

mysqld返回本地数据类型使用服务器端预置语句,例如,返回一个INT列作为一个整数变量,而不是字符串。这意味着更少的数据在内部转换。

source:如何使用PDO从MySQL获得数字类型?

在这种情况下,有PDO::ATTR_STRINGIFY_FETCHES,在你的情况下应该设置为true,你也可以给尝试PDO::ATTR_EMULATE_PREPARES属性进一步看:PDO MySQL:使用PDO:: attr_emulate_prepare或不?

...
$pdo->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);

希望这对任何情况或任何人都有帮助:))

我会编写一个小例程来修补 PDO输出以满足需求,并尝试对编码进行最少的更改。

$results = pdoFix($SqlResult->fetchAll(PDO::FETCH_BOTH))

function pdoFix($results) {
    foreach ($results as &$row) { // note the "&"
      $row[0] = sprintf("%'04s",$row[0]); // zerofill '0'
      $row['id'] = sprintf("%'04s",$row['id']); // zerofill 'id'
    }
    unset($row); // break the reference with the last element
    return $results;
}

注意:其他的答案都一样好,挑一个你觉得最舒服的。