PHP MySQL PDO:如何保留zerofill int列的前导零

Ale*_*lex 15 php mysql pdo

在从旧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;
Run Code Online (Sandbox Code Playgroud)

注意zerofill'ed IdTestDecimal字段.

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

$SqlQuery = "SELECT * FROM test";
$Sql_Result = mysql_query($SqlQuery);
var_dump(mysql_fetch_array($Sql_Result));
Run Code Online (Sandbox Code Playgroud)

我得到以下输出,正确的zerofilled 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)
Run Code Online (Sandbox Code Playgroud)

但是,如果我使用PDO执行相同操作,请执行以下操作:

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

我得到此输出,错误的非零填充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)
Run Code Online (Sandbox Code Playgroud)

看起来PDO类正在查看列类型并在PHP中返回匹配的变量类型(在本例中为整数).经过一些搜索,我发现了一个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)
Run Code Online (Sandbox Code Playgroud)

它似乎与该decimal(6,0) zerofill字段正常工作,但不适用于该tinyint(4) zerofill字段...有没有办法使这项工作,或者我将不得不重新审视我的代码库并找出这一变化的突破(我已经确定了几个那些不起作用的东西......)?

演示代码.

Geo*_*ili 7

你可以用LPAD

试试这个: SELECT *, LPAD( Id, 3, '0') AS zero_Fill_Id FROM test

应该3根据int大小改变:对于这种情况可能是4?

更新:

我不认为改变int到十进制是好习惯,为什么我不会深入研究这个,你可以搜索那个主题.

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

使用mysqlnd进行PDO的优点

使用服务器端预准备语句时,mysqlnd返回本机数据类型,例如,INT列作为整数变量而不是字符串返回.这意味着内部数据转换更少.

source:如何使用PDO从MySQL获取数值类型?

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

...
$pdo->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
Run Code Online (Sandbox Code Playgroud)

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

  • 就我个人而言,我认为LPAD是要走的路 - 但我并不真正理解zerofill的观点 (2认同)