一、写在开始
在上一篇博客中写了一个先压缩后分片下载的demo,但是存在一定的缺点,本篇介绍的是先分片然后放入压缩包最后再分片下载
二、具体代码
public function downloads() { $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'; //压缩包路径 if ($zip->open($zip_name, \ZipArchive::CREATE) !== true) { exit("压缩包文件创建失败!"); } $chunk_size = 1024 * 1024; // 分片大小,这里设置为1MB foreach ($arr as $file) { $path_url = '.' . $file; //获取到的文件路径是从/uploads开始的 $handle = fopen($path_url, 'rb'); //打开该文件 if ($handle === false) { exit('打开文件失败'); } // fseek($handle , 0); // 分片读取文件 while (!feof($handle)) { $test = fread($handle, $chunk_size); if ($test === false) { exit('读取失败'); } $zip->addFile($path_url, basename($path_url)); //向压缩包中添加文件 // flush(); // ob_flush(); } fclose($handle); //关闭文件 } $zip->close(); //关闭压缩包 // var_dump($zip_name);exit; header('Content-Type: application/zip'); header('Content-Disposition: attachment; filename="' . 'ya.zip"'); header('Accept-Ranges: bytes'); header('Content-Length:'. filesize($zip_name)); // readfile($zip_name); $length = filesize($zip_name); try { // 打开文件,并获取文件大小 $fp = fopen($zip_name, 'rb'); if ($fp === false) exit("文件打开失败"); // 直接输出文件内容到浏览器 while (!feof($fp)) { echo fread($fp, 8192); } } finally { // 关闭文件 if ($fp !== false) fclose($fp); // 删除临时目录和文件 // array_map('unlink', glob($temp_dir . '/*')); // rmdir($temp_dir); exit; } }