在Doctrine DBAL中使用executeQuery发布绑定变量类型


Issues binding variable types using executeQuery in Doctrine DBAL

我希望使用Doctrine DBAL函数executeQuery,如下所示:

$conn = DBAL'DriverManager::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参数是可选的。