【千纸诗书】—— 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、传文件函数

  • 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/5002 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‘]?>" > </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" ></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、二手书购买与评论功能

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

 


注:转载请注明出处 

相关文章