留言板的基本功能已经实现,但是还是存在非常多的问题的。例如有用户忘记输入用户名或者留言内容或者直接在地址栏输入数据处理页localhost/message/send.php,所以我们需要一个验证的手段和安全性的检验,验证的手段非常多,有客户端的有服务端的。
首先检测表单是否提交,在send.php中添加以下代码:
if ($_SERVER["REQUEST_METHOD"] == "POST"){
....正常的数据处理代码
}else {
header("refresh:3;url=index.php");
print('对不起,操作有误,页面正在跳转,请重新留言!');
}
这可以防止直接在地址栏输入处理页send.php。
对用户输入的内容进行过滤,我们新建一个自定义函数testInput(),这样可以提高重复性
//check the user's data
function checkInput($data) {
$data = trim($data); //移除字符串两侧的空白字符或者预定义字符
$data = stripslashes($data); //删除反斜杠
$data = htmlspecialchars($data); //把预定义字符转换为HTML实体
return $data;
}
完整的代码:
<?php
header("Content-Type:text/html;charset=utf-8");
date_default_timezone_set('PRC');
if ($_SERVER["REQUEST_METHOD"] == "POST"){
// import the connection file
require "conn.php";
// insert the data to the table
$user_name = checkInput($_POST["user_name"]);
$user_mes = checkInput($_POST["user_mes"]);
$send_time = date("Y-m-d H:i:s");
// set the data encoding is utf8
$conn->query("set names 'utf8'");
$sql = "INSERT INTO message (user_name, user_mes, send_time)
VALUES ('$user_name', '$user_mes', '$send_time')";
// check it
if($conn->query($sql) === true) {
header("Location:index.php");
}else {
echo "数据插入失败" . $conn->error;
}
// close the datebase connection
$conn->close();
}else {
header("refresh:3;url=index.php");
print('对不起,操作有误,页面正在跳转,请重新留言!');
}
//check the user's data
function checkInput($data) {
$data = trim($data); //移除字符串两侧的空白字符或者预定义字符
$data = stripslashes($data); //删除反斜杠
$data = htmlspecialchars($data); //把预定义字符转换为HTML实体
return $data;
}
?>
下面进行用户输入空内容的处理:
if (empty($user_name) or empty($user_mes)) {
header("refresh:3;url=index.php");
print('对不起,用户昵称或留言内容不得为空,页面正在跳转,请重新留言!');
}else {
$sql = "INSERT INTO message (user_name, user_mes, send_time)
VALUES ('$user_name', '$user_mes', '$send_time')";
// check it
if($conn->query($sql) === true) {
header("Location:index.php");
}else {
echo "数据插入失败" . $conn->error;
}
}
一般的用户名称,为中文、英文以及数字的集合,当然也有其他符号类型,但是我们在这里限制用户在用户名中输入任何字符,只能输入中文、英文和数字。这个就需要正则表达式了。
if (preg_match("/^[\x{4e00}-\x{9fa5}a-zA-Z0-9]{3,60}$/u", $user_name))
preg_match 是匹配正则表达式的函数,刚开始我的正则表达式是这样写的:/^[\u4e00-\u9fa5a-zA-Z0-9]{3,60}$/,结果编译出错,显示不支持这种格式,我百度了下,发现了这位前辈写的博文和我的情况几乎一样:
PHP正则匹配中文 然后按照他的方法写,结果能正常匹配了。
if (preg_match("/^[\x{4e00}-\x{9fa5}a-zA-Z0-9]{3,60}$/u", $user_name)) {
$sql = "INSERT INTO message (user_name, user_mes, send_time)
VALUES ('$user_name', '$user_mes', '$send_time')";
// check it
if($conn->query($sql) === true) {
header("Location:index.php");
}else {
echo "数据插入失败" . $conn->error;
}
}else {
// header("refresh:3;url=index.php");
// print('对不起,用户名仅限中英文和数字,页面正在跳转,请重新填写!');
echo "<script>alert('对不起,用户名仅限中英文和数字!'); location='index.php';</script>";
}
在匹配不成功的时候,小伙伴们应该发现了,我把原来的跳转方法给注释掉了,因为他们不跳转,我就转用了JS方法。header()不跳转硬挨是因为前面的print('对不起,用户昵称或留言内容不得为空,页面正在跳转,请重新留言!');这条输出语句的关系,我不知道我说的是否正确,还请看到的大神指点下。
本人知道的所有安全性就只有这些啦,完整的代码如下:
<?php
header("Content-Type:text/html;charset=utf-8");
date_default_timezone_set('PRC');
if ($_SERVER["REQUEST_METHOD"] == "POST"){
// import the connection file
require "conn.php";
// insert the data to the table
$user_name = checkInput($_POST["user_name"]);
$user_mes = checkInput($_POST["user_mes"]);
$send_time = date("Y-m-d H:i:s");
// set the data encoding is utf8
$conn->query("set names 'utf8'");
if (empty($user_name) or empty($user_mes)) {
header("refresh:3;url=index.php");
print('对不起,用户昵称或留言内容不得为空,页面正在跳转,请重新留言!');
}else {
if (preg_match("/^[\x{4e00}-\x{9fa5}a-zA-Z0-9]{3,60}$/u", $user_name)) {
$sql = "INSERT INTO message (user_name, user_mes, send_time)
VALUES ('$user_name', '$user_mes', '$send_time')";
// check it
if($conn->query($sql) === true) {
header("Location:index.php");
}else {
echo "数据插入失败" . $conn->error;
}
}else {
// header("refresh:3;url=index.php");
// print('对不起,用户名仅限中英文和数字,页面正在跳转,请重新填写!');
echo "<script>alert('对不起,用户名仅限中英文和数字!'); location='index.php';</script>";
}
}
// close the datebase connection
$conn->close();
}else {
header("refresh:3;url=index.php");
print('对不起,操作有误,页面正在跳转,请重新留言!');
}
//check the user's data
function checkInput($data) {
$data = trim($data); //移除字符串两侧的空白字符或者预定义字符
$data = stripslashes($data); //删除反斜杠
$data = htmlspecialchars($data); //把预定义字符转换为HTML实体
return $data;
}
?>
以上都是在服务端的验证,但是这样其实并不友好,最佳的应该是在客户端进行一些基本的验证,而服务端的作为后备手段,在浏览器被禁止使用脚本的时候的,发挥作用。这个我们到下篇讲吧!