实现原理:通过oss接口下载文件至服务器相关目录,然后进行压缩为一个zip文件,接口调用返回文件流或浏览器访问直接下载文件,下载完成后删除相关目录。
一、ThinkPHP版本6.1
二、PHP版本:8.0
三、逻辑示例代码(根据应用场景更改,主要更改数据来源)
- /**
- * @notes 下载赛事作品
- * @return Json
- */
- public function downloadWork(): Json
- {
- try {
- // 设置作品下载或保存目录
- $loaclPath = public_path() . '/zip';
- // 目录不存在则进行创建
- if (!is_dir($loaclPath)) mkdir($loaclPath, 0777, true);
- // OSS数据内容,不包含bucket名称
- $list = ['1.png','2.png'];
- // 定义本地图片数组
- $img = [];
- foreach ($list as $k => $v) {
- // 获取oss文件地址,不包含bucket名称
- $object = str_replace('http://myykj-w.oss-cn-hangzhou.aliyuncs.com/', '', $val['down_load_url']);
- $filename = '/' . $key . '_文件';
- // 文件后缀
- $ext = substr($object, stripos($object, '.'));
- // 设置文件全名
- $fullPath = $loaclPath . $filename . $ext;
- $img[] = $fullPath;
- // 调用oss下载文件
- OssLogic::aliossDownload($object, $fullPath);
- }
-
- //这里需要注意该目录是否存在,并且有创建的权限
- $fileName = public_path() . '/image.zip';
- $zip = new \ZipArchive();
- $res = $zip->open($fileName, \ZipArchive::CREATE);
- if ($res === TRUE) {
- foreach ($img as $file) {
- //这里直接用原文件的名字进行打包,也可以直接命名,需要注意如果文件名字一样会导致后面文件覆盖前面的文件,所以建议重新命名
- $new_filename = substr($file, strrpos($file, '/') + 1);
- $zip->addFile($file, $new_filename);
- }
- }
- //关闭文件
- $zip->close();
- // 定义下载至本地的文件名称
- $downLoadName = '文件.zip';
- // 这里是下载zip文件
- header("Content-Type: application/zip");
- header("Content-Transfer-Encoding: Binary");
- header("Content-Length: " . filesize($fileName));
- header("Content-Disposition: attachment; filename=\"" . $downLoadName . "\"");
- readfile($fileName);
- unlink($fileName); // 删除压缩包
- deleteDirectory($loaclPath); // 删除文件目录及文件
- exit;
- } catch (\Exception $e) {
- return $this->fail($e->getMessage());
- }
- }
四、oss下载示例代码(参数需要改为自己oss参数)
- /**
- * @notes oss下载
- * @return bool
- */
- public static function aliossDownload($object, $localfile): bool
- {
- // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
- $accessKeyId = config('AccessKeyId');
- $accessKeySecret = config('AccessKeySecret');
- // Endpoint以杭州为例,其它Region请按实际情况填写。
- $endpoint = config('Endpoint');
- // 设置存储空间名称。
- $bucket = config('Bucket');
- //下载地址
- $options = array(
- OssClient::OSS_FILE_DOWNLOAD => $localfile
- );
-
- // 使用try catch捕获异常。如果捕获到异常,则说明下载失败;如果没有捕获到异常,则说明下载成功。
- try {
- $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
-
- $ossClient->getObject($bucket, $object, $options);
- return true;
- } catch (OssException $e) {
- printf(__FUNCTION__ . ": FAILED\n");
- printf($e->getMessage() . "\n");
- return false;
- }
- }
五、删除目录示例代码
- /**
- * @notes 递归删除文件夹
- * @return true
- */
- function deleteDirectory($dir): bool
- {
- if (!is_dir($dir)) {
- return false;
- }
- $files = array_diff(scandir($dir), array('.', '..'));
- foreach ($files as $file) {
- (is_dir("$dir/$file")) ? deleteDirectory("$dir/$file") : unlink("$dir/$file");
- }
- return rmdir($dir);
- }