CMS 实现过程(重点)
一. 程序结构介绍
1. 目录结构介绍
— cms 程序根目录
-- cms.sql 数据库导出文件,可通过导入建立系统数据库-- controller.php 服务端接口处理程序-- js js相关文件(jQuery)-- css css 样式相关文件-- res 程序中的图片资源文件-- KindEditor 富文本编辑器-- home 前台页面文件-- admin 后台页面文件
2. 前后端交互过程
- 基本通信过程示意图
  - 页面加载过程示意图
  - 实现过程示意图
 

2.1 交互过程功能模块划分
- index.html 负责前端页面的展示
 - controller.php 负责后端业务的逻辑处理
 - Database 负责数据的处理
 
2.2 交互过程实现步骤
- 步骤一 页面基本布局框架实现与加载
 - 步骤二 通过Ajax向服务端发起请求,获取页面需要显示的数据
 - 步骤三 服务端接收客户端请求,并根据传递的参数进行业务的区分
 - 步骤四 在接口函数中通过PDO向数据库发起查询,并将查询结果返回
 - 步骤五 Ajax成功回调函数中接收服务端返回的数据,并将数据展示到页面中
 
2.3 按步骤实现过程
步骤一
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>p{width: 800px;height: 50px;margin: 0 auto;margin-top: 100px;line-height: 50px;text-align: center;font-weight: bold;font-size: 20px;}div{width: 800px;height: 50px;background: red;margin: 0 auto;line-height: 50px;text-align: center;}ul{list-style: none;display: flex;justify-content: space-between;padding: 0;}</style></head><body><p>静态页面</p><div id="staticNav"><ul><li><a href="list.html?id=1">创业资讯</a></li><li><a href="list.html?id=3">创业指导</a></li><li><a href="list.html?id=2">创业故事</a></li><li><a href="list.html?id=5">创业点子</a></li><li><a href="list.html?id=4">职场江湖</a></li><li><a href="list.html?id=6">求职攻略</a></li><li><a href="list.html?id=7">故事语录</a></li><li><a href="about.html">关于我们</a></li></ul></div><p>动态加载数据</p><div id="Nav"></div></body></html>
步骤二
<script src="../cms/js/jquery-1.11.3.js"></script><script>$(function(){$.get('controller.php',{"a":"getNavData"},function(data){},'json');});</script>
步骤三
```php <?php header(“content-type:text/html;charset=utf-8”);// 获取请求参数,进行业务判断 $act = $_GET[‘a’]; if($act == “getNavData”){
// 调用对应的业务处理函数getNavData();
}
?>
- 步骤四```php<?php// 数据库封装函数function queryAll($sql){$url = "mysql:host=localhost;dbname=cms";$user = "root";$pwd = "";$conn = new PDO($url,$user,$pwd);$st = $conn->query($sql);$rs = $st->fetchAll(PDO::FETCH_ASSOC);return $rs;}// 业务处理函数function getNavData(){$class = queryAll("select id,name from class where type=0 order by sort");echo json_encode($class);}?>
步骤五
// Ajax 成功回调函数$.get('controller.php',{"a":"getNavData"},function (data){// 用于拼接内容的字符串var html = "<ul>";for(var i=0;i<data.length;i++){var o = data[i];html += "<li><a href='list.html?id=" + o.id + "'>" + o.name +"</a></li>";}html += "<li><a href='about.html'>关于我们</a></li>";html += "</ul>";// 将拼接内容设置到页面中$("#Nav").html(html);},"json");
3. Controller.php 服务端Ajax请求处理程序
<?phpheader("content-type:text/html;charset=utf-8");session_start();/*** Ajax的处理类*///########【页面Ajax逻辑处理】########################################$module = $_GET["m"]; //访问的模块:前台home、后台admin$act = ""; //操作if($module == "home"){//前台$act = $_GET["a"];}elseif ($module == "admin"){// 后台$act = $_GET["a"];}//########【前台接口函数封装函数】########################################//########【后台接口函数封装函数】########################################################################//########【MySQL封装函数】###############################################// 查询多条记录, 返回结果的二维数组function queryAll($sql){$url = "mysql:host=localhost;dbname=cms";$user = "root";$pwd = "";$conn = new PDO($url,$user,$pwd);$st = $conn->query($sql);$rs = $st->fetchAll(PDO::FETCH_ASSOC);return $rs;}// 查询单条记录,返回结果的一维数组function queryOne($sql){$url = "mysql:host=localhost;dbname=cms";$user = "root";$pwd = "";$conn = new PDO($url,$user,$pwd);$st = $conn->query($sql);$rs = $st->fetch(PDO::FETCH_ASSOC);return $rs;}// 执行增删改,返回影响结果function execute($sql){$url = "mysql:host=localhost;dbname=cms";$user = "root";$pwd = "";$conn = new PDO($url,$user,$pwd);$row = $conn->exec($sql);return $row;}
二. 前台页面实现
1. index.html
index页面功能模块

