阿里百秀项目实战day2

登录页面逻辑

1.表单校验是否空
2. 数据校验是否合理
3. 表单状态保持(将数据更新到数据库)
4. 记录登录状态
5. 跳转

//载入配置文件
require_once'../config.php'; 

function login(){
  // 1.校验
  if(empty($_POST['email'])){
    $GLOBALS['message']='请填写邮箱';
    return;
  }
  if(empty($_POST['password'])){
    $GLOBALS['message']='请填写密码';
    return;
  }
$email=$_POST['email'];
$password=$_POST['password'];

// 当客户端提交完整的表单信息就应该开始对其进行数据校验,把例子换位数据库校验
$conn=mysqli_connect(DB_HOST,DB_USER,DB_PASS,DB_NAME);
if(!$conn){
  exit('<h1>连接数据库失败</h1>');
}
$query=mysqli_query($conn,"select * from users where email='{$email}' limit 1;");

if(!$query){
  $GLOBALS['message']='登陆失败请重试';
  return;
}

$user=mysqli_fetch_assoc($query);
if(!$user){
  $GLOBALS['message']='用户名不存在';
  return;
}
if($user['password']!=($password)){
  $GLOBALS['message']='密码错误';
  return;
}

// 表单状态保持

// 记录登陆状态
session_start();
$_SESSION['current_login_user']=$user;
// 一切ok,跳转
header('Location:/admin/');
}
if($_SERVER['REQUEST_METHOD']=='POST')
{
  login();
}

页面访问权限控制

利用session在首页的代码页开头检测登录标识,若没有,则跳转到登陆页,不允许访问内容页面

session_start();
if(empty($_SESSION['current_login_user'])){
  header('Location:/admin/login.php');
}

动态获取登陆用户头像

在avatar.php中

<?php
// 根据用户邮箱获取用户头像
// email=》image
require_once '../../config.php';

// 1.接收传递过来的邮箱
if(empty($_GET['email'])){
    exit('缺少必要参数');
}
$email=$_GET['email'];
// 连接数据库
$conn=mysqli_connect(DB_HOST,DB_USER,DB_PASS,DB_NAME);
if(!$conn){
    exit('连接数据库失败');
}
$res=mysqli_query($conn,"select avatar from users where email = '{$email}' limit 1;");
if(!$res){
exit('查询失败');
}

$row=mysqli_fetch_assoc($res);

echo $row['avatar'];

?>

在login.php中

 <script src="/static/assets/vendors/jquery/jquery.js"></script>
<script>
$(function(){

// 1.单独作用域
// 2.确保页面加载过后执行
// 目标:在用户输入自己的邮箱过后,页面上显示这个邮箱的头像
// 实现:
// 时机:邮箱文本框失去焦点,并且能够拿到文本框中填写的邮箱时
// 事情:获取这个文本框中填写的邮箱对应的头像地址,展示到上面的img元素上

var emailFormat=/[a-zA-Z0-9]+@[a-zA-Z0-9]+\.[a-zA-Z0-9]+$/;
// test()校验正则表达式,exec()提取正则表达式里的组
$('#email').on('blur',function(){
var value=$(this).val();
// 忽略邮箱为空或不是邮箱
if(!value||!emailFormat.test(value)) return;
// 因为客户端无法用js操作数据库,所以发送ajax请求,告诉服务端的某个接口,让这个接口帮助客户端获取头像地址
$.get('/admin/api/avatar.php',{email:value},function(res){
// 希望res=》这个邮箱对应的头像地址
if(!res) return;
// 展示到img元素上
$('.avatar').attr('src',res);
})
})

})

</script>

输入邮箱后,emial框失去焦点后显示出头像

*require 载入文件路径问题*
index.php incude了sidebar.php require的相对路径是相对于index不是sidebar来看的

封装数据库查询操作

在functions.php(用于封装公共函数)中定义函数

// 通过一个数据库查询获取数据
function bx_fetch($sql){

$conn=mysqli_connect(DB_HOST,DB_USER,DB_PASS,DB_NAME);
if(!$conn){
    exit('连接失败');
}
$query=mysqli_query($conn,$sql);//查询失败可能是语句写错,所以给个机会,不要直接exit
if(!$query) {
    return false;
}
while($row=mysqli_fetch_assoc($query)){
    $result[]=$row;
}
return $result;
}
// 获取单条数据
function bx_fetch_one($sql){

    $res=bx_fetch($sql);
    return isset($res[0])?$res[0]:null;
    }

回到index.php中调用

