【千纸诗书】—— PHP/MySQL二手书网站后台开发之知识点记录

前言:使用PHP和MySQL开发后台管理系统的过程中,发现有一些通用的【套路小Tip】,这里集中记录一下。结合工作中ing的后台业务,我逐渐体会到:除了技术知识外、能使用户体验好的“使用流程设计”积累也十分重要╭( ・ㅂ・)و ̑̑    

项目github地址:https://github.com/66Web/php_book_store,欢迎Star。  


 一、知识点记录

1、数据库的表名和列名

  • 绝对不要和数据库的关键字相同  order  order by   
  • 订单表-indent   分类表-class(数据库中没有class关键词)
  • 数据库中   凡是数字  INT FLOAT   一定要UNSIGNED   有负数的不能加UNSIGNED
  • 数据库插入时间   使用时间戳   UNIX_TIMESTAMP

2、后台用户模块

  • 修改页面change.php:必须要id  隐藏域,带过去id
    <input  type="hidden"  name="id"  value='<?php echo $row['id'] ?>' />  
  • 因为update.php中的update语句中where id= ?才可以形成完整语句
  • 图书模块change.php  id  img 两个隐藏域 方便update.php中图片缩放处理和删除原图

3、_top 是指向:上一级目录

<p><a href="logout.php" target='_top'>|-退出系统</a></p>

4、disabled 禁用username提交,不能修改

<p>管理员名:</p>
<p><input type="text" name='username' value='<?php echo $row['username']?>' disabled></p>

5、后台修改、删除  

  • 能通过带参数id等实现,就不要查数据库,不灵活,能不查就不查。 

6、Select选项‘修改’时显示原选项

<p>类别:</p>
<p>
    <select name="class_id">
    <?php
        $sqlClass="select * from class";      //创建sql语句
        $rstClass=mysql_query($sqlClass);     //发送sql语句
        while($rowClass=mysql_fetch_assoc($rstClass)){      //读取并判断mysql服务器返回结果  
            if($rowClass['id'] == $rowBook['class_id']){    //rowClass的id 与传过来的rowCook的class_id相同时,选中 加selected
                echo "<option value='{$rowClass['id']}' selected>{$rowClass['name']}</option>";
            }else{
                echo "<option value='{$rowClass['id']}'>{$rowClass['name']}</option>";
            }
        }
     ?>
    </select>
</p>  

7、后台书的模块,delete.php

$file="../../public/uploads/{$img}";  //定义图片文件路径
$file2="../../public/uploads/thumb_{$img}" //定义缩略图文件路径

//删除图片 删除文件用unlink()
unlink($file);
unlink($file2);

8、传文件函数

扫描二维码关注公众号,回复: 5990721 查看本文章
  • move_uploaded_file($src,$dst) 上传成功返回true 否则false
  1. 第一个参数:$src 上传文件的临时文件名
  2. 第二个参数:$dst 上传后保存的新的路径和名称
    $ext = array_pop(explode('.',$name));
    $dst = '../../public/uploads/'.time().mt_rand().'.'.$ext;//指定地址,并随机生成新文件名
    
    // array_pop() 函数删除数组中的最后一个元素 
    // explode('.',$name) 字符串分割函数获得文件扩展名.jpg等
    
    $src = $_FILES['img']['tmp_name']; //文件上传时在临时目录中被保存成一个临时文件的文件名
    $name = $_FILES['img']['name']; //上传文件的文件名
  • 为了让前台效率不下降,进行图片缩放
  1. 等比例计算真实目标资源的宽和高 (算法难度)
    //判断 原图x/目标x   >  原图y/目标y   以大的比例结果为准
    
    1000/500    500/500
    2            1
  2. 等比例计算真实目标资源的宽和高 如果结果为小数,缩放能小不能大,用floor
    $img = basename($dst);   //获得目录下的文件名a.jpg

9、PHP中exit; 可以阻止脚本,不用通篇注释。

10、图书模块update.php

$imgerror=$_FILES['img']['error'];    //文件上传错误信息

