PHP多文件压缩并分片下载文件详细介绍,附上完整代码

简介: 有时我们经常需要压缩下载多个文件,我这里主要采用在fastadmin框架中添加了一个表格自定义按钮,并为按钮绑定相应的事件来实现。

一、写在文章开始:

      有时我们经常需要压缩下载多个文件,我这里主要采用在fastadmin框架中添加了一个表格自定义按钮,并为按钮绑定相应的事件来实现。

      添加自定义按钮可以参考我的博客:fastadmin在表格列表中创建一个自定义按钮。

     本代码可以实现文件的压缩下载,但对于大文件的下载会出现问题。后续在第二篇中会介绍另一种代码执行效率较高的代码。

     需要注意的是:在点击按钮触发控制器对应的方法时不能采用ajax的方式,因为Ajax的返回值类型是json,text,html,xml类型,或者可以说ajax的接收类型只能是string字符串,不是流类型,所以无法实现文件下载。但用Ajax仍然可以获得文件的内容,该文件将被保留在内存中,无法将文件保存到磁盘。这是因为JavaScript无法和磁盘进行交互,否则这会是一个严重的安全问题,js无法调用到浏览器的下载处理机制和程序,会被浏览器阻塞。

0d22f34dbd49476dad0aea5cc3642158.png


二、完整代码及详细讲解

(1)获取到你需要下载的文件的链接集合,得到一个数组,我在这里的存储的路径格式为:/uploads/20230714/文件名.文件后缀(pptx/excel)。


(2)创建压缩包存放目录,这里使用的存放目录是存在了public/uploads/zip文件夹下创建了日期文件夹。mkdir()是创建目录的函数。


(3)实例化ZipArchive类,打开压缩包,循环文件添加到压缩包中。

在PHP中使用ZipArchive类可以从一个充满文件的文件夹中创建一个压缩包。这个类的实例创建了一个句柄来读取或写入压缩档案的文件。

(4)最后分片下载文件,使用的是fread()函数。

friad函数详解:

fread() 函数读取打开的文件。

函数会在到达指定长度或读到文件末尾(EOF)时(以先到者为准),停止运行。

该函数返回读取的字符串,如果失败则返回 FALSE。

总的代码如下:

    public function download()
    {
        //获取需要下载哪个用户的资源
        $id = input();
        $row = db('files')->where('id', $id['ids'])->find();
        $datas = db('files')->where('uid', $row['uid'])->select();
        //获取到数据表中某用户对应的数据集合,表中存储的是文件路径
        $arr = [];
        foreach ($datas as $key => $value) {
            array_push($arr, $value['path']);
        }
        // 压缩多个文件
        //创建压缩包存放目录
        $path = "./uploads/zip/" . date('Y-m-d');
        if (!file_exists($path)) {
            mkdir(iconv("UTF-8", "GBK", $path), 0777, true);
        }
        $zip = new \ZipArchive();
        $zip_name = $path . '/' . date('H-i-s') . '.zip';
        $res = $zip->open($zip_name, \ZipArchive::CREATE); //打开压缩包
        if ($res === true) {
            //循环文件添加到创建好的压缩包中
            foreach ($arr as $file) {
                $path_url = '.' . $file;
                $handle = fopen($path_url, 'rb');  //打开文件目录对应的文件
                $zip->addFile($path_url, basename($file)); //向压缩包中添加文件
                fclose($handle);  //关闭文件
            }
        }
        $zip->close(); //关闭压缩包
        if (!file_exists($zip_name)) {
            exit("无法找到文件"); //即使创建,仍有可能失败
        }
        //如果报错,检查服务器上面的压缩文件是否可以正确的解压,如果可以你就可以加一个ob_clean试一下报错是否还存在
        ob_clean();
        header('Content-Type:application/zip;charset=utf-8');
        header('Content-disposition:attachment;filename=' . basename($zip_name));
        $filesize = filesize($zip_name);   //要下载文件的大小
        header('Content-length:' . $filesize);
        // readfile($zip_name);   //可以直接使用readfile方法来进行下载
        //分片下载
        $read_buffer = 1024*1024;分片大小,这里设置为1MB
        $sum_buffer = 0;
        $f = fopen($zip_name, 'rb');
        if ($f === false)  exit("文件打开失败");
        //一般在文件操作,中经常使用feof()判断文件是否结束。
        while(!feof($f) && $sum_buffer<$filesize) {
            echo fread($f, $read_buffer);
            $sum_buffer += $read_buffer;
        }
        fclose($handle);
        exit;
    }


欢迎留言评论进行指导,我是一个虚心学习的程序员。

目录
相关文章
|
6天前
|
PHP 开发者
PHP中的命名空间:优雅解决代码冲突与组织结构
在PHP开发中,命名空间是一种重要的工具,可以帮助开发者避免代码冲突、提高代码组织结构和可读性。本文将深入探讨PHP中命名空间的概念、使用方法以及实际应用场景,帮助读者更好地理解和运用命名空间来优化他们的PHP代码。
|
6天前
thinkphp5.1隐藏index.php入口文件
thinkphp5.1隐藏index.php入口文件
32 0
thinkphp5.1隐藏index.php入口文件
|
6天前
|
PHP 开发者
【专栏】介绍PHP的命名空间,它是一个用于封装代码、避免名称冲突的机制
【4月更文挑战第27天】本文介绍了PHP的命名空间,它是一个用于封装代码、避免名称冲突的机制。命名空间的作用包括:防止大型项目中的命名冲突,提升代码可读性和可维护性,以及方便代码重用。文章详细阐述了如何定义、导入命名空间,使用完全限定名称以及设置命名空间别名。通过实例展示了命名空间在项目模块划分和第三方库如Laravel中的应用,强调了命名空间在组织和管理PHP代码中的关键作用。
|
6天前
|
PHP
利用一段代码轻松绕过PHP授权系统
利用一段代码轻松绕过PHP授权系统
12 0
|
6天前
|
安全 PHP
【PHP开发专栏】PHP文件上传与下载实现
【4月更文挑战第30天】本文介绍了在PHP中实现文件上传和下载的详细步骤。文件上传通过`$_FILES`全局数组处理,包括设置HTML表单、PHP脚本处理上传及安全性考虑。文件下载则可使用`readfile()`、`fpassthru()`或`file_get_contents()`函数,同时关注安全问题,如防止目录遍历漏洞。文中还提供了一个简单的图片分享网站案例,演示了上传和下载功能的集成。
|
6天前
|
安全 PHP 数据库
【PHP开发专栏】PHP文件包含漏洞与防范
【4月更文挑战第30天】本文探讨了PHP文件包含漏洞,该漏洞让攻击者能执行恶意代码或访问敏感信息。文章分为三部分:原理、影响和防范。文件包含函数(如`include`和`require`)在攻击者控制文件名时可能导致漏洞。影响包括执行恶意代码、泄露敏感信息和影响服务器性能。防范措施包括验证文件名安全性、使用安全包含函数、设置安全包含路径和参数,以及定期更新和维护代码及库。开发者应重视此问题,采取相应措施保障应用安全。
|
6天前
|
PHP
php下载MP4视频
php下载MP4视频
15 0