PHP实现简易留言板

2022-10-27 14:47:30 浏览数 (1)

简介

初学PHP用来练手的项目。只有一些基本功能。

实现

一个基于bootstrap前端框架,PHP MySQL开发的简易留言板web程序。

  • 主题:留言板
  • 前端:bootstrapCSSHTMLJavaScriptAJAX
  • 后端:PHP
  • 数据库:MySQL
  • GitHub源码:一个基于bootstrap框架的简易PHP留言板程序

基本功能

  • 登录、登出和注册
  • 留言的预览与查看
  • 留言的发布、删除与修改
  • 通过标题搜索留言
  • 个人信息的查询

页面展示

登录和注册

留言的预览与查看

留言的发布、修改与删除

查看个人资料

搜索功能

配置方式

bootstrap框架下载

数据库脚本。

代码语言:javascript复制
/*
SQLyog 企业版 - MySQL GUI v8.14 
MySQL - 5.7.26 : Database - comments
*********************************************************************
*/


/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`comments` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `comments`;

/*Table structure for table `comments` */

DROP TABLE IF EXISTS `comments`;

CREATE TABLE `comments` (
  `title` varchar(20) DEFAULT NULL,
  `author` varchar(20) DEFAULT NULL,
  `email` varchar(50) DEFAULT NULL,
  `content` varchar(2500) DEFAULT NULL,
  `time` varchar(30) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

/*Data for the table `comments` */

insert  into `comments`(`title`,`author`,`email`,`content`,`time`) values ('我的第一条留言','tsuki','652240843@qq.com','你好!!!','2022-09-03 15:36:31');

/*Table structure for table `user` */

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (
  `uname` varchar(20) DEFAULT NULL,
  `email` varchar(50) DEFAULT NULL,
  `pswd` varchar(20) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

/*Data for the table `user` */

insert  into `user`(`uname`,`email`,`pswd`) values ('tsuki','652240843@qq.com','123456');

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

修改db.php的配置信息,修改为本机MySQL的用户名密码

代码语言:javascript复制
<?php
	//连接数据库服务器
     $conn=mysqli_connect("localhost","root","root") or die("数据库服务器连接错误".mysql_error()); 
	 mysqli_set_charset($conn,'utf8'); //设定字符集 
?>

使用phpstudy集成环境运行即可。

目录结构

  • css存放CSS层叠样式文件(bootstrap框架)
  • js存放JavaScript源文件(bootstrap框架)
  • login.php登录界面 、loginsuc.php登陆成功界面 、reg.php注册界面 、quit.php实现登出功能
  • board.php为首页所有留言预览展示界面
  • write.phpdelete.phpedit.phpsearch.php实现对留言的增删改查
  • comment.php留言正文展示界面
  • mycmt.php个人发布留言展示界面,myinfo.php个人信息展示界面
  • db.php为数据库连接文件

关键代码分析

登录和注册

直接使用使用bootstrap框架在前端对输入数据进行验证,节省了很多时间。

代码语言:javascript复制
<form action="login.php" class="was-validated">
	  <div class="form-group">
		<label for="uname">Username:</label>
		<input type="text" class="form-control" id="uname" placeholder="Enter username" name="uname" required>
		<div class="invalid-feedback">请输入用户名!</div>
	  </div>
      <div class="form-group">
		<label for="pwd">email:</label>
		<input type="email" class="form-control" id="email" placeholder="Enter email" name="email" required>
		<div class="invalid-feedback">请输入正确格式的邮箱!</div>
	  </div>
	  <div class="form-group">
		<label for="pwd">Password:</label>
		<input type="password" class="form-control" id="pwd" placeholder="Enter password" name="pswd" required>
		<div class="invalid-feedback">请输入密码!</div>
	  </div>
	  <div class="form-group form-check">
		<label class="form-check-label">
		  <input class="form-check-input" type="checkbox" name="remember" required> 同意<a href="xieyi.html">协</a>
		  <div class="invalid-feedback">同意协议能登录!</div>
		</label>
	  </div>
	  <button type="submit" class="btn btn-primary">登录</button>
</form>

登录时根据用户提交的数据来进行数据库的查询,用户名、密码和邮箱均正确后跳转到登陆成功页面。

代码语言:javascript复制
$select = mysqli_select_db($conn,"comments");	
    if($select && isset($_GET['remember'])) {
        // sql语句
        $sql_select = "select uname, email, pswd from user where uname = '$uname' and email = '$email' and pswd = '$pswd'";

        //设置编码
        mysqli_query($conn, 'SET NAMES UTF8');
        //执行sql语句
        $ret = mysqli_query($conn, $sql_select);
        
        if (!$ret) {
            printf("Error: %sn", mysqli_error($conn));
            exit();
        }

		$row = mysqli_fetch_array($ret); 

        if($uname == $row['uname'] && $pswd == $row['pswd'] && $email == $row['email'] && $ret->num_rows > 0){
            //跳转登陆成功页面
            $_SESSION['uname'] = $uname;
            $_SESSION['email'] = $email;
            header('location:loginsuc.php');
        }else{
            //跳转登陆失败页面
            echo '<script>alert("用户名或者密码错误")</script>';
        }

注册界面同理,判断用户提交的邮箱是否已经被注册。

代码语言:javascript复制
if($select && isset($_GET['remember'])) {
        $sql_select = "select email from user where email = '$email'";
        $result = mysqli_query($conn,$sql_select);
		//判断用户名是否已存在
		$num = mysqli_num_rows($result);

        if($num) {
            echo '<script>alert("该用户名或者邮箱已经被注册!")</script>';
        }else{
            $sql_insert = "insert into user(uname,email,pswd) values('$uname','$email','$pswd')";
            $ret = mysqli_query($conn,$sql_insert); 
            echo '<script>alert("注册成功!")</script>';
        }
        mysqli_close($conn);
    }

登录状态

登陆成功后从login.php跳转到login.php,存在可以直接从url定位到成功登录页面的隐患。所以在使用session来存储登录状态。

代码语言:javascript复制
session_start(); //创建session
...
//登录成功后设置session
$_SESSION['uname'] = $uname;
$_SESSION['email'] = $email;

之后在需要登录才能访问的页面添加登录逻辑判断,如果无session则重定向到登录页面。

代码语言:javascript复制
session_start();
$user = $_SESSION["uname"];
if(empty($user)){
    header('location:login.php');
    exit;
 }

实现登出功能就是销毁session

代码语言:javascript复制
<?php
//  退出时清除session,并返回登录界面
session_start();
unset($_SESSION["uname"]);
header("location:login.php");
?>

除了实现登录登出功能,session在个人信息和个人留言管理界面也提供了便利。可以直接从session获取信息而不用经过数据库。

例如个人信息界面,可以直接输出个人信息:

代码语言:javascript复制
session_start();
  $user = $_SESSION["uname"];
  $email = $_SESSION["email"];
  if(empty($user)){
    header('location:login.php');
    exit;
  }else{
    echo '<div class="card" id="myinfo" style="width:400px">
    <img class="card-img-top" src="https://upload-bbs.mihoyo.com/upload/2021/02/21/73745121/889dd95182ad248b035a19fbefe90764_4703068301332017047.png" alt="Card image" style="width:100%">
    <div class="card-body">
      昵称:<h4 class="card-title" id="uname">tsuki</h4>
      邮箱地址:<h4 class="card-text" id="email">652240843@qq.com</p>
      <a href="quit.php" class="btn btn-primary">登出</a>
    </div>';
  }

留言的增删改查

写留言

前端用POST方式提交留言的titlecontentauthoremail直接从session中获取。

时间则通过DataTime对象获取。

代码语言:javascript复制
$user = $_SESSION["uname"];
$email = $_SESSION["email"];
$time = new DateTime();
$time = $time->format('Y-m-d H:i:s');
$title = $_POST['title'];
$content = $_POST['content'];
$sql = "INSERT INTO comments (title, author, email, content, time) 
		VALUES ('" . $title . "','" . $user . "','" . $email . "','" . $content . "','" . $time . "')";
if ($conn->query($sql) === TRUE) {
	echo '<script>alert("发布成功!")</script>';
} else {
	echo '<script>alert("输入字数超出限度!")</script>';
}

删留言

个人留言展示界面直接echo删除留言的按钮并包含当前的留言的标题,并通过GET方式传入delete.php

<a href="delete.php?title=' . $row["title"] . '"><button type="button" class="btn btn-warning">删除留言</button></a>

然后和GET传入的标题与session中的用户邮箱定位到该留言,并将其删除。

delete.php代码如下:

代码语言:javascript复制
<?php
//  删除留言
session_start();
include("db.php");
$select = mysqli_select_db($conn,"comments");
$user = $_SESSION["uname"];
$email = $_SESSION["email"];
if(empty($user)){
  header('location:login.php');
  exit;
}
if(isset($_GET['title'])){
    $title=$_GET['title'];
    $sql = "DELETE FROM comments WHERE title='" . $title . "' and email='" . $email . "'";
    mysqli_query($conn,$sql);
    header("location:mycmt.php");
}
mysqli_close($conn);
?>

改留言

和删除留言类似,个人留言展示界面直接echo修改留言的按钮并包含当前的留言的标题,并通过GET方式传入editcmt.php

<a href="editcmt.php?title=' . $row["title"] . '"><button type="button" class="btn btn-info">修改留言</button></a>

这里用到了AJAXGET传入的标题和session中的邮箱定位到该留言,然后将旧标题与旧文本写入文件。

代码语言:javascript复制
if(isset($_GET['title'])) {
    $title=$_GET['title'];
    $sql = "SELECT title, content FROM comments where title = '" . $title . "' and email = '" . $email . "'"; 
    $result = mysqli_query($conn, $sql);
    $row = mysqli_fetch_assoc($result);
    // 写入旧标题
    $myfile_1 = fopen("change_title.txt", "w") or die("Unable to open file!");
    fwrite($myfile_1, $title);
    fclose($myfile_1);
    // 写入旧文本
    $content = $row['content'];
    $myfile_2 = fopen("change_content.txt", "w") or die("Unable to open file!");
    fwrite($myfile_2, $content);
    fclose($myfile_2);
}

前端JavaScript脚本发送XMLHttpRequest请求获取这两个文件的数据然后输出。

代码语言:javascript复制
// 旧标题
var xmlhttp;
if (window.XMLHttpRequest){
	//  IE7 , Firefox, Chrome, Opera, Safari 浏览器执行代码
	xmlhttp=new XMLHttpRequest();
}else{
	// IE6, IE5 浏览器执行代码
	xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function(){
	if (xmlhttp.readyState==4 && xmlhttp.status==200){
		document.getElementById("biaoti").value=xmlhttp.responseText;
	}
}
xmlhttp.open("GET","/change_title.txt",true);
xmlhttp.send();

所以在未进行修改前,显示的数据为原本数据。之后进行修改就和写类似了。

修改之后提交,更新数据库,然后重定向到显示信留言的页面。

代码语言:javascript复制
if(isset($_POST['title']) && isset($_POST['content'])){
    $ex_title = file_get_contents('change_title.txt');
    $newtitle=$_POST['title'];
    $newcontent=$_POST['content'];
    $sql = "UPDATE comments SET title='" . $newtitle . "', content='" . $newcontent . "' WHERE title='" . $ex_title . "' and email='" . $email . "'";
    mysqli_query($conn,$sql);
    header('location:comment.php?title=' . $newtitle . '&email=' . $email);
}

查留言

查询的逻辑比较简单,因为目前只能将标题打完整才能查询。

留言的预览与查看

预览

comments表中所有数据取出,根据日期降序排列,order by time DESC,实现最新留言展示在最上方。最后将所有留言的预览效果显示在前端。

代码语言:javascript复制
// 按照最新留言排序
  $sql = "SELECT title, author, email, time FROM comments order by time DESC"; 
  $result = mysqli_query($conn, $sql);
 
if (mysqli_num_rows($result) > 0) {
    // 输出数据
    while($row = mysqli_fetch_assoc($result)) {
        echo '<a href="comment.php?title=' . $row["title"] . '&email=' . $row["email"] . '">
        <div class="media border p-3">
        <img src="https://uploadbbs.mihoyo.com/upload/2021/02/21/73745121/
        889dd95182ad248b035a19fbefe90764_4703068301332017047.png" 
        class="mr-3 mt-3 rounded-circle" style="width:60px;">
        <div class="media-body"><h3>标题:' . $row["title"] . '</h3>
        <h6>发布时间:' . $row["time"] . '</h6>
        <h5>留言人:' . $row["author"] . '</h5>
        </div>
        </div></a>';
    }
} else {
  echo "<mark>还没有人发布留言喔!</mark>";
}

查看

在主界面输出留言预览框时,添加了<a href="comment.php?title=' .

代码语言:javascript复制
$sql = "SELECT title, author, time, content FROM comments 
		where title = '" . $title . "' and email = '" . $email . "'"; 
  $result = mysqli_query($conn, $sql);
  if ($result->num_rows > 0) {
    // 输出数据
    while($row = $result->fetch_assoc()) {
        echo '<div class="card">
        <div class="card-body">
          <h4 class="card-title">' . $row["title"] . '</h4><br>
          <p class="card-text">' . $row["content"] . '</p><br>
          <mark>留言人:' . $row["author"] . '</mark>
          <mark>留言时间:' . $row["time"] . '</mark>
        </div>
      </div>';
    }
} else {
    echo "<mark>还没有发布留言喔!</mark>";
}

总结

这是本人初学PHP用于练手的一个简易小项目,花了一天时间,功能并不完善,有很多不足之处。

存在一些开发过程的逻辑错误,还存在一些安全风险,比如SQL注入和XSS。

等待后续深入学习之后再来完善。

0 人点赞