【问题标题】:PDO/MYSQL prepared statements not escaping characters?PDO/MYSQL 准备好的语句没有转义字符?
【发布时间】:2012-02-07 17:48:09
【问题描述】:
我正在尝试在我的程序中编写搜索功能:
$search = "%".$_POST['search']."%";
$query=$connection->prepare("SELECT * FROM TABLE WHERE COLUMN LIKE ?");
$query->execute(array($search));
但是,用户似乎可以简单地输入 % 并返回所有结果。我该如何防止这种情况发生?我的印象是使用准备好的语句会转义这些字符。这是否也适用于其他字符(\、'等)?我该如何解决?
【问题讨论】:
标签:
php
mysql
pdo
prepared-statement
【解决方案1】:
准备好的语句不会逃避任何事情。当你准备一个语句时,你的查询会被预编译,因此它只需要填写占位符(?)。由于无法更改预编译查询的 SQL,因此不需要转义。
要解决此问题,请手动转义 % 和 _。
添加:
一点常识推理:在您的情况下,当用户在搜索框中输入% 时,您的$search 变量包含字符串%%%。 MySQL 怎么知道,哪个% 应该逃跑,哪个应该不理会?
【解决方案2】:
如果您不希望将% 或_ 作为有效输入,您需要防止在应用程序代码中包含它。
if (strpos($_POST['search'], '%') !== FALSE || strpos($_POST['search'], '_') !== FALSE) {
$query = $connection->prepare("SELECT * FROM TABLE WHERE COLUMN LIKE ?");
$query->execute(array($search));
}
else echo "% and _ are not allowed!";
对于像' 这样的字符,它们被视为代替? 占位符传递的字符串的一部分,而不是连接起来以构建SQL 语句。所以他们是安全的。
【解决方案3】:
您必须正确地转义用户输入,让服务器知道哪些字符是通配符,哪些是要匹配的数据。
$search = '%' . str_replace(array('_', '%'), array('\\_', '\\%'), $_POST['search']) . '%';
这将转义那些原本会被视为通配符的字符。 $search 现在将包含以下内容:
%100\%%
将匹配I always give 100% when working,但不匹配I do 100 pushups daily。