为什么我们需要在bindParam()中指定参数类型?

Sam*_*hid 6 php pdo sql-injection

我有点困惑为什么我们需要指定在 Php 的 PDO 中的 bindParam() 函数中传递的数据类型。例如这个查询:

$calories = 150; 
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < ? AND colour = ?');
$sth->bindParam(1, $calories, PDO::PARAM_INT); 
$sth->bindParam(2, $colour, PDO::PARAM_STR, 12);
$sth->execute();
Run Code Online (Sandbox Code Playgroud)

如果不指定第三个参数,是否存在安全风险?我的意思是如果我只是在 bindParam() 中执行以下操作:

$sth->bindParam(1, $calories); 
$sth->bindParam(2, $colour);
Run Code Online (Sandbox Code Playgroud)

PLP*_*ers 3

使用bindParam()类型可以被认为更安全,因为它允许更严格的验证,进一步防止 SQL 注入。但是,如果您不这样做,我不会说存在真正的安全风险,因为事实上,您执行的是准备好的语句来防止 SQL 注入,而不是类型验证。实现此目的的一种更简单的方法是简单地将数组传递给execute()函数而不是使用bindParam(),如下所示:

$calories = 150; 
$colour = 'red';

$sth = $dbh->prepare('SELECT name, colour, calories
                      FROM fruit
                      WHERE calories < :calories AND colour = :colour');

$sth->execute(array(
    'calories' => $calories,
    'colour' => $colour
));
Run Code Online (Sandbox Code Playgroud)

您不必使用字典,您也可以像使用问号一样进行操作,然后将其按照相同的顺序放入数组中。然而,即使这工作得很好,我还是建议养成使用第一个方法的习惯,因为一旦达到一定数量的参数,这种方法就会变得一团糟。为了完整起见,它如下所示:

$calories = 150; 
$colour = 'red';

$sth = $dbh->prepare('SELECT name, colour, calories
                      FROM fruit
                      WHERE calories < ? AND colour = ?');

$sth->execute(array($calories, $colour));
Run Code Online (Sandbox Code Playgroud)