在PHP向数据库提交字符串时,我应该使用htmlspecialchars()处理非法字符还是使用正则表达式?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (55)

我正在处理一个表单,可能会让用户在要提交给数据库的字符串中使用非法/特殊字符。我想避免字符串中的这些字符,并使用htmlspecialchars()。有更好还是更快的方法?

提问于
用户回答回答于

如果将此数据提交给数据库,请查看数据库的转义函数。

也就是说,对于MySQL,有mysql_real_escape_string。

这些转义功能可以处理任何可能具有恶意的字符,并且仍然可以按照与放置在其中的方式相同的方式获取数据。

还可以使用预处理语句来处理数据:

$dbPreparedStatement = $db->prepare('INSERT INTO table (htmlcontent) VALUES (?)');
$dbPreparedStatement->execute(array($yourHtmlData));

或者多一点解释:

$dbPreparedStatement = $db->prepare('INSERT INTO table (htmlcontent) VALUES (:htmlcontent)');
$dbPreparedStatement->execute(array(':htmlcontent' => $yourHtmlData));

如果你想保存不同类型的数据,bindParam用来定义每种类型,也就是说,一个整数可以用下面的定义:$db->bindParam(':userId', $userId, PDO::PARAM_INT);。例:

$dbPreparedStatement = $db->prepare('INSERT INTO table (postId, htmlcontent) VALUES (:postid, :htmlcontent)');
$dbPreparedStatement->bindParam(':postid', $userId, PDO::PARAM_INT);
$dbPreparedStatement->bindParam(':htmlcontent', $yourHtmlData, PDO::PARAM_STR);
$dbPreparedStatement->execute();

$db你的PHP数据对象(PDO)在哪里?如果你不使用它,可能会在PHP Data Objects上了解更多。

用户回答回答于

数据库没有“非法”字符。无法存储某些字符的数据库是无稽之谈。有一些服务字符,如引号,用于分隔字符串。这些角色应该只是逃脱,而不是消除。

要将查询发送到数据库,您有两个选项:

  1. 构建查询通常的方式,使其看起来完全像SQL查询,可以在SQL控制台中运行。 要做到这一点,人们应该理解一整套规则,而不仅仅是“使用mysql_real_escape_string”。 规则如:
    • 字符串应该用引号括起来并且逃脱。这是转义的唯一含义:它只是逃避分隔符!(和一些其他字符 - 字符串终止字符和转义字符本身)。没有周围的引号mysql_real_escape_string只是没用。
    • 数字应该明确地转换为它的类型。虽然数据编号可能像字符串一样受到威胁,但也有一些编号,如LIMIT子句参数,它们不能被转义,只能转换。

  2. 要发送的查询和数据分开。 这是最好的方式,因为它可以缩短为“使用绑定”。所有的字符串,数字和LIMIT参数都可以被绑定 - 根本不用担心。 使用这种方法,将占位符的查询按原样发送到数据库,并将绑定的数据以单独的数据包发送,因此它不会产生干扰。它就像代码数据分离一样。您将您的程序(查询本身)从数据中分离出来。

以上所说的全部内容仅涵盖查询的数据部分。 但有时我们必须使我们的查询更具动态性,增加运算符或标识符。 在这种情况下,每个动态参数都应该在我们的脚本中进行硬编码并从该组中进行选择。 例如,做动态排序:

$orders  = array("name","price","qty"); //field names
$key     = array_search($_GET['sort'],$orders)); // see if we have such a name
$orderby = $orders[$key]; //if not, first one will be set automatically. smart enuf :)
$query   = "SELECT * FROM `table` ORDER BY $orderby"; //value is safe

或动态搜索:

$w     = array();
$where = '';

if (!empty($_GET['rooms']))     $w[]="rooms='".mesc($_GET['rooms'])."'";
if (!empty($_GET['space']))     $w[]="space='".mesc($_GET['space'])."'";
if (!empty($_GET['max_price'])) $w[]="price < '".mesc($_GET['max_price'])."'";

if (count($w)) $where="WHERE ".implode(' AND ',$w);
$query="select * from table $where";

在这个例子中,我们只向查询添加用户输入的数据,而不是字段名,这些都是在脚本中硬编码的。对于绑定,算法会非常相似。

扫码关注云+社区

领取腾讯云代金券