说到后台管理系统,肯定要有登陆呀,为了简化,我们先把管理员的账号和密码固定下来,都设为admin。
那么后台管理就有几个事情要做了,首先是登陆逻辑,未登陆的用户肯定是要跳登陆的,不能让他进入后台,这段逻辑我们之前是练过的。然后就是进来之后的图片上传,这个也是练过的,然后就是日志的提交,其实都是之前会的,就看怎么把它串起来了。来看看代码:
<!DOCTYPE html> <head> <meta charset=utf-8 /> <title>pet show</title> <style> * { margin : 0px; padding : 0px; } body { background-color : #B1ECFE; } .totalDiv { width : 1000px; margin : 10px auto; } .titleDiv { width : 100%; height : 100px; background-color : #AEFFCF; margin-top : 10px; } .imgDiv { float : left; } .twoTitle { float : left; } .bigTitle { font-size : 45px; color : #FF5400; font-weight : bold; margin-top : 8px; margin-left : 28px; } .subTitle { font-size : 20px; color : #FF0000; margin-top : 5px; margin-left : 35px; } .menu { float : left; margin-left : 120px; margin-top : 15px; } .menu li { float : left; margin-left : 50px; list-style-type : none; } .menu a { font-size : 60px; text-decoration : none; color : #FFC600; } .menu a:hover { color : #6CDBFF; } .bodyDiv { width : 100%; background-color : #6DDBFF; padding-top : 10px; padding-bottom : 10px; } .loginLine { text-align : center; font-size : 30px; margin-top : 30px; } .loginLine input { height : 30px; vertical-align: top; } .loginLine input[type="submit"] { font-size : 30px; height : 50px; width : 100px; } .picDiv, .blogDiv { width : 950px; background-color : #29CAFF; margin : 30px auto; padding : 15px; } .selectDiv { width : 950px; background-color : #29CAFF; margin : 10px auto; padding : 15px; } .blogDiv { text-align : center; } .picTitle { color : #2B6BB2; font-size : 40px; } .picUl li { list-style-type : none; float : left; margin : 15px; } .bodyDiv select { width : 200px; height : 30px; } .blogDiv input[type="text"] { width : 100%; height : 30px; font-size : 20px; } .blogDiv textarea { margin-top : 10px; width : 100%; font-size : 20px; } .blogDiv button { background-color : #4C42C7; color : white; width : 150px; height : 50px; font-size : 30px; margin-top : 10px; } #addPic { cursor : pointer; } #uploadPic { display : none; } </style> </head> <body> <div class="totalDiv"> <div class="titleDiv"> <div class="imgDiv"> <img src="../../images/logo.jpg" width="150px" height="100px" /> </div> <div class="twoTitle"> <div class="bigTitle"> 宠恋秀 </div> <div class="subTitle"> 秀出你的宠物 </div> </div> <div class="menu"> <ul> <li><a href="index.php">首页</a></li> <li><a href="pic.php">图片</a></li> <li><a href="blog.php">日记</a></li> </ul> </div> </div> <div class="bodyDiv"> <?php $login = false; session_start(); if(!isset($_SESSION['petuser'])) { if(isset($_POST['username']) && isset($_POST['password'])) { if($_POST['username'] == "admin" && isset($_POST['password']) == "admin") { $_SESSION['petuser'] = "admin"; $login = true; } } } else { $login = true; } ?> <?php if(!$login) { ?> <div class="selectDiv"> <div class="loginLine">请登陆</div> <form action="#" method="post"> <div class="loginLine">用户名:<input type="text" name="username" /></div> <div class="loginLine">密 码:<input type="password" name="password" /></div> <div class="loginLine"><input type="submit" value="登陆" /></div> </form> </div> <?php } else { ?> <script> var curTitleId = 1; </script> <div class="selectDiv"> <select id="selectPicTitle"> <?php require_once dirname ( __FILE__ ) . '/../../common/SQLHelper.class.php'; $sqlHelper = new SQLHelper(); $sql = "select * from pic_title"; $picTitles = $sqlHelper->execute_dql_array($sql); foreach ($picTitles as $picTitle) { ?> <option value="<?php echo $picTitle['id'];?>"><?php echo $picTitle['title'];?> </option> <?php } ?> <option value="-1">添加</option> </select> <script> curTitleId = <?php if (count($picTitles) > 0) { echo $picTitles[0]['id']; } else { echo "1"; } ?>; </script> </div> <div class="picDiv"> <div class="picTitle">狗狗的故事</div> <ul class="picUl"> <div id="pics"> </div> <li id="addPic"><img src="../../images/add.jpg" /></li> <input id="uploadPic" name="pic" type="file" /> </ul> <div style="clear : both;"></div> </div> <div class="blogDiv"> <form id="blogForm" action="#" method="post"> <input id="blogTitle" type="text" name="title" placeholder="标题"/> <textarea id="blogArticle" name="article" placeholder="正文" cols="100" rows="30"></textarea> <button id="submitBlog">提交</button> </form> </div> <?php } ?> <script> // 更新图片 var selectPic = function(titleId) { var xhr = new XMLHttpRequest(); xhr.open("POST", "getPics.php", true); xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if (xhr.status == 200) { if(xhr.responseText != "false") { var picJson = JSON.parse(xhr.responseText); var lis = ""; for (var i in picJson) { lis += '<li><img src="' + picJson[i].path + '" /></li>'; } document.getElementById('pics').innerHTML = lis; } } } }; xhr.send("titleId=" + titleId); }; // select逻辑 var selectPicTitle = document.getElementById("selectPicTitle"); selectPic(curTitleId); selectPicTitle.onchange = function() { if(selectPicTitle.value == -1) { var res = window.prompt('请输入新Title:'); if(res) { // ajax 添加新Title var xhr = new XMLHttpRequest(); xhr.open("POST", "addTitle.php", true); xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if (xhr.status == 200) { if(xhr.responseText == "true") { window.location.reload(); } else { window.alert('添加新Title失败'); } } } }; xhr.send("newTitle=" + res); } } else { curTitleId = selectPicTitle.value; selectPic(curTitleId); } }; // 添加图片逻辑 document.getElementById("addPic").onclick = function() { document.getElementById("uploadPic").click(); } // 上传逻辑 document.getElementById('uploadPic').onchange = function() { var fd = new FormData(); fd.append(this.name, this.files[0]); var xhr = new XMLHttpRequest(); xhr.open('POST', 'uploadPic.php?titleId=' + curTitleId, true); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if (xhr.status == 200) { if(xhr.responseText == "success") { selectPic(curTitleId); } else { window.alert(xhr.responseText); } } } }; xhr.send(fd); } // 提交日记 document.getElementById('submitBlog').onclick = function(e) { e.preventDefault(); var xhr = new XMLHttpRequest(); xhr.open("POST", "uploadBlog.php", true); xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if (xhr.status == 200) { if(xhr.responseText == "true") { window.alert("添加成功"); } else { window.alert("操作失败"); } } } }; xhr.send("title=" + document.getElementById("blogTitle").value + "&article=" + document.getElementById("blogArticle").value); } </script> </div> </div> </body>check the result
首先,我们随便加了个登陆的样式,这里我们用了一个vertical-align: top;,这个属性指定input应该如何垂直对齐。然后我们根据session和参数来判断,如果有session或者有post参数,而且用户名密码正确,就让它登陆成功,否则还是显示登陆框。
登陆进去之后,首先是取出title放在option中,这对于我们来说已经易如反掌,然后要做的是添加Title的功能,在option的最后,我们有一个添加,它的value是特殊的-1,在select的onchange中,我们判断select.value ,如果为-1,就用ajax进行请求新Title的添加,这里我们来看下ajax的后台页面addTitle.php
<?php require_once dirname ( __FILE__ ) . '/../../common/SQLHelper.class.php'; if(isset($_POST['newTitle'])) { $sqlHelper = new SQLHelper(); $sql = "insert into pic_title (title) values ('" . $_POST['newTitle'] . "')"; $res = $sqlHelper->execute_dqm($sql); if($res == 1) { echo "true"; } else { echo "false"; } } else { echo "false"; } ?>
然后就是根据选择的option来更新图片了,也是一个ajax请求,但是这个ajax请求得到的是json格式的数据。来看看后台文件getPics.php
<?php require_once dirname ( __FILE__ ) . '/../../common/SQLHelper.class.php'; if(isset($_POST['titleId'])) { $sqlHelper = new SQLHelper(); $sql = "select * from picture where title_id=" . $_POST['titleId']; $res = $sqlHelper->execute_dql_array($sql); echo json_encode($res); } else { echo "false"; } ?>
我们选出数据之后用了json_encode($res);将结果json格式化,在js中,我们用JSON.parse(xhr.responseTex t);将结果转为js对象,然后拼出一个字符串lis,通过document.getElementById('pics').innerHTML将它显示在页面上。
然后是上传图片,这里,我们添加一个隐藏的type为file的input,然后用javascript来触发它的点击,这里还用了id选择器为li增加手型鼠标,文件上传和之前的笔记是一样的,这里使用ajax异步上传,我们来看下后台文件uploadPic.php
<?php require_once dirname ( __FILE__ ) . '/../../common/SQLHelper.class.php'; if(isset($_FILES['pic'])) { if(is_uploaded_file($_FILES['pic']['tmp_name'])) { if($_FILES['pic']['size'] < 1000000) { //不能超过1M $extension = substr($_FILES['pic']['name'], strpos($_FILES['pic']['name'], ".")); if(strcasecmp($extension, ".jpg") && strcasecmp($extension, ".png")) { echo "extension error"; } else { $path = "../../images/pics/" . time() . "_" . rand(1, 10000) . $extension; move_uploaded_file($_FILES["pic"]["tmp_name"], dirname ( __FILE__ ) . "/" . $path); $sqlHelper = new SQLHelper(); $sql = "insert into picture (title_id, path) values (" . $_GET['titleId'] . ", '" . $path . "')"; $res = $sqlHelper->execute_dqm($sql); if($res != 1) { echo "database operate error"; } else { echo "success"; } } } else { echo "file too large"; } } else { echo "error"; } } else { echo "error, check php.ini"; } ?>
在后台的php文件中,我们给上传上来的文件新取一个名字,注意,这里一定要换个名字,不然张三传一个pic.jpg,李四也传一个pic.jpg,那么就会覆盖张三的图片啦,换名字的策略也很简单,当前时间_1到10000的随机数,这样就很难重名了。我们通过get方式将titleId传过去,然后我们把相关信息插入数据库就好了。实际项目的路径可能和代码路径不一样哈,请自行理解并修改路径。
最后就是日记的提交了,title是很简单就能拿到的,content却要经过处理,把用回车符分割的段落用<p>包起来,short_content更是要从content中提取前100个字,来看看后台代码uploadBlog.php:
<?php require_once dirname ( __FILE__ ) . '/../../common/SQLHelper.class.php'; if(isset($_POST['title']) && isset($_POST['article'])) { $title = $_POST['title']; $article = "<p>"; $article = $article . str_replace("\n", "</p><p>", $_POST['article']); $article = $article . "</p>"; $short = substr($_POST['article'], 0, 100); $short = str_replace("\n", " ", $short); $short = $short . "..."; $sqlHelper = new SQLHelper(); $sql = "insert into blog (title, short_content, content) values ('" . $title . "', '" . $short . "', '" . $article . "')"; if(1 == $sqlHelper->execute_dqm($sql)) { echo "true"; } else { echo "false"; } } else { echo "false"; } ?>
就这样,整个后台管理的功能全部实现了,但是试了试,好像有不少问题啊,这网站经得起考验吗?
本文的代码放在这里,欢迎大家下载!