PHPbbs系统—后台
时间 2022春节
B站视频地址 https://www.bilibili.com/video/BV1ct411S7nj?spm_id_from=333.337.search-card.all.click
1 通用配置
1.1 静态资源
1.2 数据库
1.2.1 数据库配置信息
<?php
define('DB_HOST', 'localhost');
define('DB_USER', 'root');
define('DB_PASSWORD', '123456');
define('DB_DATABASE', 'sfkbbs');
define('DB_PORT', '3306');
header('Content-type:text/html;charset=utf-8');
1.2.2 数据库工具方法
<?php
//连接数据库,如果连接错误,则输出错误信息
//返回连接钥匙
function connect($host=DB_HOST,$user=DB_USER,$password=DB_PASSWORD,$database=DB_DATABASE,$post=DB_PORT){
$link = @mysqli_connect($host,$user,$password,$database,$post);
if(mysqli_connect_errno()){
exit(mysqli_connect_error());
}
mysqli_set_charset($link, 'utf8');
return $link;
}
//执行一条SQL语句
//返回结果集
function execute($link,$query){
$result = mysqli_query($link, $query);
if(mysqli_errno($link)){
exit(mysqli_error($link));
}
return $result;
}
//一次性执行多条sql语句,如果有错误则输出错误信息
//传入:连接钥匙,sql语句数组;引用地传入错误信息
//返回查询结果集
function execute_multi($link,$arr_sqls,&$error){
$sqls=implode(';',$arr_sqls).';';
if(mysqli_multi_query($link,$sqls)){
$data=array();
$i=0;//计数
do {
if($result=mysqli_store_result($link)){
$data[$i]=mysqli_fetch_all($result);
mysqli_free_result($result);
}else{
$data[$i]=null;
}
$i++;
if(!mysqli_more_results($link)) break;
}while (mysqli_next_result($link));
if($i==count($arr_sqls)){
return $data;
}else{
$error="sql语句执行失败:<br /> 数组下标为{$i}的语句:{$arr_sqls[$i]}执行错误<br /> 错误原因:".mysqli_error($link);
return false;
}
}else{
$error='执行失败!请检查首条语句是否正确!<br />可能的错误原因:'.mysqli_error($link);
return false;
}
}
//获取记录数
function num($link,$sql_count){
$result=execute($link,$sql_count);
$count=mysqli_fetch_row($result);
return $count[0];
}
//结果集语句数量
function execute_num($link,$sql_count){
$execute_result = execute($link, $sql_count);
$execute_num = mysqli_fetch_row($execute_result);
return $execute_num[0];
}
//转义操作!!!!!!!!!!递归函数的应用的一个实例!!!!!!!
function escapes($link, $data){
if (is_string($data)){
$data = mysqli_real_escape_string($link, $data);
return $data;
}
if (is_array($data)){
foreach ($data as $key=>$val){
$data[$key] = escapes($link, $val);
}
}
return $data;
}
//关闭数据库
function close($link){
mysqli_close($link);
}
1.3 二次确认页
<?php
function skip($url,$class,$message){
//!!!注意定界符里面不能解析php标签
//!!!!注意如何在meta里面设置自动跳转语法
$html = <<<A
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta http-equiv="refresh" content="3; URL={$url}"/>
<title>正在跳转</title>
<link rel="stylesheet" type="text/css" href="style/remind.css" />
</head>
<body>
<div class="notice"><span class="pic {$class}"></span>{$message}<a href="{$url}">3秒后自动跳转</div>
</body>
</html>
A;
echo $html;
exit;//不写括号也可以?对
}
?>
2 父板块
2.1 页面展示
2.2 添加
2.3 删除
2.4 修改
3 子板块
3.1 页面展示
任务:显示子版块数据中的所有内容
解决:遍历查询结果集
<?php
include_once '../inc/config.inc.php';//此前不能添加任何信息?
include_once '../inc/mysql.inc.php';
$link = connect();
$template['title'] = '父板块';
?>
<?php include 'inc/header.inc.php';?>
<div id="main">
<div class="title">功能说明</div>
<table class="list">
<tr>
<th>排序</th>
<th>版块名称</th>
<th>所属父版块</th>
<th>版主</th>
<th>操作</th>
</tr>
<?php
$query = "select * from sfk_son_module";
$result = execute($link, $query);
while ($data = mysqli_fetch_assoc($result)){
$html = <<<A
<tr>
<td><input class="sort" type="text" name="sort" /></td>
<td>{$data["module_name"]}[id:{$data["id"]}]</td>
<td>
<a href="#">[访问]</a>
<a href="#">[编辑]</a>
<a href="#">[删除]</a>
</td>
</tr>
A;
echo $html;
}
?>
</table>
</div>
<?php include 'inc/footer.inc.php';?>
3.2 添加
1 添加按钮
2 添加验证
3.3 删除
1 删除按钮
-需求分析以及实现:
1.点击删除按钮,跳转到二次确认页面。
2.在二次确认页面,
-
配置二次确认页面:利用地址传参:1.传入 m e s s a g e u r l ( 提 示 信 息 ) 2. message_url(提示信息) 2. messageurl(提示信息)2.return_url(返回的地址)
-
点击确认删除按钮:跳转到后台的子版块删除页面,根据传入的id值,执行数据库删除操作。
- 如何跳转到后台的子版块删除页面:利用地址传参
- 如何传递id值:利用地址传参
-
点击取消按钮:不删除。
-
点击最终结果:1.自动跳转回子版块展示页面 (需要重新查询数据库,而更新页面)
<?php
include_once '../inc/config.inc.php';//此前不能添加任何信息?
include_once '../inc/mysql.inc.php';
$link = connect();
$template['title'] = '父板块';
?>
<?php include 'inc/header.inc.php';?>
<div id="main">
<div class="title">功能说明</div>
<table class="list">
<tr>
<th>排序</th>
<th>版块名称</th>
<th>所属父版块</th>
<th>版主</th>
<th>操作</th>
</tr>
<?php
$query = "select * from sfk_son_module";
$result = execute($link, $query);
while ($data = mysqli_fetch_assoc($result)){
//通过传递url来让目的页面可以跳转传递过来的指定页面
//注意!!!为了返回url参数注入,不能直接传递【url+url参数】,需要以下两种办法传递
$delete_url = urlencode("son_module_delete.php?id={$data['id']}");//如果这边用字符串形式设置url参数,要注意双引号入住
$return_url = urlencode($_SERVER['REQUEST_URI']);//!!!获取当前页面的url!!!
$message_url = urldecode("{$data["module_name"]}");
$confirm_ulr = "confirm.php?delete_url={$delete_url}&return_url={$return_url}&message_url={$message_url}";
//!!!!记住这种定界符写法!!!!
$html = <<<A
<tr>
<td><input class="sort" type="text" name="sort" /></td>
<td>{$data["module_name"]}[id:{$data["id"]}]</td>
<td>
<a href="#">[访问]</a>
<a href="son_module_update.php?id={$data['id']}">[编辑]</a>
<a href="$confirm_ulr">[删除]</a>
</td>
</tr>
A;
echo $html;
}
?>
</table>
</div>
<?php include 'inc/footer.inc.php';?>
2 父板块删除补充
**-需求:**当父板块存在子板块时,作删除操作,需要二次确认。
<?php
include_once '../inc/config.inc.php';
include_once '../inc/mysql.inc.php';
include_once '../inc/tool.php';
$url = "father_module.php";
if(!isset($_GET["id"]) || !is_numeric($_GET["id"])){//$_GET["id"]其实就是一个以字符串为索引的数组
skip($url, "error", "id参数不存在!");
}//!!!注意!!!在此处如果不设置停止,其会继续执行下面语句,所以需要停止,停止方式有多种看详情!!!!!
$link = connect();
/**
* 若父板块存在子板块(若子板块存在父板块)
* 则当删除该父板块时,需要二次确认。
*/
$query = "select * from sfk_son_module where father_module_id = {$_GET['id']}";
$result = execute($link, $query);
if (mysqli_num_rows($result)){
skip($url, 'error', '该父板块存在子板块!需要先删除对应子版块!');
}
$query = "delete from sfk_father_module where id = {$_GET['id']}";
execute($link, $query);
if (mysqli_affected_rows($link) == 1){
skip($url, "ok", "恭喜删除成功!");
}else {
skip($url, "error", "删除失败!");
}
//!!!!url地址传递参数,传递的其实是字符串,在其显示上省略了双引号
3.4 修改
1 修改按钮
<?php $template['title'] = '子版块-修改'?>
<?php include '../inc/config.inc.php';?>
<?php include '../inc/mysql.inc.php';?>
<?php include '../inc/tool.php'?>
<?php
//1,对传入的id值验证
/*
* 问题:在地址栏输入错误的id
* 跳转回页面
*/
if (!isset($_GET['id']) || !is_numeric($_GET['id'])){
skip("son_module_update.php", "error", "id参数错误");
}
/*
* 问题:对编辑的板块,其信息不存在
* 跳转回页面
*/
$link = connect();
$query = "select * from sfk_son_module where id='{$_GET['id']}'" ;//注意这里需要用get而不是post,因为是通过url地址传递参数
$result = execute($link, $query);
if(!mysqli_num_rows($result)){
skip("son_module_update.php", "error", "该板块信息不存在");
}
//对传递的要修改的内容验证。
/*
* 设置当按下提交后,才执行数据库修改操作
*/
$data = mysqli_fetch_assoc($result);//将结果集转化为数组的形式
if(isset($_POST['submit'])){
/*
* 对插入语句参数,处理
*/
$check_flag = 'update';
include 'inc/check_son_module.inc.php';
/*
* 执行修改语句
*/
$query = "update sfk_son_module set
father_module_id ='{$_POST['father_module_id']}',
module_name = '{$_POST['module_name']}',
info='{$_POST['info']}',
sort={$_POST['sort']} ,
member_id={$_POST['member_id']}
where id ={$_GET['id']} ";
$result = execute($link, $query);
/*
* 判断修改是否成功
*/
if(mysqli_affected_rows($link) == 1){//传入参数是数据库钥匙!!!!
skip('son_module.php', 'ok', '修改成功!');
}else {
skip('son_module.php', "error", '修改失败!');
}
}
?>
<?php include 'inc/header.inc.php';?>
<div id="main">
<div class="title" style="margin-bottom: 20px;">功能说明</div>
<form method="post">
<table class="au">
<tr>
<td>所属父板块</td>
<td>
<select name="father_module_id">
<option value = "0">======请选择一个父版块======</option>
<?php
$query = "select * from sfk_father_module";
$result = execute($link, $query);
while ($data_father = mysqli_fetch_assoc($result)){
if($data['father_module_id'] == $data_father['id']){
//让其被选中
echo "<option selected='selected' value = '{$data_father['id']}'>{$data_father['module_name']}</option>";
}else {
echo "<option value = '{$data_father['id']}'>{$data_father['module_name']}</option>";
//此处不能用双引号
}
}
?>
</select>
</td>
<td>
不得选择空值
</td>
</tr>
<tr>
<td>版块名称</td>
<td><input name="module_name" type="text" value="<?php echo $data['module_name']?>" /></td>
<td>
版块名称不得为空,最大不得超过66个字符
</td>
</tr>
<tr>
<td>版块简介</td>
<td>
<textarea name="info"><?php echo $data['info']?></textarea>
</td>
<td>
简介不得多于255个字符
</td>
</tr>
<tr>
<td>版主</td>
<td>
<select name="member_id">
<option value="0">======请选择一个会员作为版主======</option>
</select>
</td>
<td>
你可以在这边选一个会员作为版主
</td>
</tr>
<tr>
<td>排序</td>
<td><input name="sort" value="<?php echo $data['sort']?>" type="text" /></td>
<td>
填写一个数字即可
</td>
</tr>
</table>
<input style="margin-top: 20px; cursor:pointer" class="btn" type="submit" name="submit" value="修改" />
</form>
</div>
<?php include_once 'inc/footer.inc.php';?>
2 修改验证
<?php
/*
* 父板块下拉列表——判断是否选择——根据传参是否为空
*/
if(!is_numeric($_POST['father_module_id'])){
skip('son_module_add.php', 'error', '所属父板块不能为空!');
}//注意!!!!!!url的参数都是字符串!!没有什么特殊符号之分
// if(!is_string($_POST['father_module'])){
// skip('father_module_add.php', 'error', '不能输入特殊符号');
// }
/*
* 父板块下拉列表——父板块是否存在——根据传参的id
* 细节:!!!问题处理:对sql注入的毛病!!!!
*/
$link = connect();
$query="select * from sfk_father_module where id={$_POST['father_module_id']}";
$result = execute($link, $query);
if(mysqli_num_rows($result)==0){
skip('son_module_add.php','error','所属父版块不存在!');
}
/*
* 版块名称——判断是否为空;是否大于66个字符数量;是否已经存在——根据传入名字的参数
* 例外:对修改操作,联合判断两个:id、板块名称
*/
if (empty($_POST['module_name'])){
skip('son_module_add.php', 'error', '子版块名称不能为空!');
}
if(mb_strlen($_POST['module_name']) > 66){
skip('son_module_add.php', 'error', '输入的字符数量大于了66!');
}
$_POST = escapes($link, $_POST);
switch ($check_flag){
case 'add':
$query="select * from sfk_son_module where module_name='{$_POST['module_name']}'";
break;
case 'update':
$query="select * from sfk_son_module where module_name='{$_POST['module_name']}' and id!={$_GET['id']}";//!!!!巧妙:!!!此处可以写id也可以写sort去判断!!!!
break;
default:
skip('father_module_add.php','error','$check_flag参数错误!');
}
$result = execute($link, $query);
if (mysqli_num_rows($result)){
skip('son_module_add.php', 'error', '该子板块已经存在!');
}
/*
* 判断简介和排序
*/
if(mb_strlen($_POST['info'])>255){
skip('son_module_add.php','error','子版块简介不得多于255个字符!');
}
if(!is_numeric($_POST['sort'])){
skip('son_module_add.php','error','排序只能是数字!');
}
3 侧边栏
-任务:当编辑时,添加编辑按钮
<?php
?>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<!-- !!!!此处利用天然条件判断!!!变量得以发挥其作用 -->
<title><?php echo $template['title']?></title>
<meta name="keywords" content="后台界面" />
<meta name="description" content="后台界面" />
<link rel="stylesheet" type="text/css" href="style/public.css" />
</head>
<body>
<div id="top">
<div class="logo">
管理中心
</div>
<ul class="nav">
<li><a href="http://www.sifangku.com" target="_blank">私房库</a></li>
<li><a href="http://www.sifangku.com" target="_blank">私房库</a></li>
</ul>
<div class="login_info">
<a href="#" style="color:#fff;">网站首页</a> |
管理员: admin <a href="#">[注销]</a>
</div>
</div>
<div id="sidebar">
<ul>
<li>
<div class="small_title">系统</div>
<ul class="child">
<li><a class="current" href="#">系统信息</a></li>
<li><a href="#">管理员</a></li>
<li><a href="#">添加管理员</a></li>
<li><a href="#">站点设置</a></li>
</ul>
</li>
<li><!-- class="current" -->
<div class="small_title">内容管理</div>
<ul class="child"><!--SCRIPT_NAME:script_name--> <!-- 先输出在html页面 -->
<li><a class="<?php if(basename($_SERVER['SCRIPT_NAME']) == "father_module.php"){echo 'current';}?>" href="father_module.php">父板块列表</a></li>
<li><a class="<?php if(basename($_SERVER['SCRIPT_NAME'])== "father_module_add.php"){echo 'current';}?>" href="father_module_add.php">添加父板块</a></li>
<?php
if(basename($_SERVER['SCRIPT_NAME']) == "father_module_update.php"){
echo '<li><a class="current">编辑父板块</a></li>';
}
?>
<li><a class="<?php if(basename($_SERVER['SCRIPT_NAME'])== "son_module.php"){echo 'current';}?>" href="son_module.php">子板块列表</a></li>
<li><a class="<?php if(basename($_SERVER['SCRIPT_NAME'])== "son_module_add.php"){echo 'current';}?>" href="son_module_add.php">添加子板块</a></li>
<?php
if(basename($_SERVER['SCRIPT_NAME']) == "son_module_update.php"){
echo '<li><a class="current">编辑子板块</a></li>';
}
?>
<li><a href="#">帖子管理</a></li>
</ul>
</li>
<li>
<div class="small_title">用户管理</div>
<ul class="child">
<li><a href="#">用户列表</a></li>
</ul>
</li>
</ul>
</div>
- 报错:
Unknown column 'asdasdsdfcasd' in 'field list'
- 翻译:不知道这个字段是什么。原因:可能是sql语句的字段名类型写错了
4 父板块排序
4.1 获取排序
<?php
include_once '../inc/config.inc.php';//此前不能添加任何信息?
include_once '../inc/mysql.inc.php';
$link = connect();
$template['title'] = '父板块';
?>
<?php include 'inc/header.inc.php';?>
<div id="main">
<div class="title">功能说明</div>
<form method="post">
<table class="list">
<tr>
<th>排序</th>
<th>版块名称</th>
<th>操作</th>
</tr>
<?php
$query = "select * from sfk_father_module";
$result = execute($link, $query);
while ($data = mysqli_fetch_assoc($result)){
//通过传递url来让目的页面可以跳转传递过来的指定页面
//注意!!!为了返回url参数注入,不能直接传递【url+url参数】,需要以下两种办法传递
$delete_url = urlencode("father_module_delete.php?id={$data['id']}");//如果这边用字符串形式设置url参数,要注意双引号入住
$return_url = urlencode($_SERVER['REQUEST_URI']);//!!!获取当前页面的url!!!
$message_url = urldecode("{$data["module_name"]}");
$confirm_ulr = "confirm.php?delete_url={$delete_url}&return_url={$return_url}&message_url={$message_url}";
//!!!!记住这种定界符写法!!!!
$html = <<<A
<tr>
<td><input class="sort" type="text" name="sort[{$data['id']}]" value="{$data['sort']}" /></td>
<td>{$data["module_name"]}[id:{$data["id"]}]</td>
<td><a href="#">[访问]</a> <a href="father_module_update.php?id={$data['id']}">[编辑]</a> <a href="$confirm_ulr">[删除]</a></td>
</tr>
A;
echo $html;
}
?>
</table>
<input style="margin-top:20px;cursor:pointer;" class="btn" type="submit" name="submit" value="排序" />
</form>
</div>
<?php include 'inc/footer.inc.php';?>
4.2 修改排序
-问题?:
- 在这种情况下,同名参数如何包含多个参数值?
- 如何一次性执行多个数据库操作?
**-细节:**1.引入方法。2.验证传入sql
语句的参数 (排序只能是数字,否则sql语句错误)。3.注意if_else语句
<?php
include_once '../inc/config.inc.php';//此前不能添加任何信息?
include_once '../inc/mysql.inc.php';
include_once '../inc/tool.php';
$link = connect();
if(isset($_POST['submit'])){
foreach ($_POST['sort'] as $key=>$value){
/**
* 若传入的id 和 sort不是数字
* 则报错
*/
if(!is_numeric($value) || !is_numeric($key)){
skip("father_module.php", "error", "排序只能是数字");
}//不需要else,因为前面错误会跳转
$query[] = "update sfk_father_module set sort={$value} where id={$key}";
// echo $query[];//不能直接输出数组
}
if(execute_multi($link, $query, $error)){
skip("father_module.php", "ok", "排序修改成功!");
}else {//要写else, 否则无论如何 都会执行跳转。
skip("father_module.php", "error", $error);
}
}
$template['title'] = '父板块';
?>
<?php include 'inc/header.inc.php';?>
<div id="main">
<div class="title">功能说明</div>
<form method="post">
<table class="list">
<tr>
<th>排序</th>
<th>版块名称</th>
<th>操作</th>
</tr>
<?php
$query = "select * from sfk_father_module";
$result = execute($link, $query);
while ($data = mysqli_fetch_assoc($result)){
//通过传递url来让目的页面可以跳转传递过来的指定页面
//注意!!!为了返回url参数注入,不能直接传递【url+url参数】,需要以下两种办法传递
$delete_url = urlencode("father_module_delete.php?id={$data['id']}");//如果这边用字符串形式设置url参数,要注意双引号入住
$return_url = urlencode($_SERVER['REQUEST_URI']);//!!!获取当前页面的url!!!
$message_url = urldecode("{$data["module_name"]}");
$confirm_ulr = "confirm.php?delete_url={$delete_url}&return_url={$return_url}&message_url={$message_url}";
//!!!!记住这种定界符写法!!!!
$html = <<<A
<tr>
<td><input class="sort" type="text" name="sort[{$data['id']}]" value="{$data['sort']}" /></td>
<td>{$data["module_name"]}[id:{$data["id"]}]</td>
<td><a href="#">[访问]</a> <a href="father_module_update.php?id={$data['id']}">[编辑]</a> <a href="$confirm_ulr">[删除]</a></td>
</tr>
A;
echo $html;
}
?>
</table>
<input style="margin-top:20px;cursor:pointer;" class="btn" type="submit" name="submit" value="排序" />
</form>
</div>
<?php include 'inc/footer.inc.php';?>
5 子版块排序
<?php
include_once '../inc/config.inc.php';//此前不能添加任何信息?
include_once '../inc/mysql.inc.php';
include_once '../inc/tool.php';
$link = connect();
$template['title'] = '子板块展示';//页面标题
if(isset($_POST['submit'])){
foreach ($_POST['sort'] as $key=>$val){
if(!is_numeric($val) || !is_numeric($key)){
skip('son_module.php','error','排序参数错误!');
}
$query[]="update sfk_son_module set sort={$val} where id={$key}";
}
if(execute_multi($link,$query,$error)){
skip('son_module.php','ok','排序修改成功!');
}else{
skip('son_module.php','error',$error);
}
}
?>
<?php include 'inc/header.inc.php';?>
<div id="main">
<div class="title">功能说明</div>
<form method="post">
<table class="list">
<tr>
<th>排序</th>
<th>版块名称</th>
<th>所属父版块</th>
<th>版主</th>
<th>操作</th>
</tr>
<?php
$query="select ssm.id,ssm.sort,ssm.module_name,sfm.module_name father_module_name,ssm.member_id from sfk_son_module ssm,sfk_father_module sfm where ssm.father_module_id=sfm.id order by sfm.id";
$result = execute($link, $query);
while ($data = mysqli_fetch_assoc($result)){
//通过传递url来让目的页面可以跳转传递过来的指定页面
//注意!!!为了返回url参数注入,不能直接传递【url+url参数】,需要以下两种办法传递
$delete_url = urlencode("son_module_delete.php?id={$data['id']}");//如果这边用字符串形式设置url参数,要注意双引号入住
$return_url = urlencode($_SERVER['REQUEST_URI']);//!!!获取当前页面的url!!!
$message_url = urldecode("{$data["module_name"]}");
$confirm_ulr = "confirm.php?delete_url={$delete_url}&return_url={$return_url}&message_url={$message_url}";
//!!!!记住这种定界符写法!!!!
$html = <<<A
<tr>
<td><input class="sort" type="text" name="sort[{$data['id']}]" value="{$data['sort']}" /></td>
<td>{$data["module_name"]}[id:{$data["id"]}]</td>
<td>
<a href="#">[访问]</a>
<a href="son_module_update.php?id={$data['id']}">[编辑]</a>
<a href="$confirm_ulr">[删除]</a>
</td>
</tr>
A;
echo $html;
}
?>
</table>
<input style="margin-top:20px;cursor:pointer;" class="btn" type="submit" name="submit" value="排序" />
</form>
</div>
<?php include 'inc/footer.inc.php';?>
修改样式失效问题
问题描述:修改样式后,在页面没有生效:
- 需要清空浏览器缓存
- 页面编码格式不一致导致