1.1 获取展示分类标题
- 请求目标: 前台
m=home - 请求动作: 
a=getClass 
controller.php
if($act == "getClass"){getClass();}// 获取分类函数function getClass(){//获得所有分类$class = queryAll("select id,name from class where type=0 order by sort");echo json_encode($class);}
页面中getClass函数
//获得所有分类function getClass(){// 发起请求,获取分类数据$.get("../controller.php?m=home&a=getClass",function(data){// 拼接 页头和页脚的内容var p1 = "<ul>";// 页头的导航条需要,页脚不需要var p2 = "<li><a href='index.html'>首页</a></li>";// 中间分类内容var p3 = "";// 遍历请求返回的数据for(var i=0;i<data.length;i++){// 拿到数据var o = data[i];//使用字符串形式拼接页面内容,点击跳转后传入分类的id,方便对应页面获取该类的数据p3 += "<li><a href='list.html?id=" + o.id + "'>" + o.name +"</a></li>";}p3 += "<li><a href='about.html'>关于我们</a></li>";p3 += "</ul>";// 页头包含首页var s1 = p1 + p2 + p3;// 页脚不包含首页var s2 = p1 + p3;// 分别设置页头和页脚// 通过标签名 header 找到页面位置,并将内容显示到页面中$("header").html(s1);// 通过ID名 footer 找到页面位置,并将内容显示到页面中$("#footer").html(s2);},"json");}
1.2 获取展示分类数据(重点)
- 请求目标: 前台
m=home - 请求动作: 
a=getClassData 
controller.php
// 路由判断...else if($act == "getClassData"){getClassData();}...// 获取分类数据函数function getClassData(){// 返回数据格式/*** [[name: 标题 , items:[item1, item2,... ], ...]*/$data = [];// 先获取分类标题$class = queryAll("select id, name from class where type=0 order by sort");// 遍历标题,获取每个标题对应的数据foreach($class as $obj){//获得所有分类中按时间排序后的前5条数据$items= queryAll("select id, title, images, click from content where classId={$obj['id']} order by date desc limit 5");// 创建一个关系数组,使用分类名做为key, 使用分类对应数据做为 Value$tmp = ["name"=>$obj['name'], "items"=>$items];// 添加到数组中$data[] = $tmp;}// 最后返回的是一个索引数组,对应的每个元素是每一个分类的关系数组echo json_encode($data);}
页面中getClassData函数
//获得所有分类数据function getClassData(){$.get("../controller.php?m=home&a=getClassData",function(data){// 调用页面内容设置函数来设置内容setContent( data );},"json");}// 设置页面内容function setContent(data){// 每一个分类,都被单独的放到一个section标签中// 该标签中包含分类标题和分类内容两部分for(var i=0;i<data.length;i++){var html = "";// 获取单个分类var item = data[i];// 设置分类标题html += '<div class="title">';html += '<img src="../res/icon_text3.png" />' + item.name;html += '</div>';// 追加到页面中$("#s"+i).append(html);// 获取内容数组var items = item.items;// 拼接行内分页内容itemvar row = "";row += '<div class="row">';for(var j=0;j<items.length;j++){var o = items[j];row += '<div>';row += '<img src="' + o.images + '"/>';row += '<div class="t">' + o.title + '</div>';row += '<div class="msg">';row += '<div>' + item.name + '</div>';row += '<div>人气:'+ o.click + '</div>';row += '</div>';row += '</div>';}row += '</div>';$("#s"+i).append(row);}}
1.3 获取展示排序数据
- 请求目标: 前台
m=home - 请求动作: 
a=getRank 
controller.php
// 路由判断...else if($act == 'getRank'){getRank();}...// 获取推荐排行函数function getRank(){// 查询排行数据$rank = queryAll('select id, title from content order by homePageWeight desc limit 10;');// 服务端返回数据的另一种形式,直接返回拼接好的页面中要显示的内容$html = '';foreach($rank as $v){// 通过查询结果拼接 html 代码,将文章 ID 做为参数放到地址中,在跳转内容页面时,// 可以通过ID获取该页面的内容$html .= "<li><span>.</span> <a href='content.html?id={$v['id']}'>{$v['title']}</a></li>";}echo $html;}
页面中getRank函数
// 获取新闻排行function getRank(){$.get("../controller.php?m=home&a=getRank",function(data){// 因为请求返回的数据就是页面的HTML代码,所以直接添加到页面中$("#rank").html(data);});}
1.4 获取展示ICP备案信息
- 请求目标: 前台
m=home - 请求动作: 
a=getIcp 
controller.php
// 路由判断else if($act == "getIcp"){getIcp();}// 获取备案信息的内容function getIcp(){$icp = queryAll('select IcpId from website;');echo json_encode($icp);}
页面中的getICP函数
// 获取备案号function getIcp(){$.get("../controller.php",{'m':"home",'a':"getIcp"},function (data){$('#icp').html(data[0].IcpId);},"json");}
1.5 获取展示轮播图数据(重点)
- 请求目标: 前台
m=home - 请求动作: 
a=getIcp 
controller.php
// 路由判断else if($act == "getLbt"){getLbt();}// 获取轮播图数据function getLbt(){$imgs = queryAll('select sort,name,url from rotationchart order by sort;');echo json_encode($imgs);}
页面中的getLbt函数及轮播图按钮事件绑定函数
// 获取轮播图数据function getLbt(){$.get("../controller.php",{'m':"home",'a':"getLbt"},function (data){lbtImgs = data;var obj = lbtImgs[0];$(".lbt img").attr({"src":obj.url});$(".lbt>.txt").html(obj.name);},"json");}// 绑定事件方法function bindEvent(){$(".leftBtn").click(function(){lbtIdx--;if(lbtIdx < 0) lbtIdx = lbtImgs.length-1;var obj = lbtImgs[lbtIdx];$(".lbt img").attr({"src":obj.url});$(".lbt>.txt").html(obj.name);console.log("left");});$(".rightBtn").click(function(){lbtIdx++;if(lbtIdx == lbtImgs.length) lbtIdx = 0;var obj = lbtImgs[lbtIdx];$(".lbt img").attr({"src":obj.url});$(".lbt>.txt").html(obj.name);console.log("right");});}
2. list.html
list页面功能模块

2.1 导航,页脚,备案信息可复用index.html内容
- 请求目标: 前台
m=home - 导航,页脚 
- 请求动作: 
a=getClass 
 - 请求动作: 
 - 备案信息 
