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;
    }


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

目录
相关文章
|
1月前
thinkphp5.1隐藏index.php入口文件
thinkphp5.1隐藏index.php入口文件
30 0
thinkphp5.1隐藏index.php入口文件
|
18天前
|
PHP
php下载MP4视频
php下载MP4视频
9 0
|
1月前
|
PHP 开发者 UED
PHP 中的异常处理:提高代码健壮性的关键
【2月更文挑战第28天】在 PHP 开发中,异常处理是确保应用程序稳定性和可靠性的重要环节。本文将深入探讨 PHP 异常的概念、类型及其处理机制,并通过实例演示如何有效地捕获和处理异常,以增强代码的健壮性和用户体验。
|
3月前
|
PHP 数据安全/隐私保护
php案例:判断这个文件是什么编程语言代码的文件(判断java或者php)
php案例:判断这个文件是什么编程语言代码的文件(判断java或者php)
php案例:判断这个文件是什么编程语言代码的文件(判断java或者php)