我正面临史蒂夫M所描述的问题但是“大规模”,请参阅详情http://www.php.net/manual/en/pdostatement.bindparam.php#94711
我正在使用Phalcon,但它主要用作包装器,问题不能受此限制。详细问题在这里 - https://github.com/phalcon/cphalcon/issues/2111
TL;数组中的DR Int值将转换为字符串,如下所示:
var_dump($params); // array(2) { [0]=> int(6609) [1]=> int(6664) }
$adapter->fetchAll($sql, Db::FETCH_ASSOC, $params);
var_dump($params); // array(2) { [0]=> string(4) "6609" [1]=> string(4) "6664" }
我稍后重用该数组并严重依赖于整数。当它们变成字符串时,它会破坏所有的快乐......无论我用它做什么(将值foreach
,array_merge
复制到新数组中,ArrayObject::getArrayCopy
获得副本)原始值不断变化(以及他们从中复制的其他数组的值)。它们只有复制方式才有效:
$adapter->fetchAll($sql, Db::FETCH_ASSOC, unserialize(serialize(($params)));
这感觉就像一场大规模的矫枉过正。另一个似乎有效的解决方案如下,但$paramTypes
没有记录(Phalcon code that handles it对于那些感兴趣的人)。
$paramTypes = [];
foreach ($params as $param) {
if (is_int($param)) {
$paramTypes[] = \PDO::PARAM_INT;
} else {
$paramTypes[] = null;
}
}
$rows = $this->adapter->fetchAll($sql, Db::FETCH_ASSOC, $params, $paramTypes);
对我而言,它似乎是最好的方法,但这里是Axeia描述的收到负面反馈的同一方法 - http://www.php.net/manual/en/pdo.constants.php#97130。
我的问题:
非常感谢你们!
答案 0 :(得分:0)
你的mysql数据库将保留数据类型,因为它是宽度php-mysqlnd驱动程序,并且这两个属性设置为false:
$dbh->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$parm1 = 2;
var_dump($parm1);
// int(2)
$sth = $dbh->prepare('SELECT * FROM test.table1 WHERE id = ?');
$sth->bindParam(1, $parm1, PDO::PARAM_INT);
$sth->execute();
$data = $sth->fetchAll(PDO::FETCH_ASSOC);
var_dump($parm1);
// int(2)
var_dump($data);
/* you get nice and clean result:
array(1) {
[0]=>
array(4) {
["id"]=> int(2)
["name"]=> string(3) "XYZ"
["someint"]=> int(543)
["somefloat"]=> float(1000.0001220703)
}
}
And table is:
CREATE TABLE `table1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`someint` int(8) DEFAULT NULL,
`somefloat` float(10,5) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
*/
答案 1 :(得分:0)
问题在于Phalcon没有充分使用PDOStatement::bindParam
代替PDOStatement::bindValue
。 github上覆盖了大debate,后跟pull request,最终合并到1.3.2版本。