我在表单中有一个简单的文本框,我想在POST或GET后安全地在数据库中存储特殊字符,我使用下面的代码。 $文本= mysql_real_escape_string(htmlspecialchars_decode(的stripslashes(修剪($ _ GET [ “文本”])),ENT_QUOTES));
当我从数据库中读取文本并将其放入文本值时,我使用上面的代码。
$text=htmlspecialchars($text_from_DB,ENT_QUOTES,'UTF-8',false);
<input type="text" value="<?=$text?>" />
我试图在没有特殊字符的数据库中保存(意思是我不想在数据库字段中写入“或”)
实际上,当写入数据库时,请{i} htmlspecialchars_decode
到文本。
写入表单文本框时,请对文本执行htmlspecialchars
。
这是安全地将特殊字符写入数据库的最佳方法吗?
答案 0 :(得分:3)
您有正确的想法将数据库中的文本保持为原始状态。不确定所有HTML实体的内容是什么;您不应该为数据库插入而这样做。
[我可以想到为什么你可能会尝试对数据库的传入输入进行实体解码的唯一原因是,如果您发现在表单提交输入中获得了Š
等字符引用。如果发生这种情况,那是因为用户正在输入页面使用表单所使用的编码中不存在的字符。这种编码形式完全是假的,因为您无法区分用户输入Š
和字面输入Š
!您应该通过对所有页面和内容使用UTF-8编码来避免这种情况,因为每个可能的字符都符合此编码。]
脚本中的字符串应始终为原始文本而不进行转义。这意味着在将它们输出到非纯文本的上下文之前,您不会对它们执行任何操作。因此,将它们放入SQL字符串:
$category= trim($_POST['category']);
mysql_query("SELECT * FROM things WHERE category='".mysql_real_escape_string($category)."'");
(或使用参数化查询以避免必须手动转义它。)将内容放入HTML时:
<input type="text" name="category" value="<?php echo htmlspecialchars($category); ?>" />
(如果你想减少模板中必须输入的数量,你可以用function h($s) { echo htmlspecialchars($s, ENT_QUOTES); }
这样的较短名称定义辅助函数。)
而且......就是这样。您不需要处理来自数据库的字符串,因为它们已经是原始字符串。除了要执行的任何特定于应用程序的字段验证之外,您不需要处理输入字符串(*)。
*:好吧,除非启用了magic_quotes_gpc
,否则您需要{get:post / cookie中的stripslashes()
所有内容或者我喜欢的选项失败:
if (get_magic_quotes_gpc())
die(
'Magic quotes are turned on. They are utterly bogus and no-one should use them. '.
'Turn them off, you idiot, or I refuse to run. So there!'
);
答案 1 :(得分:1)
当您写入数据库时,请使用 htmlentities ,但在您回读时,请使用 html_entity_decode 功能。
作为旁注,如果您正在寻找一些安全措施,那么对于字符串使用 mysql_real_escape_string ,对于数字,请使用 intval 。
答案 2 :(得分:1)
我想指出一些事情:
在数据库中保存'
和"
等字符没有任何问题,SQL注入只是字符串操作的问题,它们实际上与SQL或数据库无关 - - 问题 only 依赖于查询字符串的构建方式。如果你想编写自己的查询(不推荐),你不必编码每个撇号或双引号:只需转义一次以构建一个安全的字符串,并将它们保存在数据库中。更好的方法是使用所提到的PDO,或者使用允许使用预准备语句进行查询的mysqli extension
htmlentities()
并且在将数据作为输出发送到浏览器时应该使用类似的函数,而不是为了将数据编码存储在数据库中,至少有两个原因:首先它没用,DB不关心html实体,它只包含数据;其次,您应始终将来自数据库的数据视为可能不安全,因此您应将其保存为“原始”格式,并在使用时对其进行编码。
答案 3 :(得分:0)
安全写入数据库的最佳方法是使用PDO抽象层并使用预准备语句。
http://www.php.net/manual/en/intro.pdo.php
一个好的教程(我从这个中学到的)是
http://www.phpro.org/tutorials/Introduction-to-PHP-PDO.html
但是,您可能需要重写您的网站,以实现此目的。但这无疑是最优雅的方法,而不是必须使用所有这些功能。此外,准备好的声明现在正成为事实。这样做的另一个好处是,如果切换到不同的数据库(例如从MySQL到PostgreSQL),则不必重写查询。但是如果您计划扩展您的网站,我会考虑这个。