layui框架实战案例(22):多附件上传实战开发实录(php后端、文件删除、数据库删除)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: layui框架实战案例(22):多附件上传实战开发实录(php后端、文件删除、数据库删除)

前言

在发布文章时,可以将附件上传至富文本编辑器,但是对文件删除时,无法将其从服务器删除。为了便于附件的管理,将附件上传管理,进行单独的项目开发。具体步骤如下:


开发步骤

  • 服务器端的文件上传处理;
  • 保存上传文件的信息,包括文件名、大小、类型、上传时间等;
  • 在界面上展示上传的附件,并提供下载和删除等操作。


保存上传文件的信息

要保存上传的文件信息,你可以将文件信息保存在数据库中,也可以直接将信息保存在服务器文件系统的某个目录中。以下示例展示了如何将文件信息保存在MySQL数据库中。需要在上传文件时,同时保存文件信息,比如文件名、大小、类型、上传时间等。

上传信息

<?php
if(isset($_FILES['file'])){
    $file_name = $_FILES['file']['name'];
    $file_size =$_FILES['file']['size'];
    $file_tmp =$_FILES['file']['tmp_name'];
    $file_type=$_FILES['file']['type'];
    // 设置目标文件夹,并保存上传文件
    $target_dir = "uploads/";
    $target_file = $target_dir . $file_name;
    move_uploaded_file($file_tmp,$target_file);
    // 保存文件信息到数据库
    $conn = mysqli_connect("localhost","my_user","my_password","my_db");
    $sql = "INSERT INTO attachments (filename, filesize, filetype, fileurl, uploadtime) VALUES ('$file_name', '$file_size', '$file_type', '$target_file', now())";
    mysqli_query($conn,$sql);
    mysqli_close($conn);
}


在layui中,如何进行开发呢?


一、HTML容器

1.新增信息页

新增信息页,上传附件默认是无对应的项目id的,此处以上传token作为唯一索引值,在项目提交时,统一将token更新为项目id.

   <!--附件管理-->
                        <div class="layui-form-item">
                            <label for="uploadAttach" class="layui-form-label">附件管理<span class="x-red">* </span></label>
                            <div class="layui-inline layui-upload"><button type="button" class="layui-btn" id="uploadAttach">上传附件</button> 建议以.pdf格式上传,同时支持docx/xlsx/pptx</div>
                            <!--附件明细-->
                            <div class="layui-form-item">
                                <table class="layui-table">
                                    <tbody id="upfiles"></tbody>
                                </table>
                            </div>
                        </div>


2.信息编辑页

在信息处于编辑状态时,将数据库中的数据读出,并在表格内遍历输出。

 <!--附件管理-->
                        <div class="layui-form-item">
                            <label for="uploadAttach" class="layui-form-label">附件管理<span class="x-red">* </span></label>
                            <input type="hidden" name="mod_content3" id="mod_content3" value="upfiles">
                            <div class="layui-inline layui-upload"><button type="button" class="layui-btn" id="uploadAttach">上传附件</button> 建议以.pdf格式上传,同时支持docx/xlsx/pptx</div>
                            <!--附件明细-->
                            <div class="layui-form-item">
                                <table class="layui-table">
                                    <tbody id="upfiles">
                                    {foreach $data_up as $p}
                                    <tr align="center">
                                        <td>{$p['up_name']}</td>
                                        <td>{$p['up_time']}</td>
                                        <td><a href="javascript:;" onclick="delAll(this,'{$p['up_id']}','{$p['up_url']}')">删除</a></td>
                                    </tr>
                                    {/foreach}
                                    </tbody>
                                </table>
                            </div>
                        </div>

