用户输入,在发送到db之前清理并清理

SUL*_*TAN 11 html php mysql

我在这里搜索了很多的问题,我发现,他们要么很旧的或使用预处理语句暗示PDO我不使用.所以我需要你的帮助.

我有一个小的讨论/聊天框,用户使用一个提交消息 <textarea>

我需要的是清理和过滤用户输入,因此它只接受纯文本(例如没有标签,没有html标签,没有脚本没有链接等). 此外,允许换行也很重要.

根据我的阅读,我按以下顺序执行以下操作:

  1. trim()
  2. htmlentities($comment, ENT_NOQUOTES)
  3. mysqli_real_escape_string()
  4. nl2br()

我正在做的是对的吗?或者我错过了什么?

echo从数据库中获取数据时我还需要做什么吗?

真的,感谢你的帮助和善意

Ric*_*mes 8

首先,保持文本的逻辑和清洁:

trim() -- OK
htmlentities($comment, ENT_NOQUOTES)  -- No; do later
mysqli_real_escape_string()  -- Yes; required by API
nl2br()  -- No; see below
Run Code Online (Sandbox Code Playgroud)

这些建议背后的逻辑:数据库中的数据应该只是普通数据.不是htmlentities,不是br-tags.但是,您必须执行escape_string才能将数据从PHP传递到MySQL; 转义将不会被存储.

但是......这只是中间步骤.数据来自哪里?旧版本的PHP试图"保护"你添加转义和其他适用于HTML的垃圾,但是搞砸了MySQL.关闭这样的魔法转义,并获取原始数据.

数据在哪里?可能是HTML?后SELECTing的数据回出表中的,然后第一做htmlentities()和(任选地)nl2br();

请注意,如果您希望保留像<I>(斜体)这样的东西,那么您就会遇到麻烦 - 大麻烦.黑客需要做的就是<script> ...将各种恶意注入您的网页,甚至是整个系统.


nom*_*tic 6

你还有另一种选择.您可以使用预准备语句mysqli

它们并不是很难学习和工作mysqli_real_escape_string(),因为您不必担心转义查询中的每个变量.在进入数据库之前,它们本质上是"准备好的".这还有其他优点,其中:

  1. 你不需要addslashes()能够处理撇号等字符.

  2. 对于大型数据库,它们将大大加快您的查询速度(非常像PDO).

这是怎么做的:

您通过创建一个新的mysqli对象连接到数据库,如下所示:

$conn = new mysqli($host, $username, $password, $dbname);

if ($conn->connect_error) {
    die("Connection failed: " . $dbc->connect_error);
    }
Run Code Online (Sandbox Code Playgroud)

接下来,您要从表单转换变量.

假设您有一个这样的表单域:

<input type="text" name="var1">
Run Code Online (Sandbox Code Playgroud)

你可以像这样使用htmlentities和trim,并创建你的$var1变量:

$var1 = htmlentities(trim($_POST['var1']));
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样创建你的交易:

$stmt= $conn->prepare("insert into tablename (key1, key2) values (?,?)");
$stmt->bind_param("is",$var1, $var2);
$stmt->execute();
$stmt->close();
Run Code Online (Sandbox Code Playgroud)

基本上就是这样.您可以像通常那样进行查询,而是使用?占位符,分配数据类型(上面是i整数和s字符串),然后将它们绑定到查询中的占位符.

基本上就是这样.

如果你想用带变量的select来做,你可以使用普通的select语法和a ?与变量一样的方法,然后绑定它.然后,您可以轻松地将结果绑定到变量中(假设var3是一个整数):

$stmt= $conn->prepare("select var1, var2  from tablename where var3 = ?");
$stmt = bind_param("i", $var3);
$stmt->bind_result($var1, $var2);
$stmt->execute();
$stmt->close()
Run Code Online (Sandbox Code Playgroud)

然后你可以使用它来获取变量

$stmt->fetch();
Run Code Online (Sandbox Code Playgroud)

或者如果您的查询带回多行

while ($stmt->fetch() {
    echo $var1 . $var2;
}
Run Code Online (Sandbox Code Playgroud)

nl2br()用于输出,你不需要担心输入; 它可以存储在数据库中\n,并在需要时将其作为中断发出.如果这些变量中的一个需要将新行转换为<br/>标记,您可以,因为您建议使用nl2br()变量(注意这不会增加安全性,但正如您所说,您需要它),就像这样

echo nl2br($var1, false);
Run Code Online (Sandbox Code Playgroud)

你也可以使用trim(),并htmlentities()在此判断是否被呼应成,也就是说,一个表单输入字段,你不希望你的形式突破,如果有输出HTML字符.