php - 如何避免 PDOStatement::bindParam 弄乱引用的值

标签 php mysql pdo phalcon

我正面临 Steve 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 .

我的问题:

  1. 为什么这样做可能不是一个好主意 Axeia建议?
  2. 你能推荐另一种替代方案吗?除了将修改后的数组转换回整数。
  3. WTF???!!!为什么需要引用并修改它?应该有错误报告吗???

非常感谢大家!

最佳答案

你的 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;

*/

关于php - 如何避免 PDOStatement::bindParam 弄乱引用的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22084499/

相关文章:

php - 私信系统查询

mysql - 如何在 MySql 中 DATETIME 字段的日期部分创建索引

c# - 如何将字符串转换为mysql日期时间格式?

mysql - PDO GROUP BY 不返回结果

php - 为什么 PDO 在 wamp 中不起作用?

javascript - 如何从 Active Class 获取类别 ID 并传递给 Post 查询

php - 使用特定选择查询(嵌套语句)中的值更新查询

php - json_encode 序列化空字节

mysql - SQL检查A和B是否IN(...)

php - 使用 pg_execute,我不能使用 now() 或空值