在从旧的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;
注意Id
和TestDecimal
字段填零
如果我运行以下代码,使用旧的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;
}
注意:其他的答案都一样好,挑一个你觉得最舒服的。