首页 >> 大全

PHP ZipArchive 大文件分片下载压缩 支持断点续传

2023-12-08 大全 22 作者:考证青年

删除临时文件和目录:

源码


class File extends Backend
{/*** @description: 压缩下载* @param {*} $params['uid']:用户ID,用于查询数据库中的文件列表。* @param {*} $temp_dir:临时目录路径。* @param {*} $username:用户名。* @param {*} $zip_name:压缩文件名。* @param {*} $chunkSize:每次读取文件的大小。* @param {*} $range:请求头中的 HTTP_RANGE 值。* @param {*} $startPos:传输文件的起始位置。* @param {*} $files:用户的文件列表。* @param {*} $file_path:文件路径。* @param {*} $fp:文件资源。* @param {*} $chunk:每次读取的文件内容的缓冲区。* @param {*} $contentLength:压缩文件* @return {*}*/public function export(){// TODO 1.创建一个临时目录,并检查是否已存在。如果不存在,则创建该目录$temp_dir = './temp/' . '-' . uniqid();if (!is_dir($temp_dir))  mkdir($temp_dir, 0777, true);// TODO 2.创建一个 ZipArchive 对象,并指定压缩文件名。$zip = new \ZipArchive();$zip_name = $temp_dir . '/' . $username . '.zip';if ($zip->open($zip_name, \ZipArchive::CREATE) !== true) exit("文件创建失败!");// TODO 3.定义文件分块传输的相关参数$chunkSize = 1024 * 1024 * 1;  // 定义文件分块传输的相关参数。$range = isset($_SERVER['HTTP_RANGE']) ? $_SERVER['HTTP_RANGE'] : '';   //  获取请求头中的 HTTP_RANGE 值,如果请求头中不存在 HTTP_RANGE 值,则将其设为空字符串// TODO 4.定义传输文件的起始位置$startPos = 0;// preg_match(),用于执行正则表达式的匹配操作。它接受一个正则表达式模式和一个要搜索的字符串作为参数,并尝试在字符串中找到与模式匹配的部分。如果匹配成功,则返回 1,否则返回 0。if (preg_match('/bytes=(\d+)/', $range, $matches))  $startPos = intval($matches[1]);   //  如果请求头中的 HTTP_RANGE 值匹配了 bytes=(\d+) 的正则表达式,则将该值的整数部分赋值给 $startPos 变量。// TODO 5.遍历文件列表foreach ($files as $file) {$file_path = '.' . $file['file_url'];   //构建文件路径,添加文件路径前缀 '.' 并取出 $file['file_url'] 值。$fp = fopen($file_path, 'rb');  // 打开文件,并将资源赋值给 $fp 变量。if ($fp === false) exit("文件打开失败: $file_path");fseek($fp, $startPos);  //设置文件指针位置为起始位置 $startPos(0)// TODO 6.通过文件路径打开文件,读取文件内容,并将每次读取的数据添加到压缩文件中。while (!feof($fp)) {  // 判断文件是否读完$chunk = fread($fp, $chunkSize);  // 从文件中读取指定大小的内容,成功读取内容时返回读取的数据,将文件读入内存if ($chunk === false) exit("文件读取失败: $file_path");$zip->addFile($file_path, basename($file_path));  // 将文件内容添加到压缩文件中,使用 basename($file_path) 作为文件在压缩文件中的名称。成功添加文件时返回 true// $zip->addFile($file_path, basename($file_path));  //  addFile 函数会一次性将整个文件加载到内存中,然后添加到 ZIP 压缩文件中。// $zip->addFromString(basename($file_path), $chunk);  // 将文件的每个数据块逐个添加到 ZIP 压缩文件中。}fclose($fp);  // 关闭文件}// TODO 7.关闭压缩文件,并设置响应头信息,包括文件类型、文件名和文件大小。$zip->close();header('Content-Type: application/zip');  //设置响应头信息为 ZIP 文件类型header('Content-Disposition: attachment; filename="' . $username . '_all.zip"');  // 这里对客户端的弹出对话框, 设置响应头中的文件名为 $XXX_all.zipheader('Content-Length: ' . filesize($zip_name));  // 设置响应头中的文件大小为压缩文件的大小$contentLength = filesize($zip_name);  //获取压缩文件的大小,返回值是文件的大小(字节数)// TODO 8.如果请求头中存在 HTTP_RANGE 值,则进行分块传输if ($range != '') {// TODO 9.首先对请求头中的 HTTP_RANGE 进行处理,获取起始位置和结束位置$range = preg_replace('/[\s|,].*/', '', $range);  //preg_replace() 用于执行正则表达式的替换操作。它接受一个正则表达式模式、一个替换字符串和一个要进行替换的字符串作为参数,并尝试在字符串中找到与模式匹配的部分并进行替换$ranges = explode('-', $range);$startPos = intval($ranges[0]);$endPos = $contentLength - 1;if (isset($ranges[1]) && is_numeric($ranges[1]) && $ranges[1] < $endPos) {$endPos = intval($ranges[1]);}header('HTTP/1.1 206 Partial Content');  //设置响应头状态为 206 Partial Content,表示只返回部分内容header("Content-Range: bytes $startPos-$endPos/$contentLength");   // 设置响应头中的 Content-Range,指定返回的内容范围$fp = fopen($zip_name, 'rb');  //打开压缩文件fseek($fp, $startPos); //设置文件指针位置为起始位置fpassthru($fp); // 直接将文件内容发送给浏览器进行下载或输出ob_flush(); // 刷新输出缓冲区,将内容发送到浏览器fclose($fp);  //关闭文件} else {readfile($zip_name);  //直接输出响应}// TODO 10.删除临时文件和目录// array_map('unlink', glob($temp_dir . '/*'))的作用是先使用glob函数获取指定目录下的所有文件路径(使用通配符*获取目录下所有文件的路径)并返回一个数组,然后使用array_map函数将unlink函数应用到该数组的每个元素上,即删除对应的文件。//  array_map('unlink', glob($temp_dir . '/*'));unlink($zip_name);rmdir($temp_dir);exit;}

_压缩文件中断_分段压缩包解压

PHP 操作方法 fopen( file,'rb'): (要关闭的文件资源) feof(要检测的文件资源) fread(文件资源,要读取的字节数) fseek(文件资源,偏移量,偏移起始位置) (要传输的文件资源) (要获取大小的文件名) () flush() (要输出的文件名) (要提取文件名的路径) (正则表达式模式,要搜索的字符串) (前缀,更改器) 请求头 ('HTTP/1.1 206 '): ("-Range: bytes): ('-Type: /zip'): ('-: ; ="' . $ . '_all.zip"'): ('-: ' . ($)): 方法:

参考文章:(98条消息) PHP扩展类实现压缩解压Zip文件和文件打包下载_php 解压缩文件的博客-CSDN博客

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了