这对 SQL 注入来说是 100% 安全的吗?对于任何输入都会正确表达吗?

Is this a 100% safe from SQL Injection and will word correctly for any input?

$a=$_GET["a"];
$b=$_GET["b"];
$a=str_replace("%", "\%", $a);
$b=str_replace("%", "\%", $b);
$sql="SELECT * FROM table ";
$sql.="WHERE ColA LIKE :txtA AND ColB LIKE :txtB";
$query = $db->prepare($sql);
$query->bindValue(':txtA', '%'.$a.'%', PDO::PARAM_STR);
$query->bindValue(':txtB', '%'.$b.'%', PDO::PARAM_STR);
$query->execute();

我想让用户能够搜索任何内容。我应该过滤更多字符吗?它会 100% 安全并像在数据库中搜索文本片段时那样工作吗?

是的,您的代码遵循 SQL 注入预防的良好做法。使用参数是正确的做法。

唯一的建议是可选的,为了代码风格,而不是安全代码。你的也一样安全。

$a=preg_replace('/[%_]/', '\\[=10=]', $_GET["a"]);
$b=preg_replace('/[%_]/', '\\[=10=]', $_GET["b"]);
$sql="
    SELECT * FROM table 
    WHERE ColA LIKE :txtA AND ColB LIKE :txtB";
$query = $db->prepare($sql);
$query->execute(['txtA'=>"%{$a}%", 'txtB'=>"%{$b}%"]);

PDO 允许您将查询参数作为数组参数传递给 execute(),因此您不必使用 bindValue()

此外,您不需要 bindValue()PDO::PARAM_STR 个参数,至少 MySQL 不需要。 MySQL 的 PDO 驱动程序始终将参数作为字符串传递。也许其他一些品牌的数据库需要它。

您可以在一个多行字符串中编写 SQL 查询(与 Java 等某些语言不同)。您不需要使用 .=.

您可以在双引号字符串中嵌入 PHP 变量。你不需要使用'%'.$a.'%',你可以使用"%{$a}%"。我发现后者更具可读性,尤其是当您要包含多个变量时。