二、layUI上传

        //上传附件;
        upload.render({
            elem: '#uploadAttach'
            , url: '?m=Upload&a=uploadDeal&act=upAttach&fromType=attachment&token=' + token
            , data: {
                from_id: 0,
                up_types: 0
            }
            , multiple: false
            , size: 102400
            , accept: 'file'
            , exts: 'jpg|pdf|doc|docx|xls|xlsx|ppt|pptx'
            , number: 1
            , before: function () {
                loadingIndex = layer.load();
            }
            , done: function (res) {
                layer.close(loadingIndex);
                if (res.code == 0) {
                    layer.msg('上传失败:' + res.msg);
                } else {
                    //console.log(res.data);
                    var trHtml = "<tr align=\"center\">" +
                        "<td>" + res.data.up_name + "</td>" +
                        "<td>" + res.data.up_time + "</td>" +
                        "<td><a href=\"javascript:;\" οnclick=\"delAll(this,'"+ res.data.up_id +"','"+ res.data.up_url +"')\">删除</a></td>" +
                        "</tr>";
                    $("#upfiles").append(trHtml);
                }
            }
        });


三、php后端上传

1.接受参数

按照开发需求,接受前端传递过滤的参数,主要涉及:


$fromType,文件类型,根据不同的类型,创建不同的文件目录,便于管理;

$token,验证密钥,防止越权漏洞上传;

$from_user_id,上传用户id,为文件命名,便于查询上传用户;

from_name,用户昵称,数据库记录;


        $fromType = get_param('fromType');
        $token = get_param('token');
        $from_user_id = AuthCode($_COOKIE["admin_id"], "DECODE", "", 0);
        $user_id = $from_user_id . "_ad";
        $from_name = $_COOKIE["admin_name"];
        $from_id = $_POST['from_id'];
        $up_types = $_POST['up_types'];

2.设置目录

        //创建目录;
        $upload_dir = 'upload';
        $imgUrl = $upload_dir . '/' . $fromType;
        if (!is_dir($upload_dir)) {
            mkdir($upload_dir);
        }
        if (!is_dir($imgUrl)) {
            mkdir($imgUrl);
        }
        //上传信息;
        $file = $_FILES['file'];
        $uploaded_type = $file['type'];
        $uploaded_tmp = $file['tmp_name'];
        $uploaded_ext = substr($file['name'], strrpos($file['name'], '.') + 1);
        $fileName = $user_id . "_" . md5(time()) . "." . $uploaded_ext;
        $temp_file = $upload_dir . '/' . $fileName;


