IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> PHP保姆级入门练手商品后台维护项目详解 -> 正文阅读

[PHP知识库]PHP保姆级入门练手商品后台维护项目详解

目录

项目成果

商品后端维护功能

前端功能

数据库表

?项目效果图

项目的收获

WEBAPP开发总体思想

前端开发

后端开发

后端代码的分层作用

前端开发

首页核心代码

添加商品页面核心代码

商品维护页面核心代码

后端开发

数据库工具类

实体

DAO层

Service层

Controller层

PHP项目运行遇到的坑


文章初衷就是学习PHP开发后端项目的过程,推荐一个模块一个模块做,项目代码有没有放文末,这是个随机事件:) ,如果觉得文章不错麻烦动动小手指点个赞吧哈哈。

项目成果

商品后端维护功能

  1. 添加商品(需要有商品图片,在服务器保存)
  2. 商品的上架(status字段的取值为“新增”“已上架”“已下架”)
  3. 商品的基本信息修改(状态为已上架商品不能修改)
  4. 商品的删除(状态为已上架商品不能删除)

前端功能

  1. 商品列表页面
  2. 添加商品页面
  3. 商品维护页面

数据库表

? ? ? ?商品Product(主键ID,商品名称Name,图片Pic,价格Price,状态Status)? ??

?项目效果图

商品列表首页?

添加商品页面

商品维护页面

?前端好麻烦,这里偷懒了。。。

项目的收获

  1. 熟悉PHP开发后端的流程
  2. 熟悉前后端数据交互的流程
  3. 后端连接数据库和增删改查的流程
  4. 前端如何把本地图片上传并实时显示
  5. 上传图片到服务器的流程

WEBAPP开发总体思想

WEBAPP就是网页应用(WEB application)

前端开发

????????负责渲染网页、编写Ajax传输请求数据与获得响应数据。

后端开发

????????负责与服务器的数据库打交道(DAO层)、业务逻辑(Service层)、编写响应前端的方法(Controller层)。

????????一开始没经验开发小项目中代码分层就会让我觉得很麻烦很愚蠢,写了很多没必要的代码。

后端代码的分层作用

????????使我们的项目工程化,而在大项目中代码量很多这个时候我们的大脑就容易混乱注意力不集中,分层就能很好集中我们的注意力开发特定的模块,使项目开发有规律可循并稳定前进。

????????在计算机网络操作系统计算机组成原理这些知识体系中分层思想出现较为频繁。

前端开发

网页样式使用BootStrap框架的样式,使得前端页面开发变得简单高效,我代码部分就不贴出引用部分了。

首页核心代码

这里HTML部分我就简单贴出body

<body>
<h1>你好,世界!</h1>
<p class="addBlock"><a href="addGoods.html" class="btn btn-primary addBtn" role="button">添加商品</a></p>
<!-- 商品列表容器 -->
<div class="row">

</div>
</body>

JS部分使商品模块渲染的关键,这里是发送请求到后端,后端响应商品数据回来的ajax。

window.onload = function () {
    var rowDiv = document.getElementsByClassName('row')[0];
    //请求获得商品数据,并渲染页面
    $.ajax({
        url:'../controller/GoodsController.php',
        type:'POST',
        data:'Action=queryAllGoods',
        dataType: 'json',
        // processData: false,
        // contentType: false,
        success: function (response) {
            console.log(response);
            var htmlstr = '';
            var status = ["已下架","已上架","新增"];
            for(var i = 0; i < response.length; i++){
                var goods = response[i];
                var lable;
                if(goods.status == 0) lable = "label label-default";
                else if(goods.status == 1) lable = "label label-success";
                else if(goods.status == 2) lable = "label label-danger";
                // console.log(goods.status);
                htmlstr = "<div id=\"goods"+goods.id+"\" class=\"col-xs-6 col-md-2 \">\n" +
                    "        <div class=\"thumbnail \">\n" +
                    "            <span class=\"goodsStatus "+ lable+"\">"+ status[goods.status]+ "</span>\n" +
                    "            <img src=\""+goods.pic+"\" class=\"goodsImg\">\n" +
                    "            <span class=\"goodsPrice label label-info\">¥"+ goods.price+ "</span>\n" +
                    "\n" +
                    "            <div class=\"caption\">\n" +
                    "                <h3 class=\"goodsName\">"+ goods.name+ "</h3>\n" +
                    "                <p class=\"goodsDetail\">"+goods.detail+ "</p>\n" +
                    "                <p><a href=\"updateGoods.html?id="+goods.id+"\" class=\"btn btn-primary\" role=\"button\">商品维护</a> <a onclick=\"delGoods("+goods.id+","+goods.status+")\" class=\"btn btn-default\" role=\"button\">删除商品</a></p>\n" +
                    "            </div>\n" +
                    "        </div>\n" +
                    "    </div>";
                rowDiv.innerHTML += htmlstr;
            }
        },
        error: function (jqXHR, textStatus, errorMessage) {
            console.log(errorMessage); // Optional
        }
    });
};

