为什么在PDO中强类型化参数很重要?

10
当你将参数绑定到SQL语句时,可以提供参数类型,例如PDO::PARAM_STR。如果没有提供,类型的默认值为PDO::PARAM_STR。为什么要特别设置每个参数的类型呢?至少在MySQL中,我知道PDO::PARAM_STR适用于任何参数。我认为甚至可以使用PDO::PARAM_STR与BLOB列一起使用。
PDO::PARAM_STR并不会引入任何SQL注入,因为您仍然拥有预处理查询。
2个回答

7

在列值中使用PARAM_STR总是有效的,因为mySQL会隐式地将值转换为正确的类型,但是它在以下查询中会失败:

$limit = 1;

$dbh->prepare("SELECT * FROM items LIMIT :limit");
$dbh->bindParam(":limit", $limit, PDO::PARAM_STR); 
     // Will throw "You have an error in your SQL syntax..."

在适当的情况下,应该绝对使用PARAM_INT - 比如上面的例子,并为除了mySQL之外的其他数据库引擎做好更加严格的准备。


我给你点赞,这是一个很好的例子。不仅应该避免SQL注入,向用户显示原始的MySQL错误信息也不太吸引人,也不够专业,因此开发人员应始终强制执行类型安全。 - N.B.
@注意:对我来说这太无聊了。我更喜欢简洁的代码,而不是一遍又一遍地重复这个绑定。 - Your Common Sense
1
你测试代码用的是哪个PHP版本?我这里用的是Windows系统,PHP版本是5.3.1,无论是使用PDO::ATTR_EMULATE_PREPARES还是不使用,在参数化LIMIT子句中都没有抛出异常,就像@Col.建议的那样。其他数据库呢?它们也会进行类型转换吗? - Vladislav Rastrusny

5

就我个人而言,只要您设置了此属性,我就看不到任何理由:

$dbh->setAttribute( PDO::ATTR_EMULATE_PREPARES, false );

因此,它会自动检测 LIMIT 情况。

不管怎样,我更喜欢在占位符中定义类型,而不是在绑定函数中定义。

然而,我的 PDO 经验并不是很强。我只是试过它,然后决定回到普通的 mysql。


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