我希望使用Doctrine DBAL函数executeQuery,如下所示:
$conn = DBALDriverManager::getConnection($connectionParams, $config);
$sql = "SELECT count(*) FROM clients WHERE client_id = :id";
$results = $conn->executeQuery($sql, ['id' => 'foo'], ['id' => PDO::PARAM_STR]);
var_dump($results->fetchAll());
var_dump($results->rowCount());
哪个工作良好返回:
array (size=1)
0 =>
array (size=1)
'count(*)' => string '1' (length=1)
int 1
然而,代码也可以使用以下行(其中类型参数声明不正确或根本没有声明):
$results = $conn->executeQuery($sql, ['id' => 'foo'], ['id' => PDO::PARAM_INT]);
$results = $conn->executeQuery($sql, ['id' => 'foo'], ['notatag' => PDO::PARAM_STR]);
$results = $conn->executeQuery($sql, ['id' => 'foo']);
暗示没有使用声明绑定变量数据类型,这引发了人们对是否可以防止SQL注入的担忧。
我是不是做错了什么?如何确保我的代码安全?
重读DBAL文档后,我发现了这个宝石:
如果您没有为任何参数绑定方法指定一个整数(通过PDO::PARAM*常量),而是指定一个字符串,Doctrine DBAL将要求类型抽象层将传递的值从其PHP转换为数据库表示。
因此,通过不定义$types
参数,可以让Doctrine显式转换类型。
但这有多安全?条令在描述"在查询中包含用户输入"的"正确"方式时有这样的说法:
除了绑定参数,您还可以传递变量的类型。这使得条令或基础供应商不仅可以逃脱,还可以将价值投射到正确的类型。
从安全角度来看,建议$types
参数是可选的。