在PHP提交string数据库时,我应该照顾使用htmlspecialchars()非法字符或使用正则expression式?

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

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

也就是说,MySQL有mysql_real_escape_string 。

这些转义function可以处理任何可能具有恶意的字符,而且您仍然可以按照与其相同的方式获取数据。

您也可以使用准备好的语句来处理数据:

$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)); 

如果你想保存不同types的数据,使用bindParam来定义每个types,也就是说,一个整数可以定义为: $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上学到更多的知识。

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

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

  1. build立一个查询通常的方式,使其看起来像SQL查询,你可以在SQL控制台中运行。
    要做到这一点,应该理解一整套规则 ,而不仅仅是“使用mysql_real_escape_string”。
    规则如:

    • string应该被括在引号中并且逃脱。 这是转义的唯一含义:它只是逃生分隔符! (和一些其他字符 – string终止字符和转义字符本身)。 没有周围的引用mysql_real_escape_string只是没用。
    • 数字应该转换为明确的types。 虽然数据的数字可以像string一样被威胁,但是有一些数字,比如LIMIT子句的参数,它们不能被转义,只能被转换。
  2. 分别发送查询和数据。
    这是最好的方式,因为它可以缩短为“使用绑定”。 所有的string,数字和LIMIT参数都可以绑定 – 根本不用担心。
    使用这种方法,将占位符的查询按原样发送到数据库,绑定的数据以单独的数据包发送,因此不会产生干扰。 它就像代码数据分离一样。 你发送你的程序(查询本身)与数据分离。

但!

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

 $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 

或dynamicsearch:

 $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"; 

在这个例子中,我们只向查询添加用户input的数据,而不是在脚本中全部硬编码的字段名称。 对于绑定,algorithm会非常相似。

等等。

首先,你应该在显示时清理东西,而不是在插入到数据库之前。 SQL注入是另一回事,但可能是脱离主题。

其次,如果你不需要你的用户能够发布HTML, htmlspecialchars是你所需要的。 它处理HTML中的所有特殊字符。

我正在处理一个表单,用户可以在要提交给数据库的string中使用非法/特殊字符。

用户可以远远超过实际情况。

我想逃避/否定string中的这些字符,并使用htmlspecialchars()。 不过,我想知道是否有更好/更快的方法。

使用HTML净化器

HTML Purifier是用PHP编写的符合标准的HTMLfilter库。 HTML Purifier不仅会删除所有的恶意代码(更好的称为XSS)与一个彻底审计,安全,宽容的白名单。

并自己决定:)

这不是你想要自己解决的问题。 有一些库可以为你做这个,比如HTML Purifier 。

你还没有说明这些非法字符可能是什么,但你一定要使用数据库API提供的机制来转义数据。 例如,如果您使用的是MySQL,请使用PDO参数化的SQL语句。