Laravel 从七牛云空间多文件压缩打包下载

Laravel框架
449
0
0
2022-12-01
Laravel 从七牛云空间多文件压缩(mkzip)打包下载(大量文件压缩 mode=4)

首先得安装七牛云

composer require itbdw/laravel-storage-qiniu

业务代码(仅供参考)

<?php

namespace App\Http\Controllers\Common;

use Qiniu\Auth;
use zgldh\QiniuStorage\QiniuStorage;
use Qiniu\Processing\PersistentFop;
use Illuminate\Support\Str;
use function Qiniu\base64_urlSafeEncode;
use function Qiniu\entry;

class QiniuCompressionController
{
    private string $accessKey;
    private string $secretKey;
    private string $bucket;
    private string $pipeline;
    private string $domain;

    public function __construct()
    {
        $this->accessKey = env('accessKey');
        $this->secretKey = env('secretKey');
        $this->bucket    = env('bucket');
        $this->pipeline  = env('pipeline'); //智能多媒体服务队列 
        $this->domain    = env('domain'); //七牛云配置域名
    }

    public function multiFileCompression(array $source_array, string $package_name, string $callback_url = null)
    {
        //初始化 
        $auth = new Auth($this->accessKey, $this->secretKey);

        $disk = QiniuStorage::disk('qiniu');

        $file_name = md5(time() . Str::random(6)).'.txt'; // 文件名

        foreach ($source_array as $source) {
            $str = '';
            $Base64EncodedURL = base64_urlSafeEncode($source['key']);
            $Base64AliasEncodedURL = base64_urlSafeEncode($source['alias']);
            $str .= '/url/'.$Base64EncodedURL;
            if(!empty($source['alias'])){
                $str .= '/alias/'.$Base64AliasEncodedURL;
            }
            // 将数据保存到本地文件中 
            file_put_contents($file_name, $str.PHP_EOL, FILE_APPEND);
        }

        $file_content = file_get_contents($file_name);

        $dir = 'zips'; // 保存到指定七牛云空间的文件夹路径(按照自己的空间路径设置即可) 
        $key = $dir . '/' . $file_name; // 文件路径 
        $bool = $disk->put($key,$file_content); //上传该文件到七牛云

        // 判断是否上传成功 
        if ($bool) {
            $fops = 'mkzip/4/|saveas/'.entry($this->bucket,$dir . '/' . $package_name);

            $pfop = new PersistentFop($auth, null);
            // 压缩打包文件 【参数 pipeline 非必填,但还是建议去配置一个https://portal.qiniu.com/dora/media-gate/pipeline】 
            list($id, $err)  = $pfop->execute($this->bucket,$key,$fops,$this->pipeline,$callback_url,false);

            if(is_null($err)){
                //轮询队列执行完成后才返回 
                while(true){
                    $url = "https://api.qiniu.com/status/get/prefop?id=" . $id;
                    $json = file_get_contents($url);
                    $arr = json_decode($json, true);
                    if($arr['code'] == 0 ){
                        break;
                    }else if($arr['code'] == 3 || $arr['code'] == 4){
                        return ['code'=>500,'msg'=>'操作失败'];
                    }
                }

                //移除本地临时文件 
                unlink($file_name);
                //移除七牛云临时文件 
                $disk->delete($key);

                return [
                    'code'=>200,
                    'download_url' => 'https://' . $this->domain . '/' . $dir . '/' . $package_name, //下载地址
                ];
            }else{
                return ['code'=>500,'msg'=>'操作失败'];
            }
            exit;
        } else{
            return ['code'=>500,'msg'=>'操作失败'];
        }
    }

    public function do()
    {
        //简单示例 
        $source_array = [
            [
                'key' => 'http://xxxxxxxxxxxxxxx.jpg',  // 七牛云文件路径 
                'alias' => 'a.jpg',                     // 设置别名(也可以不设置)
            ],[
                'key' => 'http://yyyyyyyyyyyyyyy.jpg',
                'alias' => 'b.jpg',
            ],
        ];

        //压缩包名 
        $package_name = date('YmdHis') . '-' .Str::random(6) . '.zip';

        $data = $this->multiFileCompression($source_array,$package_name);

        //触发网页下载 
        if($data['code'] == 200){
            $response = response()->streamDownload(function () use($data){
                echo file_get_contents($data['download_url']);
            },$package_name,[
                'Content-Type: application/octet-stream',
                'Content-Disposition: attachment; filename="'.$package_name.'"',
                'Content-Transfer-Encoding: binary'
            ]);

            return $response;
        }
    }
}
希望各位大佬多多指点! 感谢!