简介
初学
PHP
用来练手的项目。只有一些基本功能。
实现
一个基于bootstrap前端框架,PHP MySQL开发的简易留言板web程序。
- 主题:留言板
- 前端:bootstrap、CSS、HTML、JavaScript、AJAX
- 后端: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的用户名和密码。
<?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.php
、delete.php
、edit.php
、search.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
来存储登录状态。
session_start(); //创建session
...
//登录成功后设置session
$_SESSION['uname'] = $uname;
$_SESSION['email'] = $email;
之后在需要登录才能访问的页面添加登录逻辑判断,如果无session
则重定向到登录页面。
session_start();
$user = $_SESSION["uname"];
if(empty($user)){
header('location:login.php');
exit;
}
实现登出功能就是销毁session
。
<?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
方式提交留言的title
和content
,author
和email
直接从session
中获取。
时间则通过DataTime
对象获取。
$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
代码如下:
<?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>
这里用到了AJAX,GET
传入的标题和session
中的邮箱定位到该留言,然后将旧标题与旧文本写入文件。
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
请求获取这两个文件的数据然后输出。
// 旧标题
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
,实现最新留言展示在最上方。最后将所有留言的预览效果显示在前端。
// 按照最新留言排序
$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。
等待后续深入学习之后再来完善。