我一直在编写一个PHP脚本,用于我在网站上使用的“联系我们”表单,以允许用户对该网站发表评论。它有几个字段,包括名称字段和用于注释的文本区域。用户提交表单后,将注释输入到数据库中,然后查询最近的五条注释并将其显示在网站上。但是,用户当前无法在名称字段或注释区域中输入撇号('
)并正确显示它们。
这是一系列事件:
"User Submit -> Prepare SQL -> Insert Record -> Query Database -> Return recent Comments"
目前,这就是我对PHP的看法:
//Function that will trim the input, and run it through a small security check
function test_input($input)
{
$input = trim($input);
$input = stripslashes($input);
$input = htmlspecialchars($input);
return $input;
}
$name = test_input($_POST["txtName"]);
$comments = test_input($_POST["txtComments"]);
//Prepared statement to insert a new Contact record
$stmt = $conn -> prepare("INSERT INTO tableName (name, comments) VALUES (?, ?)");
//Create the parameters of the prepared statement
$stmt -> bind_param("ss", $param_name, $param_comments);
//Set the parameters of the statement, running them through a security check
$param_name = mysqli_real_escape_string($conn, $name);
$param_comments = mysqli_real_escape_string($conn, $comments);
//Execute the prepared statement
$stmt -> execute()
如您所见,我通过htmlspecialchars()
函数和mysqli_real_escape_string()
函数运行变量。但是,当我运行该函数时,我仍然得到一个奇怪的输出。
Name with Apostro'phe
I'm happy with the "/" and "\" of the present.
Name with Apostro\'phe
I\'m happy with the "/" and the "" of the present.
"
来自htmlspecialchars
函数,并认为\'
来自mysqli_real_escape_string()
函数。Name with Apostro\'phe
I\'m happy with the "/" and the "" of the present.
\'
相同。我如何获得它,以便在从数据库中查询撇号正常显示后在HTML中重新显示它?但是,这不是我想要的。当它显示在评论部分(从数据库中查询后)时,我希望它显示为用户输入的内容。我并不关心它在数据库中的外观,只要它在查询返回HTML时填充列表就能正常显示。
我应该怎么做才能让用户在他们的名字/评论中输入撇号,并在从数据库返回后显示撇号;但与此同时,不会冒SQL注入的风险?我看过几个相关的问题,但没有找到任何能回答我问题的问题。
MySQL/PHP: Allow special characters and avoid SQL injections
php - Allowing special characters in form submit
如果我需要澄清任何事情,请告诉我!
答案 0 :(得分:2)
您正在使用带有预处理语句的占位符。手动转义文本完全没必要。数据库已经作为占位符系统的一部分进行了自己的内部转义,因此您的转义只会添加一个额外的转义层,这些转义将输入到表中。
e.g。
name = "Miles O'Brien";
manual escape -> "Miles O\'Brien";
placeholder escape -> "Miles O\\'Brien";
stored in database -> "Miles O\'Brien";
retrieved from db -> "Miles O\'Brien";
displayed to user -> "Miles O\'Brien";
如果删除手动转义,则突然一切都按预期工作:
name = "Miles O'Brien";
placeholder escape -> "Miles O\'Brien";
stored in database -> "Miles O'Brien";
retrieved from db -> "Miles O'Brien";
displayed to user -> "Miles O'Brien";