// 重复的操作一定封装起来
// 为社么count(1/2/3/4) 效率最高,因为直接select 1也会产生4行数据 count*会扫描里面有多少字段,浪费 count(id)也会看有多少id
$posts_count=bx_fetch_one('select count(1) as num from posts;')['num'];
//as num设置返回列的名字
// var dump发现返回指是一个关联数组 array(1){array(1){["num"]=>string(1) "4"}
// 所以想要直接得到数字$posts_count['num']
$categories_count=bx_fetch_one('select count(1) as num from categories;')['num'];
$comments_count=bx_fetch_one('select count(1) as num from comments;')['num'];


在html中调用

 <ul class="list-group">
              <li class="list-group-item"><strong><?php echo $posts_count;?></strong>篇文章(<strong>2</strong>篇草稿)</li>
              <li class="list-group-item"><strong><?php echo $categories_count;?></strong>个分类</li>
              <li class="list-group-item"><strong><?php echo $comments_count;?></strong>条评论(<strong>1</strong>条待审核)</li>
            </ul>

在这里插入图片描述

通过session获取登陆信息显示在页面上

$_SESSION['current_login_user']=$user;

在公用函数页定义函数functions.php

session_start();

function bx_get_current_user(){
if(empty($_SESSION['current_login_user'])){
header('Location:/admin/login.php');
exit();//没有必要再执行之后的代码(包括html)
}
return $_SESSION['current_login_user'];
}

在sidebar.php中

<?php
require_once '../functions.php';
$current_page=isset($current_page)?$current_page:'';
$current_user=bx_get_current_user();
?>
<div class="aside">
    <div class="profile">
      <img class="avatar" src="<?php echo $current_user['avatar'];?>">
      <h3 class="name"><?php echo $current_user['nickname'];?></h3>
    </div>
    <ul class="nav">
      <li <?php echo $current_page=='index.php'?'class="active"':'' ?>>
        <a href="index.php"><i class="fa fa-dashboard"></i>仪表盘</a>
      </li>
      <?php $menu_posts=array('posts.php','post-add.php','categories.php');?>
      <li <?php echo in_array($current_page,$menu_posts)?'class="active"':''  ?>>
        <a href="#menu-posts" <?php echo in_array($current_page,$menu_posts)?'':'class="collapsed"'?> data-toggle="collapse">
          <i class="fa fa-thumb-tack"></i>文章<i class="fa fa-angle-right"></i>
        </a>
        <ul id="menu-posts" class="collapse<?php echo in_array($current_page,$menu_posts)?' in':''?>">
          <li <?php echo $current_page=='posts.php'?'class="active"':'' ?>><a href="posts.php">所有文章</a></li>
          <li <?php echo $current_page=='post-add.php'?'class="active"':'' ?>><a href="post-add.php">写文章</a></li>
          <li <?php echo $current_page=='categories.php'?'class="active"':'' ?>><a href="categories.php">分类目录</a></li>
        </ul>
      </li>
      <li <?php echo $current_page=='comments.php'?'class="active"':'' ?>>
        <a href="comments.php"><i class="fa fa-comments"></i>评论</a>
      </li>
      <li <?php echo $current_page=='users.php'?'class="active"':'' ?>>
        <a href="users.php"><i class="fa fa-users"></i>用户</a>
      </li>
      <?php $menu_posts2=array('nav-menus.php','slides.php','settings.php');?>
      <li   <?php echo in_array($current_page,$menu_posts2)?'class="active"':'' ?>>
        <a href="#menu-settings" 
        <?php echo in_array($current_page,$menu_posts2)?'':'class="collapsed"' ?> data-toggle="collapse">
          <i class="fa fa-cogs"></i>设置<i class="fa fa-angle-right"></i>
        </a>
        <ul id="menu-settings" class="collapse <?php echo in_array($current_page,$menu_posts2)?' in':'' ?>">
          <li <?php echo $current_page=='nav-menus.php'?'class="active"':'' ?>><a href="nav-menus.php">导航菜单</a></li>
          <li <?php echo $current_page=='slides.php'?'class="active"':'' ?>><a href="slides.php">图片轮播</a></li>
          <li <?php echo $current_page=='settings.php'?'class="active"':'' ?>><a href="settings.php">网站设置</a></li>
        </ul>
      </li>
    </ul>
  </div>

在这里插入图片描述

categories页数据分类展示

php中

$categories=bx_fetch('select * from categories');

