后端代码
php
// 批量下载并压缩
public function downloadAll(){
$ids = input('ids');
$row = $this->model->where('id', 'in', $ids)->field('id,title,video_url')->select();
if (!$row) {
$this->error('记录不存在');
}
$arr = [];
$tempFiles = []; // 用来存储临时下载的视频文件路径
// 打包视频文件的 ZIP 文件名
$zipname = '视频文件[' . str_replace(',', '_', $ids) . ']' . date('YmdHis') . '.zip';
// 初始化 ZIP 压缩包
$zip = new \ZipArchive();
if ($zip->open($zipname, \ZIPARCHIVE::CREATE) !== TRUE) {
$this->error('无法创建压缩包');
}
foreach ($row as $item) {
// 假设视频链接存储在数据库中的 'video_url' 字段
$videoUrl = $item['video_url']; // 远程视频的 URL
$fileName = basename($videoUrl); // 获取文件名
// 直接通过 HTTP 流式读取远程文件并将其写入到 ZIP 中
if ($this->addRemoteFileToZip($zip, $videoUrl, $fileName)) {
$arr[] = $fileName; // 添加到数组
}
}
if (empty($arr)) {
$this->error('没有可下载的视频文件');
}
// 关闭 ZIP 文件
$zip->close();
// 发送到浏览器
\fast\Http::sendToBrowser($zipname);
}
/**
* 将远程文件流式读取并添加到 ZIP 压缩包
* @param ZipArchive $zip ZipArchive 对象
* @param string $url 远程文件 URL
* @param string $fileName 压缩包中的文件名
* @return bool 是否成功
*/
private function addRemoteFileToZip($zip, $url, $fileName) {
// 打开远程文件的 URL 进行流式读取
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 允许 URL 重定向
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // 设置超时时间
$fileContent = curl_exec($ch);
if (curl_errno($ch)) {
curl_close($ch);
return false; // 下载失败
}
// 获取文件内容并关闭 cURL
curl_close($ch);
// 将内容添加到 ZIP 文件
if ($fileContent !== false) {
$zip->addFromString($fileName, $fileContent); // 使用文件名和内容添加到 ZIP 中
return true;
}
return false;
}
前端js代码
javascript
//批量下载
$(document).on("click", ".btn-download", function () {
var selectedrow = table.bootstrapTable('getSelections');
if(selectedrow.length<1){
Toastr.error('未选择任何记录,不能下载!');
return;
}
var ids = [];
for(var i=0;i<selectedrow.length;i++){
ids[i] = selectedrow[i].id;// 遍历选择记录
}
location.href='/admin/downloadAll?ids='+ids.join(',')
});