响应js的后端代码(大概看过一下,具体在后面)

$Action = '';
//当有post请求到这个php时可以使用$_POST取出请求信息
if(isset($_POST['Action'])){
    $Action = $_POST['Action'];
}
if($Action == 'queryAllGoods'){//获得所有商品信息
    $goodsService = new GoodsService();
    echo $goodsService->getAllGoods();
} 

添加商品页面核心代码

HTML结构,CSS自己写写吧。。

<body>
    
    <div class="container">
        <p  class="returnBtn"><a href="index.html" class="btn btn-primary" role="button">返回</a></p>
        <div class="leftDiv">
            <!-- <form> -->
                <li class="list-group-item list-group-item-info">商品名称</li>
                <div class="panel panel-info">
                    <input id="goodsName" type="text" class="form-control"  aria-describedby="basic-addon1">
                </div>
                <li class="list-group-item list-group-item-info">商品价格</li>
                <div class="panel panel-info">
                    <input id="goodsPrice" type="text" class="form-control" placeholder="输入数字" onkeyup="value=value.replace(/[^\d{1,}]/g,'')" aria-describedby="basic-addon1">
                </div>
                <li class="list-group-item list-group-item-info">商品状态</li>
                <div class="panel panel-info">
                    <!-- <input type="number" class="form-control" placeholder="0已下架 1已上架 2新增" min="0" max="2" aria-describedby="basic-addon1"> -->
                    <select id="goodsStatus" class="form-control">
                        <option value="0">已下架</option>
                        <option value="1">已上架</option>
                        <option value="2">新增</option>
                      </select>
                </div>
                <li class="list-group-item list-group-item-info">商品基本信息</li>
                <div class="panel panel-info">
                    <input id="goodsDetail" type="text" class="form-control" aria-describedby="basic-addon1">
                </div>

                <button class="btn btn-primary subBtn" onclick="addGoods()">添加商品</button>
            <!-- </form> -->
        </div>

        <div class="rightDiv">
            <img id="goodsImg" src="./img/default.jpg" class="goodsImg">
            <div align="center">
                <span class="btn btn-success fileinput-button">
                    <span>上传商品图片</span>
                    <input type="file" name="pic" id="pic" onchange="showImg()" accept="image/gif, image/jpeg, .png">
                </span>
            </div>
        </div>
    </div>

</body>

JS部分,这个也比较关键,图片上传这个需要多留意,比如,如何将本地图片上传到页面上实时显示,并将图片发送到后端。前端图片上传实时显示传送门

这里是模仿form表单的提交,使用了FormData类,其中AJAX默认关闭数据序列化,这里需要设置processData: false,contentType: false这两个属性就可以开启数据序列化。

function showImg(){
    //获取上传文件的信息
    var upfile = document.getElementById('pic').files[0];
    var goodsimg = document.getElementById('goodsImg');
    //在pic的文件里抓取该文件用于显示二进制信息
    var sr = window.URL.createObjectURL(upfile);
    // alert(sr);
    goodsimg.src = sr;
}

function addGoods(){
    // var goodsName = document.getElementById('goodsName');
    var goodsName = $("#goodsName");
    var goodsPrice = $("#goodsPrice");
    var goodsStatus = $("#goodsStatus");
    var goodsDetail = $('#goodsDetail');
    var goodsImg = $('#goodsImg');
    var upfile = document.getElementById('pic').files[0];
    var formData = new FormData();
    if(goodsName.val()==''){
        alert('添加失败:请填写商品名称');
        return;
    } else if(goodsPrice.val()==''){
        alert('添加失败:请填写商品价格');
        return;
    } else if(goodsDetail.val()==''){
        alert('添加失败:请填写商品明细');
        return;
    }
    formData.append('Action','addGoods');
    formData.append('status',goodsStatus.val());
    formData.append('name',goodsName.val());
    formData.append('price',goodsPrice.val());
    formData.append('detail',goodsDetail.val());
    formData.append('upfile',upfile);

    $.ajax({
        url: "../controller/GoodsController.php",
        type: "POST",
        data: formData,
        dataType: 'json', //返回的数据类型
        processData: false,
        contentType: false,
        success: function (response) {
            alert(response);
        },
        error: function (jqXHR, textStatus, errorMessage) {
            console.log(errorMessage); // Optional
        }
    });

}