html中,用foreach渲染

 <table class="table table-striped table-bordered table-hover">
            <thead>
              <tr>
                <th class="text-center" width="40"><input type="checkbox"></th>
                <th>名称</th>
                <th>Slug</th>
                <th class="text-center" width="100">操作</th>
              </tr>
            </thead>
            <tbody>
              <?php foreach($categories as $item): ?>
                  <tr>
                <td class="text-center"><input type="checkbox"></td>
                <td><?php echo $item['name'];?></td>
                <td><?php echo $item['slug'];?></td>
                <td class="text-center">
                  <a href="javascript:;" class="btn btn-info btn-xs">编辑</a>
                  <a href="javascript:;" class="btn btn-danger btn-xs">删除</a>
                </td>
              </tr> 
              <?php endforeach ?>      
            </tbody>
          </table>

在这里插入图片描述

添加分类功能

增加一个公用函数functions.php

// 增删查改
function bx_execute($sql){
    $conn=mysqli_connect(DB_HOST,DB_USER,DB_PASS,DB_NAME);
if(!$conn){
    exit('连接失败');
}
$query=mysqli_query($conn,$sql);//查询失败可能是语句写错,所以给个机会,不要直接exit
if(!$query) {
    return false;
}

$affected_rows=mysqli_affected_rows($conn);
mysqli_close($conn);
return $affected_rows;
}

在categories.php中
表单校验,保存,连接添加到数据库,在列表中显示出新增数据。

function add_category(){
  if(empty($_POST['name']||empty($_POST['slug']))){
    $GLOBALS['message']='请完整填写表单';
    $GLOBALS['success']=false;
    return;
  }

// 接受并保存
$name=$_POST['name'];
$slug=$_POST['slug'];

// 添加到数据库
$rows=bx_execute("insert into categories values(null,'{$slug}','{$name}');");
$GLOBALS['success']=$rows>0;
$GLOBALS['message']=$rows<=0?'添加失败':'添加成功';

}

if($_SERVER['REQUEST_METHOD']=='POST'){
  add_category();
}

单条数据删除

点击删除按钮跳转到删除处理页:新建categories-delete.php
通过categories界面传来的id连接数据库删除id对应的数据后返回categories界面。

categories.php

<a href="categories-delete.php?id=<?php echo $item['id'];?>" class="btn btn-danger btn-xs">删除</a>

categories-delete.php

<?php
// 根据客户端穿过来的id删除对应数据
require_once '../functions.php';
if(empty($_GET['id'])){
    exit('缺少必要参数');
}
$id=$_GET['id'];
$rows=bx_execute('delete from categories where id='.$id);//
// (删除成功跳转到列表页)
header('Location:/admin/categories.php');
?>

批量删除

在这里插入图片描述
从传1个id到传多个id到服务端
checkbox
attr与prop的区别

  • attr获取元素属性
  • prop获取元素对应的dom对象属性
  • checked属性是dom中的,元素并没有写出,除非在标签中明确写出checked=”checked/…“
  • 若在标签中没有写checked=”checked/…“,则用attr访问checked的结果是undefined,用prop访问是true
  • 若标签中写出checked=”checked/…“,则用attr访问checked结果是checked,用prop访问结果是true。(html与dom封装对象的属性里将checked=checked改为布尔值true/false)
   $(function($) {
      var $tbodyCheckbox = $('tbody input');
      var $btnDelete = $("#btn_delete");
      // ***********************方法1***************************
      var allChecks = []; //数组用于存储所有被选中信息
      $tbodyCheckbox.on('change', function() {
        // 三种获取自定义属性的方法
        // 1.$(this).dataset['id']
        // 2.$(this).attr('data-id')
        // 3.$(this).data('id')
        var id = $(this).data('id');
        if ($(this).prop('checked')) { //只访问当前点击的
          allChecks.push(id);
          console.log(allChecks);
        } else {
          allChecks.splice(allChecks.indexOf(id), 1); //当此勾选状态不是true时,将其从数组中删除
        }
        console.log(allChecks);
        allChecks.length ? $btnDelete.fadeIn() : $btnDelete.fadeOut();
        $btnDelete.prop('href', '/admin/categories-delete.php?id=' + allChecks);
      })
    })
  </script>
***********************方法2(最容易理解)***************************
      // 在表格中的任意一个checkbox选中状态改变时(此处最好用change不用click因为change是针对改变的触发)
      $tbodyCheckbox.on('change', function() {
        // 有任意一个checkbox选中就显示批量删除的按钮,否则隐藏
        var flag = false;
        $tbodyCheckbox.each(function(i, item) {
          // 看有没有被选中的
          if ($(item).prop('checked')) flag = true;
        })
        flag ? $btnDelete.fadeIn() : $btnDelete.fadeOut();
      })

