PDO bindParam与execute的区别

63

我经常看到使用PDO的bindParambindValue的代码。是否由于某种原因而不建议简单地将参数传递给execute

我知道bindParam实际上绑定变量,并且你可以使用这两种bind方法设置要绑定的参数类型,但如果只插入字符串会怎样呢?

$query = "SELECT col1 FROM t1 WHERE col2 = :col2 AND col3 = :col3 AND col4 = :col4";
$pdo->bindValue(':col2', 'col2');
$pdo->bindValue(':col3', 'col3');
$pdo->bindValue(':col4', 'col4');

我经常看到上面的写法,但个人更喜欢:

$pdo->execute(array(':col2' => 'col2', ':col3' => 'col3', ':col4' => 'col4'));

对于我来说,将输入的参数“一起”传递给查询,在视觉上更直观且不那么冗长。然而,我几乎从未看到过这种用法。

当您不必利用前者的特殊行为时,是否有理由优先使用bind方法而不是将参数传递给execute


1
我认为这归结于个人偏好 - 我倾向于使用 bindValuebindParam,因为我认为生成的代码更容易阅读。 - andrewsi
2
这确实取决于个人喜好。如果您不需要强制类型(仅使用字符串时),将数组传递给execute()是快速和方便的。 - Michael Berkowski
3个回答

72
你可能会发现在查询中只需将变量引用绑定到参数,但仍需要对其进行一些操作并且只希望在执行查询时计算变量值时使用bindParam。它还允许您执行更复杂的操作,例如将参数绑定到存储过程调用,并将返回的值更新到绑定变量中。
有关更多信息,请参见bindParam文档bindValue文档execute文档
例如:
$col1 = 'some_value';
$pdo->bindParam(':col1', $col1);
$col1 = 'some_other_value';
$pdo->execute(); // would use 'some_other_value' for ':col1' parameter

bindValue和将数组传递给execute的行为方式基本相同,因为参数值在该点被固定并且相应地执行SQL语句。

继续使用上面的示例,但使用bindValue

$col1 = 'some_value';
$pdo->bindValue(':col1', $col1);
$col1 = 'some_other_value';
$pdo->execute(); // would use 'some_value' for ':col1' parameter

当直接在execute中传递值时,所有的值都会被视为字符串(即使提供了整数值)。因此,如果您需要强制数据类型,您应该始终使用bindValuebindParam
我认为你可能会看到比execute(array)更多的bind*用法,因为许多人认为在参数声明中明确定义数据类型是更好的编码实践。

嗨,Mike。出于兴趣,你能详细解释一下吗?将变量传递给 bindParam() 的工作原理一直让我感到很有趣,因为有时我会遇到“无法通过引用传递变量”的错误,而且实际上并不确定这意味着什么,当我思考它的时候。 - Martin Bean
1
@ExplosionPills 我是指数据类型明确。抱歉造成困惑,我已经更新了我的答案。 - Mike Brant
3
bindParam按引用传递变量,这意味着该值仅在使用时(即查询执行时)进行评估。这使您可以例如在循环中查询,仅更改变量,而不需要一遍又一遍地绑定。 - Madara's Ghost
1
显式数据类型是一个好的实践方法,这在理论上是正确的。然而,在实际应用中我很少看到这种情况。个人而言,我认为大部分时间我会坚持使用“执行”。 - Explosion Pills
1
MySQL接受where number > '6',那么我们什么时候真正需要将参数转换为整数? - Chan
显示剩余2条评论

10

通过将参数传递给$pdo->execute()方法,数组中的所有值都将作为PDO::PARAM_STR传递到$pdo->bindParam()函数所在的语句中。

我现在能看到的主要区别是,使用$pdo->bindParam()函数,您可以使用PDO::PARAM_*常量来定义传递的数据类型,如PHP.net手册中所述。


4

简单来说,bindParam的值可以更改,但bindValue的值不能更改。

例如:

$someVal=10;
$someVal2=20;
/* In bindParam, the value argument is not bound and 
will be changed if we change its value before execute.
*/
$ref->bindParam(':someCol',$someVal);
$someVal=$someVal2;
$ref->execute();
//someCol=20
/* In bindValue, the value argument is bound and 
never changed if we change its value before execute.
*/
$ref->bindValue(':someCol',$someVal);
// here assignment is referral (&$someVal)
$someVal=$someVal2;
$ref->execute();
//someCol=10

5
我认为楼主的问题是在询问execute和bindParam的区别,而不是bindParam和bindValue的区别。但我刚开始使用PDO,不知道这两者的区别。 - tsukimi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接