商品维护页面核心代码

? ? ? ? 这个就跟添加商品差不多,我就不贴出来了,我这里就只贴出如何或获得首页穿过来的参数,疯狂偷懒。。。

//获得当前页面地址
var url = location.href;
//因为就一个参数这里我偷懒,按=切开字符串
var id = parseInt(url.split('=')[1]);

后端开发

代码逻辑都比较简单,这里代码我就只贴出关键部分,其他的看自己需要补充。

代码贴出顺序是由底向上。

数据库工具类

class DBHelper
{
    static function getConnect(){
        $conn = mysqli_connect(
            "localhost",
            "root",
            "1234",
            "goods_php",//数据库名
            8806);//数据库端口
        //防止中文乱码
        mysqli_query($conn,"set names 'utf8'");
        return  $conn;
    }
}

实体

setter和getter我就不贴出来了,这我用private封装后会

class Goods
{
    var $id; //商品id
    var $name; //商品名称
    var $pic; //商品图片地址
    var $price; //商品价格
    var $status; //商品状态 0已下架 1已上架 2新增
    var $detail;
}

DAO层

主要与本地数据库数据打交道的层,这里我代码就只贴出关键部分

class GoodsDao
{

    //添加商品信息
    function addGoods($goods){
        $Name = $goods->getName();
        $Pic = $goods->getPic();
        $Price = $goods->getPrice();
        $Status = $goods->getStatus();
        $Detail = $goods->getDetail();
        $conn = DBHelper::getConnect();
        $conn->query(
            "insert into product(Name,Pic,Price,Status,Detail) values('$Name','$Pic','$Price','$Status','$Detail')"
        );
        $result = mysqli_affected_rows($conn);
        mysqli_close($conn);
        return $result;
    }

    //删除商品 状态为已上架商品不能删除
    function deleteGoods($id){
        $conn = DBHelper::getConnect();
        $conn->query("delete from product where id=$id");
        $result = mysqli_affected_rows($conn); //受影响行数
        mysqli_close($conn);
        return $result;
    }

    function updateGoods($id,$goods){
        $Name = $goods->getName();
        $Pic = $goods->getPic();
        $Price = $goods->getPrice();
        $Status = $goods->getStatus();
        $Detail = $goods->getDetail();
        $conn = DBHelper::getConnect();
        $conn->query(
            "update product set Name='$Name',Pic='$Pic',Price='$Price',Status='$Status',Detail='$Detail' WHERE id='$id'"
        );
        $result = mysqli_affected_rows($conn); //受影响行数
        mysqli_close($conn);
        return $result;
    }

    //获得所有商品
    function queryAllGoods(){
        $conn = DBHelper::getConnect();
        $result = $conn->query("select * from product");
        mysqli_close($conn);
        return $result;
    }

    //获得单个商品
    function querySingleGoods($id){
        $conn = DBHelper::getConnect();
        $result = $conn->query("select * from product where id=$id");
        mysqli_close($conn);
        return $result;
    }

}

Service层

DAO与Controller之间的层

class GoodsService{
     private $goodsDao;

    /**
     * GoodsService constructor.
     * @param $goodsDao
     */
    public function __construct()
    {
        $this->goodsDao = new GoodsDao();
    }

    //添加商品
    function addGoods($goods){
        return $this->goodsDao->addGoods($goods);
    }

    //删除商品
    function deleteGoods($id){
        return $this->goodsDao->deleteGoods($id);
    }

    //获得所有商品信息
    function getAllGoods(){
        $result = $this->goodsDao->queryAllGoods();
        $arr = array();
        if ($result->num_rows > 0) {
            // 输出数据
            while($row = $result->fetch_assoc()) {
                //大坑!!!goods定义在外面,arr取的都是相同的(arr应该都是只插入对象地址)
                $goods = new Goods();
                $goods->setId($row["id"]);
                $goods->setName($row["Name"]);
                $goods->setPic($row["Pic"]);
                $goods->setPrice($row["Price"]);
                $goods->setDetail($row["Detail"]);
                $goods->setStatus($row["Status"]);
                $arr[] = $goods;
            }
        } else {
            return json_encode("0结果");
        }
        return json_encode($arr,JSON_UNESCAPED_UNICODE);
    }

