Php 如何避免PDOStatement::bindParam与引用值混淆

Php 如何避免PDOStatement::bindParam与引用值混淆,php,mysql,pdo,phalcon,Php,Mysql,Pdo,Phalcon,我面临着Steve m所描述的问题,但规模很大,详情请参见 我使用的是Phalcon,但它主要是作为包装器使用的,这个问题不能受到限制。具体问题如下—— TL;数组中的DR Int值转换为字符串,如下所示: 我以后会重用该数组,并严重依赖ints。当它们变成字符串时,它破坏了所有的乐趣…无论我如何使用它,都会使用foreach复制值,array_合并到新数组中,ArrayObject::getArrayCopy以获取副本原始值不断更改,以及从中复制的其他数组的值。他们唯一可行的复制方法是: $a

我面临着Steve m所描述的问题,但规模很大,详情请参见

我使用的是Phalcon,但它主要是作为包装器使用的,这个问题不能受到限制。具体问题如下——

TL;数组中的DR Int值转换为字符串,如下所示:

我以后会重用该数组,并严重依赖ints。当它们变成字符串时,它破坏了所有的乐趣…无论我如何使用它,都会使用foreach复制值,array_合并到新数组中,ArrayObject::getArrayCopy以获取副本原始值不断更改,以及从中复制的其他数组的值。他们唯一可行的复制方法是:

$adapter->fetchAll($sql, Db::FETCH_ASSOC, unserialize(serialize(($params)));
这感觉像是一个巨大的杀伤力。下面是另一个似乎有效的解决方案,不过$paramTypes并没有为感兴趣的人提供文档

$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描述的收到负面反馈的方法相同

我的问题是:

为什么按照建议的方式做可能是个坏主意? 你能推荐另一个替代方案吗?除了将修改后的数组转换回整数之外。 世界跆拳道联盟???!!!为什么需要引用并修改它?是否应该有错误报告???
非常感谢大家

您的mysql数据库将保持数据类型为php mysqlnd driver,这两个属性设置为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;

*/

问题在于Phalcon没有充分使用PDOStatement::bindParam而不是PDOStatement::bindValue。github上介绍了big,后面是a,最终被合并到1.3.2版。

使用bindValue而不是bindParam,这样原始变量就不会改变。使用面向对象编程,例如数据传输对象,它不会改变任何东西……真的。面向对象编程?听起来很有趣,我可能会在谷歌上搜索……正如你所看到的,所以不适合这样的问题。只有那些能够得到使用oop答案的人才会受到社区的欢迎。应该有人运行另一个需要询问编程问题的站点。为什么人们不阅读手册Phalcon\Db::FETCH_NUM第385页谢谢您的输入。我已经在github回复了这个问题。你漏掉了几点。属性在保持参数不被修改方面没有任何作用,显式设置int does$sth->bindParam1,$parm1,PDO::PARAM_int;–这就是我试图避免手动操作的原因。
$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;

*/