3.安全验证

 //01.获取验证token
        if ($token != $_SESSION['upToken'] || $token == "") {
            $res['code'] = 0;
            $res['msg'] = "非法传参页面,请刷新重新上传";
            session_destroy(); //验证码自动销毁;
            die(json_encode_lockdata($res));
        }
        //02.服务器端检查上传文件类型;
        if ($uploaded_tmp == "") {
            $res['code'] = 0;
            $res['msg'] = "无法获取上传文件";
            die(json_encode_lockdata($res));
        }
        //03.后缀判断;
        $allow_ext = array('pdf', 'jpg', 'png', 'mp4', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx');
        if (!in_array($uploaded_ext, $allow_ext)) {
            $res['code'] = 0;
            $res['msg'] = "不支持" . $uploaded_ext . "文件类型上传";
            die(json_encode_lockdata($res));
        }
        //04.检测内容是否包含木马;
        if (checkHex($uploaded_tmp) != 0) {
            $res['code'] = 0;
            $res['msg'] = "文件包含危险信息";
            die(json_encode_lockdata($res));
        }
        //05执行上传;
        if (isset($_FILES['file']) && $_FILES['file']['error'] == "0") {
            move_uploaded_file($file['tmp_name'], $imgUrl . "/" . $fileName);
            $safe_img = $imgUrl . "/" . $fileName;


4.数据入库

//数据入库
$db->insert('upfiles', array('up_name' => $file['name'], 'up_url' => $safe_img, 'up_types' => $up_types, 'from_id' => $from_id, 'from_user_id' => $from_user_id, 'from_name' => $from_name, 'up_token' => $token, 'up_time' => time()));
//获取数据表记录;
$up_id = $db->lastinsertid();
$row = $db->fetch('upfiles', 'up_id,up_name,up_url,FROM_UNIXTIME(up_time) AS up_time', array('up_id' => trim($up_id)), ' up_id DESC');


5.返回数据

将数据以json方式输出,便于前端调用。

            //返回JSON;
            $res['code'] = 1;
            $res['data'] = $row;
            $res['msg'] = '上传成功!';
            die(json_encode_lockdata($res));
        }


6.删除信息和文件

 $up_id = $_POST['up_id'];
        $up_url = $_POST['up_url'];
        if (is_array($up_id)) {
            $up_id = implode(",", $up_id);
        }
        if ($up_id == '') {
            die("up_id错误");
        }
        //删除文件
        if (is_array($up_url)) {
            foreach ($up_url as $v) {
                if (file_exists($v)) {
                    unlink($v);
                }
            }
        } else {
            if (file_exists($up_url)) {
                unlink($up_url);
            }
        }
        $db->delete('upfiles', 'up_id in(' . $up_id . ')');


总结

Layui是一个前端UI框架,它提供了多附件上传的组件,可以方便地在前端实现多附件上传功能。以下是关于Layui多附件上传的总结:

  1. Layui多附件上传组件的使用方法非常简单,只需要加载相关的js和css文件,然后在HTML中定义上传的元素即可。
  2. Layui的多附件上传组件默认支持最多同时上传6个文件,可以通过设置number属性值来改变同时上传的文件数量。
  3. Layui的多附件上传组件还支持限制上传文件的大小和类型,可以通过设置size和ext属性值来实现。
  4. Layui的多附件上传组件提供了多种上传状态的UI显示,比如上传中、上传成功、上传失败等,可以方便地为用户提供良好的上传体验。
  5. Layui的多附件上传组件还支持预览、下载和删除等操作,可以通过设置done回调函数来实现处理上传成功后的附件信息,并进行展示和操作。
  6. 当然,通过Layui提供的多附件上传组件,可以快速而方便地实现多附件上传和管理,并为用户提供良好的使用体验。在本次开发中,采用的是layui上传组件,但是没有使用多文件上传。


@漏刻有时


相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
缓存 安全 前端开发
构建高效后端服务:从理论到实战
在数字化浪潮的推动下,后端服务成为了支撑现代互联网应用的核心。本文旨在揭示如何打造一个既可靠又高效的后端系统,从基础架构设计、代码组织、性能优化到安全防护,全方位解析后端开发的艺术。通过实际代码示例和深入浅出的解释,引导读者理解并掌握后端开发的关键技术点。
|
2月前
|
编译器 PHP 开发者
PHP 8新特性解析与实战应用####
随着PHP 8的发布,这一经典编程语言迎来了诸多令人瞩目的新特性和性能优化。本文将深入探讨PHP 8中的几个关键新功能,包括命名参数、JIT编译器、新的字符串处理函数以及错误处理改进等。通过实际代码示例,展示如何在现有项目中有效利用这些新特性来提升代码的可读性、维护性和执行效率。无论你是PHP新手还是经验丰富的开发者,本文都将为你提供实用的技术洞察和最佳实践指导。 ####
34 1
|
2月前
|
自然语言处理 安全 PHP
深入浅出PHP编程:从基础到实战
【10月更文挑战第36天】本文将带你走进PHP的奇妙世界,无论你是初学者还是有一定经验的开发者,都将从中获益。文章首先介绍PHP的基础概念和语法,然后通过实际代码示例,展示如何利用PHP进行高效的Web开发。最后,我们将探讨一些高级主题,如面向对象编程、数据库操作以及安全性问题。让我们一起开启PHP的学习之旅吧!
|
2月前
|
存储 Serverless PHP
PHP编程入门:从基础到实战
【10月更文挑战第35天】本文将带你走进PHP的世界,从最基本的语法开始,逐步深入到实际应用。我们将通过简单易懂的语言和实际代码示例,让你快速掌握PHP编程的基础知识。无论你是初学者还是有一定经验的开发者,都能在这篇文章中找到你需要的内容。让我们一起探索PHP的魅力吧!
|
2月前
|
存储 SQL 数据库
深入浅出后端开发之数据库优化实战
【10月更文挑战第35天】在软件开发的世界里,数据库性能直接关系到应用的响应速度和用户体验。本文将带你了解如何通过合理的索引设计、查询优化以及恰当的数据存储策略来提升数据库性能。我们将一起探索这些技巧背后的原理,并通过实际案例感受优化带来的显著效果。
56 4
|
2月前
|
运维 NoSQL Java
后端架构演进:微服务架构的优缺点与实战案例分析
【10月更文挑战第28天】本文探讨了微服务架构与单体架构的优缺点,并通过实战案例分析了微服务架构在实际应用中的表现。微服务架构具有高内聚、低耦合、独立部署等优势,但也面临分布式系统的复杂性和较高的运维成本。通过某电商平台的实际案例,展示了微服务架构在提升系统性能和团队协作效率方面的显著效果,同时也指出了其带来的挑战。
87 4
|
2月前
|
前端开发 中间件 PHP
PHP框架深度解析:Laravel的魔力与实战应用####
【10月更文挑战第31天】 本文作为一篇技术深度好文,旨在揭开PHP领域璀璨明星——Laravel框架的神秘面纱。不同于常规摘要的概括性介绍,本文将直接以一段引人入胜的技术剖析开场,随后通过具体代码示例和实战案例,逐步引导读者领略Laravel在简化开发流程、提升代码质量及促进团队协作方面的卓越能力。无论你是PHP初学者渴望深入了解现代开发范式,还是经验丰富的开发者寻求优化项目架构的灵感,本文都将为你提供宝贵的见解与实践指导。 ####
|
11天前
|
存储 Oracle 关系型数据库
数据库传奇:MySQL创世之父的两千金My、Maria
《数据库传奇:MySQL创世之父的两千金My、Maria》介绍了MySQL的发展历程及其分支MariaDB。MySQL由Michael Widenius等人于1994年创建,现归Oracle所有,广泛应用于阿里巴巴、腾讯等企业。2009年,Widenius因担心Oracle收购影响MySQL的开源性,创建了MariaDB,提供额外功能和改进。维基百科、Google等已逐步替换为MariaDB,以确保更好的性能和社区支持。掌握MariaDB作为备用方案,对未来发展至关重要。
39 3
|
11天前
|
安全 关系型数据库 MySQL
MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!
《MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!》介绍了MySQL中的三种关键日志:二进制日志(Binary Log)、重做日志(Redo Log)和撤销日志(Undo Log)。这些日志确保了数据库的ACID特性,即原子性、一致性、隔离性和持久性。Redo Log记录数据页的物理修改,保证事务持久性;Undo Log记录事务的逆操作,支持回滚和多版本并发控制(MVCC)。文章还详细对比了InnoDB和MyISAM存储引擎在事务支持、锁定机制、并发性等方面的差异,强调了InnoDB在高并发和事务处理中的优势。通过这些机制,MySQL能够在事务执行、崩溃和恢复过程中保持
41 3
|
11天前
|
SQL 关系型数据库 MySQL
数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog
《数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog》介绍了如何利用MySQL的二进制日志(Binlog)恢复误删除的数据。主要内容包括: 1. **启用二进制日志**:在`my.cnf`中配置`log-bin`并重启MySQL服务。 2. **查看二进制日志文件**:使用`SHOW VARIABLES LIKE &#39;log_%&#39;;`和`SHOW MASTER STATUS;`命令获取当前日志文件及位置。 3. **创建数据备份**:确保在恢复前已有备份,以防意外。 4. **导出二进制日志为SQL语句**:使用`mysqlbinlog`
53 2