    //获得单个商品信息
    function getGoods($id){
        $result = $this->goodsDao->querySingleGoods($id);
        if($result->num_rows > 0){
            $goods = new Goods();
            $row = $result->fetch_assoc();
            $goods->setId($row["id"]);
            $goods->setName($row["Name"]);
            $goods->setPic($row["Pic"]);
            $goods->setPrice($row["Price"]);
            $goods->setDetail($row["Detail"]);
            $goods->setStatus($row["Status"]);
            return json_encode($goods,JSON_UNESCAPED_UNICODE);
        } else {
            return json_encode('null');
        }
    }

    //商品信息修改 状态为已上架商品不能修改
    function updateGoods($id,$goods){
        return $this->goodsDao->updateGoods($id,$goods);
    }
}

Controller层

这一层比较关键哦,是个前后端打交道的层,决定了如何与前端合作,好好看。

tips:有兴趣研究$_POST和$_FILES的小伙伴可以用print_r函数打印出来。

$Action = '';
if(isset($_POST['Action'])){
    $Action = $_POST['Action'];
}
if($Action == 'addGoods'){//添加商品

    $goods = new Goods();
    $goods->setName($_POST['name']);
    $goods->setPrice($_POST['price']);
    $goods->setDetail($_POST['detail']);
    $goods->setStatus($_POST['status']);

    //判断是否存在文件
    if (isset($_FILES["upfile"])){
        //iconv将utf-8转为gbk,由于本地编码是GBK
        $source = iconv("UTF-8","GBK//IGNORE",$_FILES['upfile']['tmp_name']);
        $realPath = iconv("UTF-8","GBK//IGNORE",'../resource/img/'.$_FILES['upfile']['name']);
        //print_r(mb_detect_encoding($realPath, array("ASCII",'UTF-8',"GB2312","GBK",'BIG5'))); //获得$realPath编码 GBK
        //图片存入服务器
        move_uploaded_file($source, $realPath);
         //设置$realPath会乱码(此时$realPath编码为gbk)
        $goods->setPic('../resource/img/'.$_FILES['upfile']['name']);
    }else {
        $goods->setPic('null');
        echo json_encode("添加失败:图片未上传");
        return;
    }

    //商品信息持久化
    $goodsService = new GoodsService();
    $result = $goodsService->addGoods($goods);
    if($result > 0) echo json_encode("添加商品成功");
    else echo json_encode("添加商品失败");

} else if($Action == 'queryAllGoods'){//获得所有商品信息

    $goodsService = new GoodsService();
    echo $goodsService->getAllGoods();

} else if($Action == 'deleteGoods'){ //删除商品

    $goodsService = new GoodsService();
    $result = $goodsService->deleteGoods($_POST['id']);
    echo json_encode($result);
} else if($Action == 'queryGoods'){

    $goodsService = new GoodsService();
    echo $goodsService->getGoods($_POST['id']);

} else if($Action = 'updateGoods'){ //修改商品信息

    $goods = new Goods();
    $goods->setName($_POST['name']);
    $goods->setPrice($_POST['price']);
    $goods->setDetail($_POST['detail']);
    $goods->setStatus($_POST['status']);
    $goods->setPic($_POST['pic']);

    //判断内存中是否存在文件,存在的话就不用再保存到服务器了
    if (isset($_FILES["upfile"])){
        //图片存入服务器
        $source = iconv("UTF-8","GBK//IGNORE",$_FILES['upfile']['tmp_name']);
        $realPath = iconv("UTF-8","GBK//IGNORE",'../resource/img/'.$_FILES['upfile']['name']);
        move_uploaded_file($source, $realPath);
        $goods->setPic('../resource/img/'.$_FILES['upfile']['name']);
    }

    //商品信息持久化
    $goodsService = new GoodsService();
    $result = $goodsService->updateGoods($_POST['id'],$goods);
    if($result > 0){
        echo json_encode("success");
    } else {
        echo json_encode('unchanged');
    }
}

至此后端代码完结!!!

PHP项目运行遇到的坑

????????php表单提交时获取不到post数据的解决方法_hys__handsome的博客-CSDN博客

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2022-01-01 13:39:24  更:2022-01-01 13:41:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 20:35:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计