要入门web安全,首先就要实战一下,所以就跟着51CTO的孙胜利老师学习PHP好长时间了,终于将这一项目(小项目)给完成了,虽然遇到了很多error,但最后还是做出来了,就记录一下开发过程,顺便再理一遍思路。
全部源码已放在GitHub上,如有需要可以自己下载,可以的话点Star,Thanks 源码地址
开发好后的小型论坛 看起来还挺清新的,那么接下来就开始整理我的开发之路了。
开发思路:
创建后台-父板块 首先,我们需要创建一个数据库来保存我们的所添加的父板块 数据库就取名为bbs,创建父板块father_module表,设置三个字段,id,module_name,sort。
数据库创建完成,就开始编写PHP代码,在此之前,我们需要HTML代码用来展示。
大致就是这样,写父板块功能的时候,中间那一部分可以不要,我们只要HTML代码的头部,左边和尾部。为了不让HTML代码重复出现,我们可以将相同的HTML代码防在一个文件中,利用PHP调用即可。 在admin目录下创建一个inc文件夹,里面放入后台经常要调用的文件,可以节省代码量。 这里把头部的HTML代码放入header.inc.php,左边的HTML代码放入left.inc.php,尾部的HTML代码放入 footer.inc.php。
现在页面搞好了,但我们还需要编写一些数据库相关的函数,比如连接数据库等,如果没有这些函数,创建的数据库也毫无意义。
因为前台和后台都要用到,所以在根目录下再建立一个inc文件夹。
下面就开始编写PHP代码,我们首先得连接数据库。 连接数据库就取名为config.in.php
<?php date_default_timezone_set('Asia/Shanghai');//设置时区 session_start();//开启SESSION,验证后台登陆 header('Content-type:text/html;charset=utf-8');//设置编码 define('DB_HOST','localhost');//定义为常量 define('DB_USER','用户名'); define('DB_PASSWORD','密码'); define('DB_DATABASE','数据库名'); define('SA_PATH',dirname(dirname(__FILE__))); define('SUB_URL',str_replace($_SERVER['DOCUMENT_ROOT'],'',str_replace('\\','/',SA_PATH)).'/'); ?>写好之后,我们还需要编写一些MYSQL常用的函数,方便后面开发使用。
<?php //连接数据库 function connect($host=DB_HOST,$user=DB_USER,$password=DB_PASSWORD,$database=DB_DATABASE){ $link=@mysqli_connect($host, $user, $password, $database); 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; } //获取记录数 function num($link,$sql_count){ $result=execute($link,$sql_count); $count=mysqli_fetch_row($result); return $count[0]; } //数据入库之前进行转义 function escape($link,$data){ if(is_string($data)){ return mysqli_real_escape_string($link,$data); } if(is_array($data)){ foreach ($data as $key=>$val){ $data[$key]=escape($link,$val); } } return $data; } //一次性执行多条SQL语句 /* 一次性执行多条SQL语句 $link:连接 $arr_sqls:数组形式的多条sql语句 $error:传入一个变量,里面会存储语句执行的错误信息 */ 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 close($link){ mysqli_close($link); } ?>这些函数都编号后,就开始我们第一个板块-父板块。 我们首先要引用这两个文件,才能调用他们。 接下来就开始编写father_module.php
<?php include_once '../inc/config.inc.php'; include_once '../inc/mysql.inc.php'; $link=connect();//连接数据库 ?> <?php include 'inc/header.inc.php'?>//引入头部 <?php include 'inc/left.inc.php'?>//引入左边 <?php include 'inc/footer.inc.php'?>//引入右边这样大致框架就做好了,要求的父板块页面至少包括编辑、排序、删除、这些功能,页面是这样的(有点丑)。 那么接下来就开始在HTML代码中嵌入PHP代码,实现相应的功能。 father_module.php完整代码如下:
<?php include_once '../inc/config.inc.php'; include_once '../inc/mysql.inc.php'; include_once '../inc/tool.inc.php'; $link=connect(); //判断用户是否点击排序按钮 if(isset($_POST['submit'])){ foreach($_POST['sort'] as $key=>$val){ //is_numeric() 函数用于检测变量是否为数字或数字字符串 if(!is_numeric($val) || !is_numeric($key)){ skip('father_module.php','error','排序错误!'); } //更新sort中的默认值 $query[]="update father_module set sort={$val} where id={$key}"; } //mysqli_multi_query() 函数可用来执行多条SQL语句 if(execute_multi($link,$query,$error)){ skip('father_module.php','ok','排序修改成功'); }else{ skip('father_module.php','error',$error); } } $template['title']='父板块列表页'; ?> <?php include 'inc/header.inc.php'?> <div id="bg_wrapper"> <div id="main"> <div id="content"> <div class="jquery_tab"> <div class="content_block"> <h2 class="jquery_tab_title">父板块列表</h2> <div class="explain"> <ul> <li>添加你所喜欢的φ(* ̄0 ̄)</li> <li>(o゜▽゜)o☆"( ̄y▽, ̄)╭ "</li> </ul> </div> <form method="POST"> <table class="list"> <tr> <th>排序</th> <th>版块名称</th> <th>版主</th> <th>操作</th> </tr> <?php //查询 $query="select * from father_module"; //执行 $result=execute($link,$query); while ($data=mysqli_fetch_assoc($result)){ //将字符串以URL编码,用于编码处理 $url=urlencode("father_module_delete.php?id={$data['id']}"); $return_url=urlencode($_SERVER['REQUEST_URI']); $message="要删除父版块 {$data['module_name']} 吗?"; //跳转确认页面,给用户更好的用户体验 $delete_url="confirm.php?url={$url}&return_url={$return_url}&message={$message}"; $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>且听风吟</td> <td><a href="#">[访问]</a> <a href="father_module_update.php?id={$data['id']}">[编辑]</a> <a href="$delete_url">[删除]</a></td> </tr> A; echo $html; } ?> </table> <input style="margin-top:20px;cursor:pointer;" class="btn" type="submit" name="submit" value="排序" /> </form> </div><!--end content_block--> </div><!-- end jquery_tab -->我们还需要做confirm.php删除确认页面、father_module_update.php编辑功能、father_module_delete.php删除功能 先来做一下删除确认页面 confirm.php代码
<?php include_once '../inc/config.inc.php'; //先判断是否传过来有参数 if(!isset($_GET['message']) || !isset($_GET['url']) || !isset($_GET['return_url'])){ exit(); } ?> <!doctype html> <html> <head> <meta charset="utf-8"> <title>确认界面</title> <style> @charset "UTF-8"; @use postcss-cssnext; :root { --windmill-dark: #14222D; --windmill-medium-dark: #508BB3; --windmill-medium: #6096C4; --windmill-medium-light: #649ECD; --windmill-light: #B6E2FF; } .windmill { position: relative; width: 800px; height: 500px; margin: auto; overflow: hidden; background: var(--windmill-medium-light); } ....//css代码太多了,这里就不展示了,只把重要的代码展示出来 <link rel="stylesheet" type="text/css" href="style/remind.css" /> <div class="notice"><span class="pic ask"></span> <?php echo $_GET['message']?> <a style="color:red;" href="<?php echo $_GET['url']?>">确定</a> | <a style="color:#666;" href="<?php echo $_GET['return_url']?>">取消</a></div> </body> </html>实现效果: 但现在没有删除功能,所以再做删除功能。 father_module_delete.php代码
<?php include_once '../inc/config.inc.php'; include_once '../inc/mysql.inc.php'; include_once '../inc/tool.inc.php'; $link=connect(); if(!isset($_GET['id'])||!is_numeric($_GET['id'])){ skip('father_module.php','error','id参数错误!'); } //从子版块中查询是否有相同的id,如果有的话就不能直接删除 $query="select * from son_module where father_module_id={$_GET['id']}"; $result=execute($link,$query); if(mysqli_num_rows($result)){ skip('father_module_add.php','error','板块下有子板块,无法直接删除'); } //查询数据库中的id是否和传过来的相同 $query="delete from father_module where id={$_GET['id']}"; execute($link,$query); //mysqli_affected_rows() 函数返回前一次 MySQL 操作(SELECT、INSERT、UPDATE、REPLACE、DELETE)所影响的记录行数 if(mysqli_affected_rows($link)==1){ skip('father_module.php','ok','删除成功'); }else{ skip('father_module.php','error','对不起删除失败,请重试!'); } ?>下面就是编辑页面了 father_module_update.php编辑页面
<?php include_once '../inc/config.inc.php'; include_once '../inc/mysql.inc.php'; include_once '../inc/tool.inc.php'; $link=connect(); $template['title']='管理员编辑页'; //验证 if(!isset($_GET['id'])||!is_numeric($_GET['id'])){ skip('father_module.php','error','id参数错误!'); } $query="select * from father_module where id={$_GET['id']}"; $result=execute($link,$query); if(!mysqli_num_rows($result)){ skip('father_module.php','error','这条版块信息不存在!'); } if(isset($_POST['submit'])){ //因为涉及修改,所以我们需要验证,在创建inc中check_father_module.inc.php文件来验证。 $check_flag='update'; include 'inc/check_father_module.inc.php'; //更新数据 $query="update father_module set module_name='{$_POST['module_name']}',sort={$_POST['sort']} where id={$_GET['id']}"; execute($link,$query); if(mysqli_affected_rows($link)==1){ skip('father_module.php','ok','恭喜你,修改成功!'); }else{ skip('father_module.php','error','对不起,修改失败,请重试!'); } } $data=mysqli_fetch_assoc($result); ?> <?php include 'inc/header.inc.php'?> <div id="bg_wrapper"> <div id="main"> <div id="content"> <div class="jquery_tab"> <div class="content_block"> <h2 class="jquery_tab_title">修改父板块-<?php echo $data['module_name']?></h2> <div class="title">功能说明</div> <div class="explain"> <ul> <li>"*★,°*:.☆( ̄▽ ̄)/$:*.°★* 。"(^U^)ノ~YO</li> </ul> </div> <div id="main"> <form method="post"> <table class="au"> <tr> <td>版块名称</td> <td><input name="module_name" value="<?php echo $data['module_name']?>" type="text" /></td> <td> 版块名称不得为空,最大不得超过66个字符 </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> </div><!--end content_block--> </div><!-- end jquery_tab --> </div> <!--end content--> </div><!--end main--> <?php include 'inc/left.inc.php'?> <?php include 'inc/footer.inc.php'?>再编辑一下check_father_module.inc.php验证文件
<?php //名字不能为空 if(empty($_POST['module_name'])){ skip('father_module_add.php','error','不能为空'); } if(mb_strlen($_POST['module_name'])>66){ skip('father_module_add.php','error','版块名称不得多余66个字符!'); } if(!is_numeric($_POST['sort'])){ skip('father_module_add.php','error','排序只能是数字!'); } //进行转义 $_POST=escape($link,$_POST); //采用switch 更加方便添加,更新等 switch ($check_flag) { case 'add': $query="select * from father_module where module_name='{$_POST['module_name']}'"; break; case 'update': $query="select * from father_module where module_name='{$_POST['module_name']}' and id!={$_GET['id']}"; break; default: skip('father_module_add.php','error','$check_flag参数错误!'); } $result=execute($link,$query); if(mysqli_num_rows($result)){ skip('father_module_add.php','error','这个版块已经有了!'); } ?>实现效果: 这样我们就把第一个任务做好了,我们的父板块展示页以及做好了,接下来开始做子版块。
创建后台-子版块 首先我们需要先创建子版块表来存放我们的数据。 起名为son_module 创建字段 接下来,开始写子版块页面。 son_module代码
<?php include_once '../inc/config.inc.php'; include_once '../inc/mysql.inc.php'; include_once '../inc/tool.inc.php'; $link=connect(); $template['title']='子版块列表'; if(isset($_POST['submit'])){ //循环语句 //$key代表id,$val代表sort //用var_dump()输出一下就了解了 foreach($_POST['sort'] as $key=>$val){ if(!is_numeric($val) || !is_numeric($key)){ skip('son_module.php','error','排序错误!'); } $query[]="update 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="bg_wrapper"> <div id="main"> <div id="content"> <div class="jquery_tab"> <div class="content_block"> <h2 class="jquery_tab_title">子板块列表</h2> <form method="POST"> <table class="list"> <tr> <th>排序</th> <th>版块名称</th> <th>所属父板块</th> <th>版主</th> <th>操作</th> </tr> <?php //起一个别名,ssm代表son_module //sfm代表father_module,有的起名相同会造成错误 $query="select ssm.id,ssm.sort,ssm.module_name,sfm.module_name father_module_name,ssm.member_id from son_module ssm,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=urlencode("son_module_delete.php?id={$data['id']}"); $return_url=urlencode($_SERVER['REQUEST_URI']); $message="要删除子版块 {$data['module_name']} 吗?"; $delete_url="confirm.php?url={$url}&return_url={$return_url}&message={$message}"; $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>{$data['father_module_name']}</td> <td>{$data['member_id']}</td> <td><a href="#">[访问]</a> <a href="son_module_update.php?id={$data['id']}">[编辑]</a> <a href="$delete_url">[删除]</a></td> </tr> A; echo $html; } ?> </table> <input style="margin-top:20px;cursor:pointer;" class="btn" type="submit" name="submit" value="排序" /> </form> </div><!--end content_block--> </div><!-- end jquery_tab --> </div> <!--end content--> </div><!--end main--> <?php include 'inc/left.inc.php'?> <?php include 'inc/footer.inc.php'?>这里的代码和父板块的查不多,但是有区别的,我们创建的子版块必须是属于其中一个父板块下面的,所以我们在子版块创建的father_module_id就是用来区分该子版块是属于那个父板块的。 实现效果: 和父板块一样,这里我们也需要son_module_add.php子版块添加、son_module_delete.php子版块删除、son_module_update.php子板块编辑 先来做son_module_add.php子版块添加
<?php //子板块添加页面 include_once '../inc/config.inc.php'; include_once '../inc/mysql.inc.php'; include_once '../inc/tool.inc.php'; $link=connect(); include_once 'inc/is_manage_login.inc.php'; $template['title']='子板块添加页面'; if(isset($_POST['submit'])){ //验证填写的信息 $check_flag='add'; include 'inc/check_son_module.inc.php'; // 插入数据 $query="insert into son_module(father_module_id,module_name,info,member_id,sort) values({$_POST['father_module_id']},'{$_POST['module_name']}','{$_POST['info']}',{$_POST['member_id']},{$_POST['sort']})"; execute($link,$query); if(mysqli_affected_rows($link)==1){ skip('son_module.php','ok','恭喜你,添加成功!'); }else{ skip('son_module_add.php','error','对不起,添加失败,请重试!'); } } ?> <?php include 'inc/header.inc.php'?> <div id="bg_wrapper"> <div id="main"> <div id="content"> <div class="jquery_tab"> <div class="content_block"> <h2 class="jquery_tab_title">添加子板块</h2> <div class="explain"> <ul> <li>添加你所喜欢的(*^-^*)</li> <li>"*★,°*:.☆( ̄▽ ̄)/$:*.°★* 。"</li> </ul> </div> <div id="main"> <form method="post"> <table class="au"> <tr> <td>所属父板块</td> <td> <select name="father_module_id"> <option value="0">---选择一个父板块---</option> <?php $query="select * from father_module"; $result_father=execute($link,$query); while($data_father=mysqli_fetch_assoc($result_father)){ 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" /></td> <td> 版块名称不得为空,最大不得超过66个字符 </td> </tr> <tr> <td>板块简介</td> <td> <textarea name="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="0" type="text" /></td> <td> 填写一个数字即可 </td> </tr> </table> <input style="margin-top:20px;cursor:pointer;" class="btn" type="submit" name="submit" value="添加" /> </form> </div> </div><!--end content_block--> </div><!-- end jquery_tab --> </div> <!--end content--> </div><!--end main--> <?php include 'inc/left.inc.php'?> <?php include 'inc/footer.inc.php'?>我们还需验证,所以在inc文件中创建check_son_module.inc.php文件
<?php if(!is_numeric($_POST['father_module_id'])){ skip('son_module_add.php','error',' 所属父板块不能为空'); } $query="select * from father_module where id={$_POST['father_module_id']}"; $result=execute($link,$query); if(mysqli_num_rows($result)==0){ skip('son_module_add.php','error',' 所属父板块不存在'); } 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=escape($link,$_POST); switch ($check_flag){ case 'add': $query="select * from son_module where module_name='{$_POST['module_name']}'"; break; case 'update': $query="select * from son_module where module_name='{$_POST['module_name']}' and id!={$_GET['id']}"; break; default: skip('son_module.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','排序只能是数字!'); } ?>实现效果: son_module_delete.php子版块删除
<?php //子版块删除页面 include_once '../inc/config.inc.php'; include_once '../inc/mysql.inc.php'; include_once '../inc/tool.inc.php'; $link=connect(); $template['title']='子板块删除页'; if(!isset($_GET['id'])||!is_numeric($_GET['id'])){ skip('son_module.php','error','id参数错误!'); } $template['title']='子版块删除页面'; $query="delete from son_module where id={$_GET['id']}"; execute($link,$query); //mysqli_affected_rows() 函数返回前一次 MySQL 操作(SELECT、INSERT、UPDATE、REPLACE、DELETE)所影响的记录行数 if(mysqli_affected_rows($link)==1){ skip('son_module.php','ok','删除成功'); }else{ skip('son_module.php','error','对不起删除失败,请重试!'); } ?>son_module_update.php子板块编辑
<?php //子板块编辑页面 include_once '../inc/config.inc.php'; include_once '../inc/mysql.inc.php'; include_once '../inc/tool.inc.php'; $link=connect(); include_once 'inc/is_manage_login.inc.php'; $template['title']='子版块编辑页面'; if(!isset($_GET['id'])||!is_numeric($_GET['id'])){ skip('father_module.php','error','id参数错误!'); } $query="select * from son_module where id={$_GET['id']}"; $result=execute($link,$query); if(!mysqli_num_rows($result)){ skip('son_module.php','error','这条板块信息不存在'); } //修改加验证 //字符串类型的用在外面加上'',例如:module_name='{$_POST['module_name']}' if(isset($_POST['submit'])){ $check_flag='update'; include 'inc/check_son_module.inc.php'; $query="update son_module set father_module_id={$_POST['father_module_id']},module_name='{$_POST['module_name']}',info='{$_POST['info']}',member_id={$_POST['member_id']},sort={$_POST['sort']} where id={$_GET['id']}"; execute($link,$query); if(mysqli_affected_rows($link)==1){ skip('son_module.php','ok','恭喜你,修改成功!'); }else{ skip('son_module.php','error','对不起,修改失败,请重试!'); } } $data=mysqli_fetch_assoc($result); ?> <?php include 'inc/header.inc.php'?> <div id="bg_wrapper"> <div id="main"> <div id="content"> <div class="jquery_tab"> <div class="content_block"> <h2 class="jquery_tab_title">修改子板块——<?php echo $data['module_name']?></h2> <div class="explain"> <ul> <li>(*^-^*)</li> <li>"*★,°*:.☆( ̄▽ ̄)/$:*.°★* 。"</li> </ul> </div> <div id="main"> <form method="post"> <table class="au"> <tr> <td>父板块</td> <td> <select name="father_module_id"> <option value="0">---选择一个父板块---</option> <?php $query="select * from father_module"; $result_father=execute($link,$query); while($data_father=mysqli_fetch_assoc($result_father)){ 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" value="<?php echo $data['module_name']?>" type="text" /></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> </div><!--end content_block--> </div><!-- end jquery_tab --> </div> <!--end content--> </div><!--end main--> <?php include 'inc/left.inc.php'?> <?php include 'inc/footer.inc.php'?>实现效果: 这样子板块和父板块基本功能都已经实现了。
后台开发-管理员 我们需要创建管理员添加功能和管理员列表,在此之前先建manage表 添加字段 manage.php管理员列表
<?php include_once '../inc/config.inc.php'; include_once '../inc/mysql.inc.php'; include_once '../inc/tool.inc.php'; $template['title']='管理员列表页'; $link=connect(); include_once 'inc/is_manage_login.inc.php'; ?> <?php include 'inc/header.inc.php'?> <div id="bg_wrapper"> <div id="main"> <div id="content"> <div class="jquery_tab"> <div class="content_block"> <h2 class="jquery_tab_title">管理员列表页</h2> <div class="explain"> </div> <table class="list"> <tr> <th>管理员名称</th> <th>管理等级</th> <th>创建日期</th> <th>操作</th> </tr> <?php $query="select * from manage"; $result=execute($link,$query); while ($data=mysqli_fetch_assoc($result)){ if($data['level']==0){ $data['level']='超级管理员'; }else{ $data['level']='普通管理员'; } $url=urlencode("manage_delete.php?id={$data['id']}"); $return_url=urlencode($_SERVER['REQUEST_URI']); $message="要删除管理员 {$data['name']} 吗?"; $delete_url="confirm.php?url={$url}&return_url={$return_url}&message={$message}"; $html=<<<A <tr> <td>{$data['name']}[id:{$data['id']}]</td> <td>{$data['level']}</td> <td>{$data['create_time']}</td> <td><a href="{$delete_url}">[删除]</a></td> </tr> A; echo $html; } ?> </table> </div><!--end content_block--> </div><!-- end jquery_tab --> </div> <!--end content--> </div><!--end main--> <?php include 'inc/left.inc.php'?> <?php include 'inc/footer.inc.php'?>实现效果: manage_delete.php管理员删除功能 代码如下:
<?php //子版块删除页面 include_once '../inc/config.inc.php'; include_once '../inc/mysql.inc.php'; include_once '../inc/tool.inc.php'; $link=connect(); include_once 'inc/is_manage_login.inc.php'; if(!isset($_GET['id'])||!is_numeric($_GET['id'])){ skip('manage.php','error','id参数错误!'); } $link=connect(); $template['title']='管理员删除页面'; $query="delete from manage where id={$_GET['id']}"; execute($link,$query); //mysqli_affected_rows() 函数返回前一次 MySQL 操作(SELECT、INSERT、UPDATE、REPLACE、DELETE)所影响的记录行数 if(mysqli_affected_rows($link)==1){ skip('manage.php','ok','删除成功'); }else{ skip('manage.php','error','对不起删除失败,请重试!'); } ?>manage_add.php管理员添加功能
<?php include_once '../inc/config.inc.php'; include_once '../inc/mysql.inc.php'; include_once '../inc/tool.inc.php'; $template['title']='管理员添加页'; $link=connect(); include_once 'inc/is_manage_login.inc.php'; if(isset($_POST['submit'])){ $check_flag='add'; include 'inc/check_manage.inc.php'; $query="insert into manage(name,pw,create_time,level) values('{$_POST['name']}',md5({$_POST['pw']}),now(),{$_POST['level']})"; execute($link,$query); if(mysqli_affected_rows($link)==1){ skip('manage.php','ok','恭喜你,添加成功!'); }else{ skip('manage.php','error','对不起,添加失败,请重试!'); } } ?> <?php include 'inc/header.inc.php'?> <div id="bg_wrapper"> <div id="main"> <div id="content"> <div class="jquery_tab"> <div class="content_block"> <h2 class="jquery_tab_title">添加管理员</h2> <div class="explain"> <ul> <li>(*^-^*)</li> <li>(o゜▽゜)o☆</li> <li>(●'◡'●)</li> </ul> </div> <div id="main"> <form method="post"> <table class="au"> <tr> <td>管理员名称</td> <td><input name="name" type="text" /></td> <td> 名称不得为空 </td> </tr> <tr> <td>密码</td> <td><input name="pw" type="text" /></td> <td> 密码不得低于六位 </td> </tr> <tr> <td>等级</td> <td> <select name="level"> <option value="1">普通管理员</option> <option value="0">超级管理员</option> </select> </td> <td> 请选择一个等级 </td> </tr> </table> <input style="margin-top:20px;cursor:pointer;" class="btn" type="submit" name="submit" value="添加" /> </form> </div> </div><!--end content_block--> </div><!-- end jquery_tab --> </div> <!--end content--> </div><!--end main--> <?php include 'inc/left.inc.php'?> <?php include 'inc/footer.inc.php'?>有往数据库中添加的,我们必须验证,所以再创建一个验证的文件 check_manage.inc.php验证添加管理员
<?php if(empty($_POST['name'])){ skip('manage_add.php','error','管理名称不得为空'); } if(mb_strlen($_POST['name'])>32){ skip('manage_add.php','error','管理员名称不得多于32个字符'); } if(mb_strlen($_POST['name'])<6){ skip('manage_add.php','error','密码不得少于6位'); } $_POST=escape($link,$_POST); $query="select * from manage where name='{$_POST['name']}'"; $result=execute($link,$query); if(mysqli_num_rows($result)){ skip('manage_add.php','error','该管理员名称以及存在'); } //默认传过来的是字符串 if(!isset($_POST['level'])){ $_POST['level']=1; } else if($_POST['level']=='0'){ $_POST['level']==0; } else if($_POST['level']=='1'){ $_POST['level']==1; }else{ $_POST['level']==1; } ?>实现效果: 我们这里0代表超级管理员,1代表普通管理员,唯一的区别就是普通管理员没有权限去添加管理员,而超级管理员有这个功能。这个功能稍后开发,接下来我们开发登陆页面和后台首页。 后台首页index.php
<?php include_once '../inc/config.inc.php'; include_once '../inc/mysql.inc.php'; include_once '../inc/tool.inc.php'; $link=connect(); include_once 'inc/is_manage_login.inc.php'; $query="select * from manage where id={$_SESSION['manage']['id']}"; $result_manage=execute($link, $query); $data_manage=mysqli_fetch_assoc($result_manage); if($data_manage['level']=='0'){ $data_manage['level']='超级管理员'; }else{ $data_manage['level']='普通管理员'; } $query="select count(*) from father_module"; $count_father_module=num($link,$query); $query="select count(*) from son_module"; $count_son_module=num($link,$query); $query="select count(*) from content"; $count_content=num($link,$query); $query="select count(*) from reply"; $count_reply=num($link,$query); $query="select count(*) from member"; $count_member=num($link,$query); $query="select count(*) from manage"; $count_manage=num($link,$query); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta name="description" content="Reflect Template" /> <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /> <title>后台首页</title> <link rel="stylesheet" href="css/style_all.css" type="text/css" media="screen" /> <!-- to choose another color scheme uncomment one of the foloowing stylesheets and wrap styl1.css into a comment --> <link rel="stylesheet" href="css/style8.css" type="text/css" media="screen" /> <link rel="stylesheet" href="css/jquery-ui.css" type="text/css" media="screen" /> <link rel="stylesheet" href="ueditor1_2_2_0-utf8-php/themes/default/ueditor.css" type="text/css" media="screen" /> <!--Internet Explorer Trancparency fix--> <!--[if IE 6]> <script src="js/ie6pngfix.js"></script> <script> DD_belatedPNG.fix('#head, a, a span, img, .message p, .click_to_close, .ie6fix'); </script> <![endif]--> <script type='text/javascript' src='js/all-ck.js'></script> <script type='text/javascript' src='ueditor1_2_2_0-utf8-php/editor_config.js'></script> <script type='text/javascript' src='js/custom.js'></script> </head> <body> <div id="top"> <div id="head"> <h1 class="logo"> <a href="index.php"></a> </h1> <div class="head_memberinfo"> <div class="head_memberinfo_logo"> <span>1</span> <img src="images/unreadmail.png" alt=""/> </div> <span class='memberinfo_span'> 欢迎 <a href="index.php">且听风吟</a> </span> <span> <a href="logout.php">登出</a> </span> <span class='memberinfo_span2'> <a href="index.php">1 条私信</a> </span> </div> <!--end head_memberinfo--> </div> <!--end head--> <div id="bg_wrapper"> <div id="main"> <div id="content"> <h2 class="jquery_tab_title">快速入口</h2> <a class="dashboard_button button1" href="index.php"> <span class="dashboard_button_heading">系统信息</span> <span>查看系统信息</span> </a><!--end dashboard_button--> <a class="dashboard_button button2" href="manage.php"> <span class="dashboard_button_heading">管理员</span> <span>查看当前管理员</span> </a><!--end dashboard_button--> <a class="dashboard_button button3" href="manage_add.php"> <span class="dashboard_button_heading">添加管理员</span> <span>添加一个新的用户</span> </a><!--end dashboard_button--> <a class="dashboard_button button4" href="father_module_add.php"> <span class="dashboard_button_heading">添加父板块</span> <span>添加父板块</span> </a><!--end dashboard_button--> <a class="dashboard_button button5" href="father_module.php"> <span class="dashboard_button_heading">父板块列表</span> <span>搜索已经存在的父板块列表</span> </a><!--end dashboard_button--> <a class="dashboard_button button7" href="son_module.php"> <span class="dashboard_button_heading two_lines">子版块列表</span> <span>查看子版块列表</span> </a><!--end dashboard_button--> <a class="dashboard_button button8" href="son_module_add.php"> <span class="dashboard_button_heading">添加子版块</span> <span>添加子版块</span> </a><!--end dashboard_button--> <a class="dashboard_button button9" href="../index.php"> <span class="dashboard_button_heading two_lines">帖子管理</span> <span>对帖子进行管理</span> </a><!--end dashboard_button--> <a class="dashboard_button button10" href="member.php"> <span class="dashboard_button_heading two_lines">用户列表</span> <span>查看用户</span> </a><!--end dashboard_button--> <a class="dashboard_button button11" href="#"> <span class="dashboard_button_heading">画廊</span> <span>管理您的图片库</span> </a><!--end dashboard_button--> <a class="dashboard_button button12" href="#"> <span class="dashboard_button_heading">帮助</span> <span>如有问题,请点击</span> </a><!--end dashboard_button--> <h2>当前管理员</h2> <div> <p> 你好 管理员:<?php echo $_SESSION['manage']['name']?> </p> <p> 你的管理等级为:<?php echo $data_manage['level']?> </p> <p> 创建时间为:<?php echo $data_manage['create_time']?> </p> </div> <h2>统计信息</h2> <div> <table> <tr> <th class="specalt">父版块 </th> <td><?php echo $count_father_module?></td> <th class="specalt">子版块</th> <td><?php echo $count_son_module?></td> <th class="specalt">帖子</th> <td><?php echo $count_content?></td> <th class="specalt">回复</th> <td><?php echo $count_reply?></td> <th class="specalt">会员</th> <td><?php echo $count_member?></td> <th class="specalt">管理员</th> <td><?php echo $count_manage?></td> </tr> </table> </div> <h2>系统信息</h2> <div> <table> <tr> <th class="specalt">服务器操作系统: </th> <td><?php echo PHP_OS?></td> <th class="specalt">服务器软件:</th> <td><?php echo $_SERVER['SERVER_SOFTWARE']?></td> <th class="specalt">MySQL 版本: </th> <td><?php echo mysqli_get_server_info($link)?></</td> <th class="specalt">最大上传文件:</th> <td><?php echo ini_get('upload_max_filesize')?></td> <th class="specalt">内存限制:</th> <td><?php echo ini_get('memory_limit')?></td> </tr> </table> </div> <h2>程序信息</h2> <div> <table> <tr> <th class="specalt">程序安装位置(绝对路径)</th> <td><?php echo SA_PATH?></td> <th class="specalt">程序在web根目录下的位置(首页的url地址):</th> <td><?php echo SUB_URL?></td> </tr> <tr> <th class="specalt">程序作者:且听风吟</th> <td>作者喜欢旅游,是个吃货</td> </tr> </table> </div> <h2>安全信息</h2> <div> <table> <tr> <th class="specalt">SQL注入</th> <td>无</td> <th class="specalt">XSS攻击</th> <td>无</td> </tr> <tr> <th class="specalt">最近检查日期:</th> <td>2019-05-06</td> </tr> </table> </div> </div> <!--end content--> </div><!--end main--> <div id="sidebar"> <ul class="nav"> <li><a class="headitem item1" href="#">系统</a> <ul><!-- ul items without this class get hiddden by jquery--> <li><a href="index.php">系统信息</a></li> <li><a href="manage.php">管理员</a></li> <li><a href="manage_add.php">添加管理员</a></li> <li><a href="web_set.php">站点设置</a></li> </ul> </li> <li><a class="headitem item4" href="#">内容管理</a> <ul> <li><a href="father_module.php">父板块列表</a></li> <li><a href="father_module_add.php">添加父板块</a></li> <li><a href="son_module.php">子版块列表</a></li> <li><a href="son_module_add.php">添加子版块</a></li> <li><a href="../index.php">帖子管理</a></li> </ul> </li> <li><a class="headitem item5" href="#">用户搜索</a> <ul> <li><a href="member.php">用户列表</a></li> </ul> </li> <!--end subnav--> <div class="flexy_datepicker"></div> <ul> <li><a class="headitem item7" href="#">博客浏览</a> <ul> <li><a href="https://bealright.github.io/">博客</a></li> </ul> </li> </ul> </div> <!--end sidebar--> </div><!--end bg_wrapper--> <div id="footer" style="color: #fff;text-align: center"> TRY YOUR BEST!!!<a href="https://bealright.github.io/" target="_blank" title="且听风吟">且听风吟</a> </div><!--end footer--> </div><!-- end top --> </body> </html>这里的一些php代码包含了系统信息这个功能 实现效果: 接下来是login.php登陆页面,但在此之前我们需要做一个验证登陆的文件 tool.inc.php跳转+验证登陆功能
<?php function skip($url,$pic,$message){ $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 {$pic}"></span> {$message} <a href="{$url}">3秒后自动跳转中!</a></div> </body> </html> A; echo $html; exit(); } //验证前台用户是否登陆 function is_login($link){ if(isset($_COOKIE['bbs']['name']) && isset($_COOKIE['bbs']['pw'])){ $query="select * from member where name='{$_COOKIE['bbs']['name']}' and sha1(pw)='{$_COOKIE['bbs']['pw']}'"; $result=execute($link,$query); if(mysqli_num_rows($result)==1){ $data=mysqli_fetch_assoc($result); return $data['id']; }else{ return false; } }else{ return false; } } function check_user($member_id,$content_member_id,$is_manage_login){ if($member_id==$content_member_id || $is_manage_login){ return true; }else{ return false; } } //验证后台用户是否登陆 function is_manage_login($link){ if(isset($_SESSION['manage']['name']) && isset($_SESSION['manage']['pw'])){ $query="select * from manage where name='{$_SESSION['manage']['name']}' and sha1(pw)='{$_SESSION['manage']['pw']}'"; $result=execute($link,$query); if(mysqli_num_rows($result)==1){ $data=mysqli_fetch_assoc($result); return true; }else{ return false; } }else{ return false; } } ?>login.php登陆页面
<?php include_once '../inc/config.inc.php'; include_once '../inc/mysql.inc.php'; include_once '../inc/tool.inc.php'; $link=connect(); if(is_manage_login($link)){ skip('index.php','ok','请不用重复登陆'); } if(isset($_POST['submit'])){ include_once 'inc/check_login.inc.php'; $query="select * from manage where name='{$_POST['name']}' and pw=md5('{$_POST['pw']}')"; $result=execute($link,$query); if(mysqli_num_rows($result)==1){ $data=mysqli_fetch_assoc($result); $_SESSION['manage']['name']=$data['name']; $_SESSION['manage']['pw']=sha1($data['pw']); $_SESSION['manage']['id']=$data['id']; $_SESSION['manage']['level']=$data['level']; skip('index.php','ok','登陆成功'); }else{ skip('login.php','error','用户名或密码错误'); } } ?> <html> <!DOCTYPE html> <html lang="en" class="no-js"> <head> <meta charset="utf-8"> <title>后台登录</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="description" content=""> <meta name="author" content=""> <!-- CSS --> <link rel="stylesheet" href="assets/css/reset.css"> <link rel="stylesheet" href="assets/css/supersized.css"> <link rel="stylesheet" href="assets/css/style.css"> <!-- HTML5 shim, for IE6-8 support of HTML5 elements --> <!--[if lt IE 9]> <script src="assets/js/html5.js"></script> <![endif]--> </head> <body> <div class="page-container"> <h1>登录(Login)</h1> <form action="" method="post"> <input type="text" name="name" class="text" placeholder="请输入您的用户名!"> <input type="password" name="pw" class="text" placeholder="请输入您的用户密码!"> <button type="submit" class="submit" name="submit">登录</button> <div class="error"><span>+</span></div> </form> <div class="connect"> <p>快捷</p> <p> <a class="facebook" href=""></a> <a class="twitter" href=""></a> </p> </div> </div> <!-- Javascript --> <script src="assets/js/jquery-1.8.2.min.js" ></script> <script src="assets/js/supersized.3.2.7.min.js" ></script> <script src="assets/js/supersized-init.js" ></script> <script src="assets/js/scripts.js" ></script> </body> </html>实现效果: OK,这样登陆页面就完成了,有登陆就要有注销,下面做注销页面。 logout.php注销页面
<?php include_once 'inc/config.inc.php'; include_once 'inc/mysql.inc.php'; include_once 'inc/tool.inc.php'; $link=connect(); setcookie('bbs[name]','',time()-3600); setcookie('bbs[pw]','',time()-3600); skip('index.php','ok','退出成功!'); ?>这样后台大部分功能已经完善好了,有的功能需要和前台交互,所以我们在开发前台的过程再将其完善。
感悟:敲的时候经常敲错、搞混、遇到报错,有时一修改就是修改几个小时,但这也许就是敲代码的乐趣所在吧,过程很难受,但找到error并改好也会有一种成就感,下一篇将继续开发前台功能,未完待续。。。。。。