- 请求动作: 
a=getIcp 
 - 请求动作: 
 
2.2 获取推荐文章
- 请求目标: 前台
m=home - 请求动作: 
a=getListTj 
controller.php
// 路由判断...else if($act == "getListTj"){getListTj();}...// 获取推荐文章function getListTj(){$tj = queryAll("select id,title,images from content order by classificationWeight desc limit 4;");echo json_encode($tj);}
页面中getListTj函数实现
// 获取推荐文章function getListTj(){$.get("../controller.php",{"m":"home","a":"getListTj"},function(data){var html = "";for(var i=0;i<data.length;i++){var o = data[i];html += "<div>";html += " <div><img src='" + o.images+ "' /></div>";html += " <div><a href='content.html?id=" + o.id +"'>" + o.title + "</a></div>";html += "</div>";}$("#tj").append(html);},"json");}
2.3 获取热门浏览
- 请求目标: 前台
m=home - 请求动作: 
a=getListHot 
controller.php
// 路由判断...else if($act == "getListHot"){getListHot();}...// 获取热门浏览function getListHot(){$hot = queryAll("select id,title from content order by click desc limit 10;");echo json_encode($hot);}
页面中getListHot函数实现
// 获取热门浏览function getListHot(){$.get("../controller.php",{"m":"home","a":"getListHot"},function(data){var html = "";for(var i=0;i<data.length;i++){var o = data[i];html += '<li><span>.</span> <a href="content.html?id='+o.id+'">' +o.title+ '</a></li>';}$("#hot").html(html);},"json");}
2.4 获取站点分类
- 请求目标: 前台
m=home - 请求动作: 
a=getSiteClass 
controller.php
// 路由判断...else if($act == "getSiteClass"){getSiteClass();}...// 获取网站分类function getSiteClass(){$sc = queryAll("select id, name from class order by sort;");echo json_encode($sc);}
页面中getSiteClass函数实现
// 获取侧边栏网站分类function getSiteClass(){$.get("../controller.php?m=home&a=getSiteClass",function(data){var html = "";for(var i=0;i<data.length;i++){var o = data[i];html += '<li><span>.</span> <a href="list.html?id='+ o.id +'">' + o.name + '</a></li>';}$("#siteClass").html(html);},"json");}
2.5 获取友情链接
- 请求目标: 前台
m=home - 请求动作: 
a=getLinks 
controller.php
// 路由判断...else if($act == "getLinks"){getLinks();}...// 获取友情链接function getLinks(){$links = queryAll("select id,name,url from links;");echo json_encode($links);}
页面中getLinks函数实现
// 获取友情链接function getLinks(){var html = '';$.get("../controller.php",{"m":"home","a":"getLinks"},function (data){for(var i=0;i<data.length;i++){var o = data[i];html += '<li><span>.</span> <a href="'+ o.url+'">' + o.name + '</a></li>';}$("#links").html(html);},"json");}
2.6 获取列表页面内容(重点)
- 请求目标: 前台
m=home - 请求动作: 
a=getContent 
controller.php
// 路由判断...else if($act == "getContent"){// 获取分类ID和当前页数$cid = $_GET["cid"];$page = isset($_GET["page"]) ? $_GET["page"] : 1;getContent($cid, $page);}...// 获取内容function getContent($cid, $page){// 页面显示的记录数$pageNum = 8;// 获取分类名$c = queryOne("select name from class where id = {$cid}");// 获取总记录数$allNum = queryAll("select count(*) as num from content where classId = {$cid}")[0]["num"];// 获取分类的内容$startPage = ($page-1) * $pageNum;$contents = queryAll("select id,title,images,date,content from content where classId = {$cid} limit {$startPage}, {$pageNum}");// 总页数$allPage = ceil($allNum / $pageNum);// 页码的配置信息$pageInfo = ["currentPage"=>$page, "allPage"=> $allPage];// 组合页面信息$tmp = ["name"=>$c["name"], "content"=>$contents, "pageInfo"=>$pageInfo];echo json_encode($tmp);}
页面中getContent函数实现
// 获取内容function getContent(){// 通过请求地址将分类ID取出来var cid = window.location.href.split("id=")[1];console.log(cid);$.get("../controller.php",{"m":"home","a":"getContent","cid":cid},function(data){// 将返回的数据,做为参数传给 setPageContent函数,来设置页面内容setPageContent(cid, data);},"json")}// 设置页面内容的函数,用来首次请求和页码响应后,获取数据展示到页面中function setPageContent(cid, data){var cn = data.name;var content = data.content;// 设置分类标题$("#className").html(cn);// 拼接内容var html = "";// 添加导航下面的背景图片html += '<div class="t">';html += ' <img src="../res/bg2.jpg" />';html += '</div>';for(var i=0;i<content.length;i++){var o = content[i];// 截取内容中的第一段内容做为简单描述var desc = o.content.split('</p>')[0];// 去掉内容p标签上的样式desc = desc.split('">')[1].trim();// 处理时间date = o.date.split(" ")[0];// 拼接页面内容html += '<div class="row">';html += ' <img src="' + o.images +'" />';html += ' <div>';html += ' <div> <a href="content.html?id=' + o.id + '">'+ o.title +'</a> </div>';html += ' <div class="desc">' + desc+ '</div>';html += ' <div>';html += ' <img src="../res/icon_time.png" />' + date;html += ' </div>';html += ' </div>';html += '</div> ';}// 设置页码内容var pageInfo = data.pageInfo;html += "<ul class='page_list'>";html += " <li onclick=getPageContent("+ cid + "," + 1 +")>首页</li>";var prePage = pageInfo.currentPage == 1? 1 : pageInfo.currentPage - 1;html += " <li onclick=getPageContent("+ cid + "," + prePage +")>前一页</li>";for(var i=1;i<=pageInfo.allPage;i++){if(i == pageInfo.currentPage)// 绑定分页获取数据的方法html += " <li class='num active' onclick=getPageContent("+ cid + "," + i +")>" + i + "</li>";elsehtml += " <li class='num' onclick=getPageContent("+ cid + "," + i +")>" + i + "</li>";}var nextPage = pageInfo.currentPage == pageInfo.allPage ? pageInfo.allPage : parseInt(pageInfo.currentPage) + 1;html += " <li onclick=getPageContent("+ cid + "," + nextPage +")>后一页</li>";html += " <li onclick=getPageContent("+ cid + "," + pageInfo.allPage +")>尾页</li>";html += "</ul>";// 先将页面中原来的内容清空$("#list_content").empty();// 将新内容添加到页面中$("#list_content").append(html);}
2.7 获取分页内容(重点)
- 请求目标: 前台
m=home - 请求动作: 
a=getContent 
controller.php
// 路由判断...else if($act == "getContent"){// 获取分类ID和当前页数$cid = $_GET["cid"];$page = isset($_GET["page"]) ? $_GET["page"] : 1;getContent($cid, $page);}...
页面中getPageContent函数实现
// 获取分页数据的内容function getPageContent(cid,page){$.get("../controller.php",{"m":"home","a":"getContent","cid":cid,"page":page},function(data){// 将返回的数据,做为参数传给 setPageContent函数,来设置页面内容setPageContent(cid, data);},"json")}
3. content.html
content页面功能模块划分