//图片上传--先上传新图,后删除原图,上传失败不删原图
if($imgerror === 0){

11、多表查询

  • 三表查询    后台评论模块index.php
    $sql="select comment.*,user.username,book.name 
          from comment,user,book 
          where comment.user_id=user.id and comment.book_id=book.id";
    $rst=mysql_query($sql);
  • 两表查询    后台书模块index.php
    $sql="select book.*,class.name cname from book,class where book.class_id=class.id";
    $rst=mysql_query($sql);

12、后台评论模块index.php

  • 双引号不能解析函数,要拿出来date(),拼接
    echo "<td>".date('Y-m-d',$row['time'])."</td>";

13、在页面里面流通的get  post中的数据都变成字符串了

  • 不存在数字类型,所以不能用=== ,要用==
    if($row['id']==1){
        //编号为1 的删除按钮的a链接,禁用--<a href='javascript:'></a>,改背景色为灰色
        echo "<td><a href='javascript:' style='background:#888'>删除</a></td>"; 
    }else{
        echo "<td><a href='delete.php?id={$row["id"]}'>删除</a></td>";
    }  

14、后台广告模块

  • 一般广告的位置position 按从上往下,然后从左往右 0~8
  • 为了不暴露admin,后台广告(图书等)图片上传路径 放在前后台公共 public的文件夹 

15、订单模块

  • 订单模块是电商网站后台错误率最高的地方,一定要检查无误。
  • 同一时间下的订单,订单号和时间一致,分组聚合,合并查看
  1. 按订单号分组聚合group  by  indent.code
  • 两表查询:
    $sql="select indent.price,indent.num,book.name,book.img 
             from indent,book 
             where  indent.book_id=book.id and indent.code='{$code}'";
    $rst=mysql_query($sql);
    

    订单编号code是varchar类型,要加单引号:失误率极高!

    indent.code='{$code}'  
  • 报错,排错方法
  1. 打印出$sql语句
  2. 把打印出的sql语句在mysql中执行,报出具体错误
    echo $sql;
    exit;
    
  • 加载出缩略图 thumb_{}

    echo "<td><img src='../../public/uploads/thumb_{$row['img']}' width='50px'></td>";
  • 输出合计

    echo "<td>".$row['price']*$row['num']."</td>";

16、后台权限把控:后台每一个页面都要写(或模块化引入)

  • 否则,毫无安全可言!
    <?php
        session_start();
    
        if(!$_SESSION['userid']){
           echo "<script>location='login.php'</script>";
           exit;     //防止程序在跳转之前,突然的,执行下去下面的代码了
        }
    ?>

17、session数组:将数据存放在服务器中

  • 开启session
    session_start();
  • 设置session
    $_SESSION['username']='user1';
    $_SESSION['user_id']='15';
  • 删除session
  1. 开启session
    session_start();
  2. 清空session数组
    $_SESSION=array();
  3. 删除客户端的cookie文件
    setcookie('PHPSESSID','',time()-1,'/');
  4. 删除服务器上PHPSESSID所对应的session文件
    session_destroy();

18、退出后台登录

<?php
   session_start();

   $_SESSION = array();     //清空session数组
   session_destroy();       //删除服务器上PHPSESSID所对应的session文件
   setcookie('PHPSESSID','',time()-3600,'/');       //删除客户端的cookie文件

   echo '<script>location="login.php"</script>';
?> 

19、前台广告  动态放置

  • index.php:从广告表中查到所有数据,放入一个二维数组中;为了与位置一一对应,将位置设置为数组下标
    <?php
       include '../public/common/conn.php';
    
       $sqlAdvert = "select * from advert";
       $rstAdvert = mysql_query($sqlAdvert);
       while($rowAdvert=mysql_fetch_assoc($rstAdvert){
             $rowAds[$rowAdvert['pos']]=$rowAdvert;
       }
    ?>
        <div class="ads">
              <img src="../public/upadverts/<?php echo $rowAds[0]['img']?>" alt="">
        </div>

20、网站下不要用绝对路径,这样文件名改动会出问题

  • header.php:explode('/',$path);  //截取字符串函数
    <?php
        $path = $_SERVER['PHP_SELF'];
        $arr = explode('/',$path);
        $root = '/'.$arr[1];   //获取根目录
    ?>
    
    <a href="">
        <img src="<?php echo $root?>/home/public/img/logo.png" alt="">
    </a>

21、首页 重复加载的相似度很高的【楼层、数据块】都要通过  php循环加载

  1. 前台页面中写sql语句一般都带一个表名,因为一个页面要查很多不同的表
  2. 在select查找时,order by rand() limit 4 随机取4个
    <?php
       $sqlClass = "select * from class order by id limit 2";
       $rstClass = mysql_query($sqlClass);
       $f = 1;
       while($rowClass=mysql_fetch_assoc($rstClass)){
    ?>
    <!--楼层开始-->
       …… …… ……
       <?php
           $sqlBook = "select book.* from book,class where book.class_id = class.id and class.id = 
                           {$rowClass['id']} and book.shelf=1 order by book.id limit 4";
           $rstBook = mysql_query($sqlBook);
           while($rowBook = mysql_fetch_assoc($rstBook)){
       ?>
       <!--楼层数据块开始-->
             …… …… ……
       <!--楼层数据块结束-->
    <?php
        }
       }
    ?>
    <!--楼层结束-->  

22、前台页面中 动态循环添加数据

  • 第一步:先查数据表
    $id=$_GET['class_id'];
    $sqlClass="select * from class where id = {$id} ";
    $rstClass=mysql_query($sqlClass);
  • 第二步:如果抓取一行->数组[下标]
    $rowClass=mysql_fetch_assoc($rstClass);
  1. 如果抓取多行->while循环
    while($rowClass=mysql_fetch_assoc($rstClass)){
       …… ……
    }
  2. 需要数据处:
    <?php echo $rowClass['name']?>

23、打印  查看:查到的数据结果

<?php
    …… ……
    while($rowClass=mysql_fetch_assoc($rstClass)){
         echo '<pre>';
         print_r($rowClass);
         echo '</pre>';
    }
?>

24、前台不同页面之间 跳转 通过a链接传递参数,查表,得到想要的结果

  • book.php 中  分类>>类别名称  需要传一个class_id
    <span><a href='class.php?class_id=<?php echo $class_id?>'>分类</a> » <?php echo $rowClass['name']?></span>
  • 分类页面 图书分页显示部分   第一页/上一页/下一页/尾页   传两个值 :pageclass_id
    if($page>=1 && $totalpage>1){
        echo "<a href=?page=1&class_id={$rowClass['id']}>第一页  </a>";
    }

25、header.php 中控制登录、注册、切换用户名

  • 用session判断,前面需要开session_start();  只能放在第一行,前面不允许有任何输出
  1. 但是,header.php是被包含的页面,其它页面前面会有输出
  2. 所以,heder.php里不能加session_start();   要在加的页面里加
    <?php
       if(!$_SESSION['home_username']){
          echo "<a href='{$root}/home/login.php'>登录</a>";
       }else{
          echo "  <a href='{$root}/home/person/index.php'>欢迎
                  {$_SESSION['home_username']}登录</a>  <a href='{$root}/home/logout.php'>退出</a>";
       }
    ?>
  3. 重新打开浏览器,会有undefined:用@解决
    @$_SESSION['home_username'];   

26、个人中心 左右结构页面

  • 第一种:复杂式
  1. 左侧 不同的栏目给不同的参数
  2. 右侧 给一个switch,根据左侧给的不同参数,发生不同的变化
  3. 优点:只需写一个页面
  4. 缺点:共用的php里易写乱,易出错
  • 第二种:简单式(
  1. 复制页面,写好一个,复制给不同的页面,然后用链接跳转。
  • 易错:echo " ";  里原本html里面的双引号,都要改为单引号

27、通过session方法开发购物车,用户关闭浏览器后,自动清空购物车

  • 点击【加入购物车】
  1. 先要跳转到 cart/insert.php 添加进购物车
  2. 确定后,才跳转到 index.php 查看购物车
  • 用户选择  →  加入购物车 后,如果最后没有购买,结账  → 用户关闭浏览器后,自动清空购物车
  1. 浏览器关闭后,session数组立刻清空,session自动过期
  2. PHPSESSID 保存在浏览器 cookie中
  • 购物车核心原理:数组改造,大数组里面放小数组   insert.php
    session_start();
    
    $id = $_GET['id'];
    $sql = "select * from book where id = {$id}";
    $rst = mysql_query($sql);
    $row = mysql_fetch_assoc($rst);
    
    $_SESSION['books'][$id]=$row;   //用id限制同一图书只能加一个,然后在购物车页面中进行加减数量
    
    //在图书信息的子数组中临时加一个num 默认1, 方便index.php中使用变量 <?php echo $book['num']?>
    $_SESSION['books'][$id]['num']=1;
  • 跳转到 index.php 查看
    echo '<script>location="index.php"</script>';
    

    有了数组,就不用while了,用foreach遍历数组  index.php

    <?php
        foreach($_SESSION['books'] as $book){
    ?>
        …… ……
    <?php
        }
    ?>
  • 删除购物车图书  delete.php
    // 在session中找到 删除 
    unset($_SESSION['books'][$id]);
  • 清空购物车图书
     $_SESSION['books']=array(); 
    

    不可以unset,那样会把 $_SESSION['books']删掉  

  • 购物车计算总额
    $tot = 0
    

    遍历后(foreach 或 while循环)

    $tot += $row['price']*$row['num']; 
  • 购物车图书数量加减:add.php 、cut.php
    $_SESSION['books'][$id]['num']++;
    $_SESSION['books'][$id]['num']--;
    

    限制数量 加→不能多于库存  减→不能少于1个

    if($_SESSION['books'][$id]['num']<1){
       $_SESSION['books'][$id]['num'] = 1;
    }
    if($_SESSION['books'][$id]['num'] > $_SESSION['books'][$id]['stock']){
       $_SESSION['books'][$id]['num'] = $_SESSION['books'][$id]['stock'];
    }

28、购物车的  联系方式、提交订单

  • 个人中心的所有页面,都要 提示 先登录,才可以看到
    <!--判断用户是否登录 session-->
    <?php
        if($_SESSION['home_username']){
    ?> 
        ……
    <?php
       }
    ?>
  • 用户在【不关闭浏览器】情况下
  1. 退出登录 → 保留session中购物车的数组内容
  2. 实现换个账号结算购物车交换数组内容(购物车内容不变)
    $arr=$_SESSION['books'];
    
    $_SESSION = array(); //清空session数组
    
    $_SESSION['books']=$arr;

29、登录后不仅要在session中放入username ,一般还要放入userid

  • 使用userid进行判断,获取数据
  • 方便后面在 【用户个人信息】(等其它只有用户自己可看到的页面)中 获取 userid
    $_SESSION['home_userid'] = $row['id'];
    
    $user_id = $_SESSION['home_userid'];
    $sql = "select * from touch where user_id = {$user_id}";
    $rst = mysql_query($sql);

30、在各个 后台数据管理模块中 修改都要有一个隐藏域 传id

31、购物车生成订单

  • 需要form表单传一个touch的id,其余的图书信息都在购物车的session数组中存放,可直接取
  • 核心要点:借用session技术跨页面 ↑ 
  • 注意:一定要把 form表单 放在table的外面,因为一些浏览器会不支持table里面放form,只支持form里面放table
  • 生成 订单号 为确保唯一性:随机数 加 时间戳
    $code =time().mt_rand();
    $code =microtime(true).time().mt_rand();   //microtime(true)微秒
    $code =time().mt_rand().mt_rand(1,10);
    $code =time().mt_rand().range('a','z'); 

32、购物车 提交订单之后,要做两件事

  • 第一:库存减去 数量
  • 第二:购物车清空
  • book.php:加入购物车之前 要判断一下 库存stock至少等于1

33、提交订单的用户,只有在 ‘已确认’状态下,才可以评论

34、在CSS样式表里,用class类

  • 最好不用id 标签
  • 因为 class 类 优点:唯一的能用,不唯一的也能用

二、运行效果图

1、注册功能

注册界面
 
 错误提示
通过提示

2、二手书搜索功能

 高级搜索成功界面
 
 搜索失败提示

3、二手书发布功能

 用户发布二手书界面
 
 用户发布二手书成功

4、二手书购买与评论功能

 加入购物车界面
 
 购物车界面
 提交订单成功
 
 未确认时查看订单界面
 
 未确认时查看订单详情界面
 
 确认时查看订单详情界面
 确认后撰写评论
 
 评论成功

注:转载请注明出处 

猜你喜欢

转载自www.cnblogs.com/ljq66/p/10753355.html