此时,categories-delete.php中

$rows=bx_execute('delete from categories where id='.$id);//

应改为

$rows=bx_execute('delete from categories where id in('.$id.');');//
  • !(’.$id.’)注意字符串拼接
  • =换为in!
$id=$_GET['id'];//不要$id=(int)$_GET['id']

编辑功能

categories页中的功能
1.列表数据查询
默认有
2.数据新增
必须post请求
并且没有在url中传id
3.更新
在url中传id

  • 点击编辑按钮传递id值,服务端返回编辑表单页
 <a href="/admin/categories.php?id=<?php echo $item['id']; ?>" class="btn btn-info btn-xs">编辑</a>
  • 获取id值

// 若有传到id
if (!empty($_GET['id'])) {
  // 客户端通过url传递了一个id
  // =>客户端要来拿一个修改数据的表单
  // =>需要拿到用户想要修改的数据
  $current_edit_category= bx_fetch_one('select * from categories where id =' . $_GET['id']);
}
  • 在页面中相应修改/显示值
    若为编辑页则显示编辑框,否则显示添加框
    在这里插入图片描述
  <div class="row">
        <div class="col-md-4">
          <?php if (isset($current_edit_category)) : ?>
            <form action="<?php echo $_SERVER['PHP_SELF']; ?> " method="post">
              <h2>编辑《<?php echo $current_edit_category['name'] ?></h2>
              <div class="form-group">
                <label for="name">名称</label>
                <input id="name" class="form-control" name="name" type="text" placeholder="分类名称" value="<?php echo $current_edit_category['name'] ?>">
              </div>
              <div class="form-group">
                <label for="slug">别名</label>
                <input id="slug" class="form-control" name="slug" type="text" placeholder="slug" value="<?php echo $current_edit_category['slug'] ?>">
                <p class="help-block">https://zce.me/category/<strong>slug</strong></p>
              </div>
              <div class="form-group">
                <button class="btn btn-primary" type="submit">保存</button>
              </div>
            </form>
          <?php else : ?>
            <form action="<?php echo $_SERVER['PHP_SELF']; ?> " method="post">
              <h2>添加新分类目录</h2>
              <div class="form-group">
                <label for="name">名称</label>
                <input id="name" class="form-control" name="name" type="text" placeholder="分类名称">
              </div>
              <div class="form-group">
                <label for="slug">别名</label>
                <input id="slug" class="form-control" name="slug" type="text" placeholder="slug">
                <p class="help-block">https://zce.me/category/<strong>slug</strong></p>
              </div>
              <div class="form-group">
                <button class="btn btn-primary" type="submit">添加</button>
              </div>
            </form>
          <?php endif ?>
        </div>
  • 若有id值传入则为编辑页,调用edit函数
if ($_SERVER['REQUEST_METHOD'] == 'POST') { //在增加了编辑功能后需多加一个对是否url传有id的判断
  if (empty($_GET['id'])) {
    add_category();
  } else {
    edit_category();
  }
}
  • edit函数
function edit_category() //3.数据更新(编辑)
{
  global  $current_edit_category;
  // 接受并保存
  //=>要么是提交过来的数据要么是原有的值
  //=>若提交的值为空,则为原有的值current_edit_category
  $id = $_GET['id'];
  $name = empty($_POST['name']) ? $current_edit_category['name'] : $_POST['name'];
  $current_edit_category['name'] = $name; //因为html页面显示的数据为$current_edit_category['name'] ,所以需更新数据为新post的数据
  $slug = empty($_POST['slug']) ? $current_edit_category['slug'] : $_POST['slug'];
  $current_edit_category['slug'] = $slug;
  // 添加到数据库
  //此处用到id,所以获取编辑id数据的代码段放前面
  $rows = bx_execute("update categories set slug='{$slug}', name='{$name}' where id={$id}");//?????
  $GLOBALS['success'] = $rows > 0;
  $GLOBALS['message'] = $rows <= 0 ?  '保存失败': '保存成功';

}

疑问: $rows = bx_execute("update categories set slug='{$slug}', name='{$name}' where id={$id}");//?????
没有返回值????

发布了7 篇原创文章 · 获赞 4 · 访问量 1041

猜你喜欢

转载自blog.csdn.net/weixin_44208883/article/details/104614401