在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。 这些字符应该只是逃脱,不能消除。
要将查询发送到数据库,您有两个选项:
-
build立一个查询通常的方式,使其看起来像SQL查询,你可以在SQL控制台中运行。
要做到这一点,应该理解一整套规则 ,而不仅仅是“使用mysql_real_escape_string”。
规则如:- string应该被括在引号中并且逃脱。 这是转义的唯一含义:它只是逃生分隔符! (和一些其他字符 – string终止字符和转义字符本身)。 没有周围的引用mysql_real_escape_string只是没用。
- 数字应该转换为明确的types。 虽然数据的数字可以像string一样被威胁,但是有一些数字,比如LIMIT子句的参数,它们不能被转义,只能被转换。
-
分别发送查询和数据。
这是最好的方式,因为它可以缩短为“使用绑定”。 所有的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语句。