3.1 导航,页脚,推荐,热门,分类,链接可复用list页面内容
- 请求目标: 前台
m=home - 导航,页脚 
- 请求动作: 
a=getClass 
 - 请求动作: 
 - 备案信息 
- 请求动作: 
a=getIcp 
 - 请求动作: 
 - 推荐文章 
- 请求动作: 
a=getListTj 
 - 请求动作: 
 - 热门浏览 
- 请求动作: 
a=getListHot 
 - 请求动作: 
 - 网站分类 
- 请求动作: 
a=getSiteClass 
 - 请求动作: 
 - 友情链接 
- 请求动作: 
a=getLinks 
 - 请求动作: 
 
3.2 获取用户状态信息
- 请求目标: 前台
m=home - 请求动作: 
a=getUserStatus 
controller.php
// 路由判断...else if($act == "getUserStatus"){getUserStatus();}...// 返回用户状态,如果登陆返回用户名,未登陆返回空字符串function getUserStatus(){$userStatus = [];$userStatus["uid"] = isset($_SESSION["uid"]) ? $_SESSION["uid"] : "0";$userStatus["user"] = isset($_SESSION["user"]) ? $_SESSION["user"] : "匿名用户";echo json_encode($userStatus);}
页面中getUserStatus函数
// 获取用户状态function getUserStatus(){$.get("../controller.php",{"m":"home","a": "getUserStatus"}, function (data){// 将当前用户的用户添加到评论前的名称上$(".pinglun .plbox .pluser").html(data.user);userStatus = data;console.log(userStatus);},"json");}
3.3 获取文章内容(重点)
- 请求目标: 前台
m=home - 请求动作: 
a=getNewsContent 
controller.php
// 路由判断...else if($act == "getNewsContent"){getNewsContent();}...// 返回文章内容,及上一条下一条数据function getNewsContent(){$id1 = $_GET["cid"];$id0 = $id1-1;$id2 = $id1+1;$content = queryAll("select id, title,content, date, userId, click, supportNum, classId from content where id in({$id0}, {$id1} ,{$id2});");// 判断返回记录是否是三条(上一条,当前条,下一条)if(count($content) < 3){// 如果第一条是当前条,说明没有上一条数据if($content[0]["id"] == $id1){// 在第一个位置,添加"没有了"array_unshift($content, ["id"=>0, "title"=>"没有了"]);}else{array_push($content, ["id"=>0, "title"=>"没有了"]);}}// 通过结果中的userId查发布者,将发布者保存到数据中$user = queryOne("select userName from user where id = {$content[1]['userId']}");$content[1]["userId"] = $user;// 通过查询结果中的classId,将该文章所属的分类名取出$className = queryOne("select name from class where id = {$content[1]["classId"]}");$content[1]["classId"] = $className["name"];// 获取Uid,cid, 判断当前用户是否点赞$uid = isset($_SESSION["uid"]) ? $_SESSION["uid"] : "0";$isSupport = queryOne("select issupport from support where contentId = {$id1} and userId = {$uid}");// 如果该用户在该文章没有点赞记录,或者点赞状态为0if($isSupport == false || $isSupport["issupport"] == "0"){// 没点赞$content[1]["isSupport"] = 0;}else{// 点赞了$content[1]["isSupport"] = 1;}// 将数据返回echo json_encode($content);}
页面中getNewsContent函数
// 获取内容function getNewsContent(){$.get("../controller.php",{"m":"home","a":"getNewsContent", "cid":cid},function(data){console.log(data);// 设置分类标题cn = data[1].classId;$("#className").html(cn);// 设置文章内容for(var i=0;i<data.length;i++){var o = data[i];if(i == 0){// 上一篇$("#pre>a").attr({"href": (o.id !=0? "content.html?id=" +o.id:"javascript:;") });$("#pre>a>span").html(o.title);}else if(i == 1){// 当前文章// 标题$(".detail .ctitle .row1").html(o.title);// 赞数if(o.isSupport != "0")$(".zan img").attr({"src":"../res/newHeart2021Active.png"});else$(".zan img").attr({"src":"../res/newHeart2021Black.png"});$(".zan span").html(o.supportNum);// 发布时间$(".fdate").html(o.date);// 作者$(".author").html(o.userId.userName);// 围观$(".look").html(o.click);// 内容$(".content_text").html(o.content);}else{// 下一篇$("#next>a").attr({"href": (o.id !=0? "content.html?id=" +o.id:"javascript:;") });$("#next>a>span").html(o.title);}}},"json")}
3.4 点赞事件逻辑(重点)
- 请求目标: 前台
m=home - 请求动作: 
a=clickZan 
controller.php
// 路由判断...else if($act == "clickZan"){clickZan();}...// 点赞请求function clickZan(){$cid = $_GET["cid"];$uid = $_GET["uid"];// var_dump($cid);// var_dump($uid);$isSupport = queryOne("select issupport from support where contentId = {$cid} and userId = {$uid}");// var_dump($isSupport);// var_dump("-----");// 点赞状态取反if($isSupport == false){// 没有点赞的情况,插入新点赞记录$isSup = "1";// 改变点赞表中,文章/用户/是否点赞状态execute("insert into support (contentId,userId,issupport) values({$cid},{$uid},{$isSup})");// 改变文章的总赞数execute("UPDATE content set supportNum = supportNum + 1 where id = {$cid};");}else{// 如果有点赞记录,取反$isSup = $isSupport["issupport"] == "1" ? "0" : "1";// 改变点赞表中,文章/用户/是否点赞状态execute("update support set issupport = {$isSup} where contentId = {$cid} and userId = {$uid}");// 改变文章的总赞数if($isSup == "0"){execute("UPDATE content set supportNum = supportNum - 1 where id = {$cid};");}else{execute("UPDATE content set supportNum = supportNum + 1 where id = {$cid};");}}echo json_encode(["isSupport"=> $isSup]);}
页面中clickZan函数
// 点赞事件function clickZan(){if(userStatus.uid == "0"){window.location = 'login.html';}else{$.get("../controller.php",{"m":"home", "a":"clickZan", "cid":cid, "uid":userStatus.uid},function (data){var num = parseInt($(".zan span").html());console.log(num);console.log(data);if(data.isSupport == "1"){alert("YesZan");$(".zan img").attr({"src":"../res/newHeart2021Active.png"});$(".zan span").html(num + 1);}else{alert("NoZan");$(".zan img").attr({"src":"../res/newHeart2021Black.png"});$(".zan span").html(num - 1);}},"json");}}
3.5 获取用户评论
- 请求目标: 前台
m=home - 请求动作: 
a=getUserStatus 
controller.php
// 路由判断...else if($act == "getComments"){getComments();}...// 获取评论function getComments(){$cid = $_GET["cid"];$comments = queryAll("select id, userId, content, time from comments where contentId = {$cid} order by time desc");// 将评论者Id 修改为评论者姓名foreach($comments as &$item){$item['user'] = queryOne("select loginName as name from user where id = {$item['userId']}")["name"];// 处理时间$item["time"] = date("Y-m-d H:i:s", $item['time']);// 添加 当前用户的id$item["currentUserId"] = isset($_SESSION["id"])?$_SESSION["id"]:0;}echo json_encode($comments);}
页面中getComments函数
// 获取用户评论function getComments(){$.get("../controller.php", {"m":"home","a": "getComments","cid":cid}, function (data){// 清空原有内容$(".plcontent").empty();// 拼接评论内容var html = '';for(var i=0;i<data.length;i++){var o = data[i];html += '<div class="msgItem">';html += ' <div class="msguser"><span class="user">' + o.user + '</span>';if(o.currentUserId == o.userId){html += '<span class="msgdel"></span></div>';}else{html += '</div>';}html += ' <div class="msg">' + o.content + '</div>';html += ' <div class="msgtime">' + o.time + '</div>';html += '</div>';}console.log(html);$('.plcontent').html(html);},"json");}
3.6 发表用户评论
- 请求目标: 前台
m=home - 请求动作: 
a=getUserStatus 
controller.php
// 路由判断...else if($act == "addComments"){addComments();}...// 添加评论function addComments(){$cid = $_GET["cid"];$uid = $_GET["uid"];$comm = $_GET["comm"];$time = 1642342314;// $time = $_GET["time"];var_dump($cid);var_dump($uid);var_dump($comm);var_dump($time);$sql = "insert into comments(contentId, userId, content, time) values({$cid},{$uid},'{$comm}',{$time})";var_dump($sql);$ret = execute($sql);var_dump($ret);echo $ret;}
页面中addComments函数
function addComments(){if(userStatus.uid == "0"){window.location = 'login.html';}else{// 获取评论var comm = $(".plin").val();// 获取当前时间var timestamp = new Date().getTime()$.get("../controller.php",{"m":"home", "a":"addComments","cid":cid, "uid":userStatus.uid,"comm":comm, "time":timestamp},function (data){var comm = $(".plin").val("");// 重新获取评论getComments();});}}
4. login.html
- 请求目标: 前台
m=home - 请求动作: 
a=login 
controller.php
// 开启Session会话session_start();// 路由判断...else if($act == "login"){login();}...// 登陆函数function login(){$user = $_GET["user"];$pwd = $_GET["pwd"];$login = queryOne("select id from user where loginName='{$user}' and password='{$pwd}'");if($login != false){// 保存session信息$_SESSION['uid'] = $login["id"];$_SESSION['user'] = $user;$_SESSION['pwd'] = $pwd;echo 1;}else{echo 0;}}
login页面中登陆按钮事件
<script>$(function(){$("#btn").click(function(){var user = $("#user").val();var pwd = $("#pwd").val();if( user == ""){alert("用户名不能为空!");$("#user").focus();return;}if(pwd == ""){alert("密码不能为空!");$("#pwd").focus();return;}$.get('../controller.php',{"m":"home","a":"login","user":user,"pwd":pwd},function(data){if(data == 1){window.location = "index.html?user=" + user;}else{alert("用户名或密码错误");}},"html");});});</script>
三. 后台页面实现
1. loginback.html
- 请求目标: 前台
m=home - 请求动作: 
a=login 
controller.php
// 开启Session会话session_start();// 路由判断...elseif ($module == "admin"){$act = $_GET["a"];//后台if($act == "login"){backLogin();}...// 后台登陆函数function backLogin(){$user = $_GET["user"];$pwd = $_GET["pwd"];$login = queryOne("select id from user where usertypeId = 1 and loginName='{$user}' and password='{$pwd}'");if($login != false){$_SESSION['buid'] = $login["id"];$_SESSION['buser'] = $user;$_SESSION['bpwd'] = $pwd;echo 1;}else{echo 0;}}
loginback页面中登陆按钮事件
<script>$(function(){$("#btn").click(function(){var user = $("#user").val();var pwd = $("#pwd").val();if( user == ""){alert("用户名不能为空!");$("#user").focus();return;}if(pwd == ""){alert("密码不能为空!");$("#pwd").focus();return;}$.get('../controller.php',{"m":"admin","a":"login","user":user,"pwd":pwd},function(data){if(data == 1){window.location = "websiteback.html?user=" + user;}else{alert("用户名或密码错误");}},"html");});});</script>
2. websiteback.html
websiteback页面功能模块划分

2.1 回显数据
- 请求目标: 后台
m=admin - 请求动作: 
a=getWebSite 
controller.php
// 路由判断
... 
  else if($act == "getWebSite"){
    getWebSite();
  }
...
// webSite 表格中回显的数据
function getWebSite(){
    $web = queryOne("select id, name, logo, Icpid from website;");
    echo json_encode($web);
}
页面中getWebSite请求回调函数
<script src="../js/jquery-1.11.3.js"></script>
<script>
  // 用来保存选中logo图片的索引
  var logoIdx = 1;
  // 用来保存选中的logo地址
  var selectLogo = "";
  // 入口函数
  $(function(){
    // 回显数据
    $.get("../controller.php",{"m":"admin","a":"getWebSite"},function(data){
      $("[name=webname]").val(data.name);
      $("[name=icp]").val(data.Icpid);
      // 获取图片编号
      var logo = data.logo.split(".png")[0];
      logoIdx = logo.substr(-1);
      logoIdx = ".webrow2 img:nth-child("+ logoIdx+")";
      $(logoIdx).addClass("logoSelect");
    },"json");
  });
</script>
2.2 logo图片添加响应事件
该功能没有发起网络请求,是在回显数据之后,点击图片时,给相应图片添加样式,并记录该图片地址.
// 入口函数
... 
// 给logo 图片添加响应事件
console.log($(".webrow2 img"));
$(".webrow2 img").click(function(event){
  // 移除选中状态
  $(".webrow2 img").removeClass('logoSelect');
  // 添加选中状态
  $(this).addClass("logoSelect");
  // 获取logo地址
  selectLogo = $(this).attr("src");
});
...
2.3 保存按钮响应事件
- 请求目标: 后台
m=admin - 请求动作: 
a=updateWebSite 
controller.php
// 路由判断
... 
  else if($act == "updateWebSite"){
    updateWebSite();
  }
...
// 更新webSite数据
function updateWebSite(){
    $name = $_GET["name"];
    $logo = $_GET["logo"];
    $icp = $_GET["icp"];
    $ret = execute("update website set name='{$name}', logo='{$logo}', Icpid='{$icp}' where id = 1");
    // var_dump($ret);
    echo $ret; 
}
页面中保存按钮绑定响应函数
// 入口函数
...
// 保存按钮绑定事件
$("#webBtn").click(function(){
  // 获取修改后的值,提交保存
  var webName = $("[name=webname]").val();
  var icp = $("[name=icp]").val();
  $.get("../controller.php",{"m":"admin","a":"updateWebSite","name":webName,"logo":selectLogo,"icp":icp},function(data){
    if(data == 1){
      alert("修改成功" + data);
    }else{
      alert("修改失败" + data);
    }
    console.log(data);
  })
});
...
2.4 退出按钮响应事件
- 请求目标: 后台
m=admin - 请求动作: 
a=logout 
controller.php
// 路由判断
... 
    else if($act == "logout"){
    session_destroy();
  }
...
页面中退出按钮绑定回调函数
// 退出按钮绑定事件
$("#out").click(function(){
  // confirm 会弹出一个带取消按钮的弹框,确定返回true,取消返回 false,
  // 根据 confrim 的返回值进行不同的操作
  var cof=window.confirm("确认退出吗?");
  if(cof==true)
  {
    $.get("../controller.php",{"m":"admin","a":"logout"},function(data){
      window.location = 'loginback.html';
    });
    // 下面的返回值可以不写,也可以添加后给其它功能使用,这里没用
    return true;   //确认
  }
  else
    return false;  //取消
});
3. rotationchartback.html
rotationchartback页面功能模块划分

3.1 退出按钮事件复用和模态框准备工作
复用退出功能 ,定义模态框相关变量
<script>
  // 用来保存选中logo图片的索引
  var imgIdx = 1;
  // 用来保存选中的logo地址
  var selectImg = "";
  // 用来记录当前页码,删除数据后刷新使用
  var cpn = 1;
  // 用来保存添加或修改状态的变量
  var status = "";
  // 用来保存修改数据的id
  var changeId = '';
    // 入口函数
  $(function(){
    // 退出按钮响应事件
    $("#out").click(function(){
      $.get("../controller.php",{"m":"admin","a":"logout"},function(data){
        window.location = 'loginback.html';
      });
    });
    // 让模态框隐藏
    $(".model").hide();
    // 给模态框关闭按钮添加事件
    $(".close").click(function(){
      $(".model").hide();
    });
    // 给模态框中的图片添加响应事件
    $(".webrow2 img").click(function(event){
      // 移除选中状态
      $(".webrow2 img").removeClass('logoSelect');
      // 添加选中状态
      $(this).addClass("logoSelect");
      // 获取logo地址
      selectImg = $(this).attr("src");
    });
  });
<script>
3.2 获取轮播图数据
- 请求目标: 后台
m=admin - 请求动作: 
a=getLbtData 
controller.php
// 路由判断
... 
  else if($act == "getLbtData"){
    getLbtData();
  }
...
// 获取后台轮播图数据
function getLbtData(){
  // 当前页总条数
  $pageNum = 8;
  // 获取当前页码
  $currentPage = $_GET["currentPage"];
  // 分页信息
  $allData = queryOne("select count(*) as allNum from rotationchart;");
  $allPage = ceil($allData["allNum"]/$pageNum);
  // 在删除最后一页中最后一条记录时,应该返回到上一页
  $currentPage = $currentPage > $allPage ? $allPage : $currentPage;
  // sql 中用的当前页码
  $cp = ($currentPage - 1)*$pageNum;
  // 数据
  $data = queryAll("select id,sort,name,url from rotationchart limit {$cp}, {$pageNum};");
    // 组合页面数据和分页数据
  $page = ["currentPage"=>$currentPage, "allPage"=>$allPage];
  $tmp = ["content"=>$data, "page"=>$page];
  echo json_encode($tmp);
}
页面中getLbtData函数
// 入口函数
...
getLbtData();
...
// 获取轮播图数据, 同时获取分页数据的内容
function getLbtData(currentPage){
  $.get("../controller.php",{"m":"admin","a":"getLbtData","currentPage":currentPage},function(data){
    // 记录当前的页码
    cpn = currentPage;
    // 设置页面内容的方法
    setContent(data.content);
    // 设置页码内容
    setPageInfo(data.page);
  },"json");
}
// 
// 设置页面内容的方法
function setContent(data){
  var html = "<tr class='tableTitle'><td>名称</td><td>图片</td><td>图片排序</td><td>操作</td></tr>";
  for(var i=0;i<data.length;i++){
    var o = data[i];
    html += '<tr>';
    html += '    <td>'+ o.name +'</td>';
    html += '    <td><img src="'+ o.url +'" alt="" ></td>';
    html += '    <td>'+ o.sort +'</td>';
    html += '    <td><button onclick="changeItem(' + o.id +')">修改</button> <button onclick="delItem(' + o.id +')">删除</button></td>';
    html += '</tr> ';
  }
  console.log(html);
  $("#lbt table").html(html);
}
// 设置分页内容的方法
function setPageInfo(pageInfo){
  html = "";
  html += "<ul class='page_list'>";
  html += "  <li  onclick=getLbtData("+ 1 +")>首页</li>";
  var prePage = pageInfo.currentPage == 1? 1 : pageInfo.currentPage - 1;
  html += "  <li  onclick=getLbtData("+ prePage +")>前一页</li>";
  for(var i=1;i<=pageInfo.allPage;i++){
    if(i == pageInfo.currentPage)
      // 绑定分页获取数据的方法
      html += "  <li class='num active' onclick=getLbtData("+ i +")>" + i + "</li>";
    else
      html += "  <li class='num' onclick=getLbtData("+ i +")>" + i + "</li>";
  }
  var nextPage = pageInfo.currentPage == pageInfo.allPage ? pageInfo.allPage : parseInt(pageInfo.currentPage) + 1;
  html += "  <li onclick=getLbtData("+ nextPage +")>后一页</li>";
  html += "  <li  onclick=getLbtData("+ pageInfo.allPage +")>尾页</li>";
  html += "</ul>";
  // 将新内容添加到页面中
  $("#lbtPage").html(html);
}
3.3 删除记录功能
- 请求目标: 后台
m=admin - 请求动作: 
a=delLbtItem 
controller.php
// 路由判断
... 
  else if($act == "delLbtItem"){
    delLbtItem();
  }
...
// 删除轮播图数据
function delLbtItem(){
    $id = $_GET["id"];
    $res = execute("delete from rotationchart where id = {$id}");
    echo $res;
}
页面中delLbtItem函数
// 删除方法
function delItem(id){
  $.get("../controller.php", {"m":"admin","a":"delLbtItem","id":id},function(data){
    getLbtData(cpn);
  })
}
3.4 添加按钮弹出模态框功能(重点)
- 页面中添加按钮响应事件函数
 
// 入口函数
...
// 给添加按钮绑定事件,显示模态框
$("#lbtAddBtn").click(function(){
  $(".modelTitle").html("添加图片");
  $(".model").show();
  status = "add";
  // 因为和修改是共用一个model框,所以如果使用添加功能 ,那么先清除一下前面的痕迹
  $(".webrow2 img").removeClass('logoSelect');
  $("[name=webname]").val("");
  $("[name=icp]").val("");
});
...
3.5 修改按钮弹出模态框功能 (重点)
- 请求目标: 后台
m=admin - 请求动作: 
a=getLbtChangeItem 
controller.php
// 路由判断
... 
  else if($act == "getLbtChangeItem"){
    getLbtChangeItem();
  }
...
// 获取轮播图修改时的回显数据
function getLbtChangeItem(){
    $id = $_GET["id"];
    $data = queryOne("select id,name,url,sort from rotationchart where id ={$id}");
    echo json_encode($data);
}
页面中changeItem函数
// 修改方法
function changeItem(id){
  $(".modelTitle").html("修改图片");
  $(".model").show();
  status = "change";
  // 保存id,在提交时使用
  changeId = id;
  $.get("../controller.php",{"m":"admin","a":"getLbtChangeItem","id":id},function(data){
    // 回显数据
    $("[name=webname]").val(data.name);
    $("[name=icp]").val(data.sort);
    // 获取图片编号
    var logo = data.url.split(".jpg")[0];
    imgIdx = logo.substr(-1);
    imgIdx = ".webrow2 img:nth-child("+ imgIdx +")";
    // 因为可能修改多个数据, 先将上一次的选中状态清除
    $(".webrow2 img").removeClass('logoSelect');
    // 给当前数据图片添加选中状态
    $(imgIdx).addClass("logoSelect");          
  },"json");
}
3.6 模态框提交按钮响应事件方法(重点)
因为添加和修改是共用一个模态框 ,所以在提交时,要区别功能的不同,分开提交
- 请求目标: 后台
m=admin - 请求动作: 
a=lbtAddItemData - 请求动作: 
a=lbtChangeItemData 
controller.php
// 路由判断
... 
  else if($act == "lbtAddItemData"){
    lbtAddItemData();
  }else if($act == "lbtChangeItemData"){
    lbtChangeItemData();
  }
...
// 添加轮播图
function lbtAddItemData(){
    $name = $_GET['name'];
    $url = $_GET['url'];
    $sort = $_GET['sort'];
    $res = execute("insert into rotationchart(name,url,sort) values('{$name}','{$url}',{$sort})");
    echo $res;
}
// 修改轮播图
function lbtChangeItemData(){
    $id = $_GET['id'];
    $name = $_GET['name'];
    $url = $_GET['url'];
    $sort = $_GET['sort'];
    $res = execute("update rotationchart set name='{$name}', url='{$url}', sort = {$sort}  where id={$id}");
    echo $res;
}
- 页面中modelSubmit提交按钮响应函数
 
// 模态框提交按钮响应方法,该方法已在模板中与按钮绑定完成
function modelSubmit(){
  // 获取要提交的数据
  var name = $("[name=webname]").val();
  var sort = $("[name=icp]").val();
  // 判断状态是什么操作
  if(status == 'add'){
    $.get("../controller.php",{"m":"admin",'a':"lbtAddItemData","name":name, "sort":sort,"url":selectImg},function(data){
      alert(data);
      $(".model").hide();
      getLbtData(cpn);
    });
  }else if(status == "change"){
    $.get("../controller.php",{"m":"admin",'a':"lbtChangeItemData","id":changeId, "name":name, "sort":sort,"url":selectImg},function(data){
      alert(data);
      $(".model").hide();
      getLbtData(cpn);
    });
  }
}
四. 其它三个页面的显示数据
- 请求目标: 后台
m=admin - 请求动作: 
a=getClassManagerData - 请求动作: 
a=getContentManagerData - 请求动作: 
a=getUserManagerData 
controller.php
// 路由判断
... 
  else if($act == "getClassManagerData"){
    getClassManagerData();
  }else if($act == "getContentManagerData"){
    getContentManagerData();
  }else if($act == "getUserManagerData"){
    getUserManagerData();
  }
...
// ///////////////////////////////////////// classBack.html //////////////////////////////////////////////
function getClassManagerData(){
    $data = queryAll("select id,name,sort,type from class;");
    // 当前页总条数
    $pageNum = 8;
    // 获取当前页码
    $currentPage = $_GET["currentPage"];
    // 分页信息
    $allData = queryOne("select count(*) as allNum from class;");
    $allPage = ceil($allData["allNum"]/$pageNum);
    $page = ["currentPage"=>$currentPage, "allPage"=>$allPage];
    $tmp = ['content'=>$data, "page"=>$page];
    echo json_encode($tmp);
}
// ///////////////////////////////////////// contentBack.html /////////////////////////////////////////////
function getContentManagerData(){
    $data = queryAll("select id,title,classId,userId,date,click from content;");
    foreach($data as &$item){
        $item['classId'] = queryOne("select name from class where id = {$item['classId']}")['name'];
        $item['userId'] = queryOne("select userName from user where id = {$item['userId']}")['userName'];
    }
    // 当前页总条数
    $pageNum = 8;
    // 获取当前页码
    $currentPage = $_GET["currentPage"];
    // 分页信息
    $allData = queryOne("select count(*) as allNum from content;");
    $allPage = ceil($allData["allNum"]/$pageNum);
    $page = ["currentPage"=>$currentPage, "allPage"=>$allPage];
    $tmp = ['content'=>$data, "page"=>$page];
    echo json_encode($tmp);
}
// ///////////////////////////////////////// userback.html ////////////////////////////////////////////////
function getUserManagerData(){
    $data = queryAll("select id, userName, loginName, password, usertypeId from user;");
    foreach($data as &$item){
        $item['usertypeId'] = $item['usertypeId'] == 1?"管理员":"用户";
    }
    // 当前页总条数
    $pageNum = 8;
    // 获取当前页码
    $currentPage = $_GET["currentPage"];
    // 分页信息
    $allData = queryOne("select count(*) as allNum from user;");
    $allPage = ceil($allData["allNum"]/$pageNum);
    $page = ["currentPage"=>$currentPage, "allPage"=>$allPage];
    $tmp = ['content'=>$data, "page"=>$page];
    echo json_encode($tmp);
}
                    