离线文件


需求分析

  • 使用cdn加速下载文件
  • 使用云效下载国外软件然后上传到国内cdn进行下载

软件设计

// 数据初始化
$this->init();

// 下载文件
$this->download();
// 七牛远程离线文件
$this->qiniuOffline();
// 七牛删除文件
$this->qiniuDelete();
// 七牛生成列表页
$this->qiniuList();

编码

$client = new Client();

// 批量异步任务
$fileNames = [];
$promises = [];
foreach ($this->downloadSet as $key => $url) {
    // 通过HEAD取出头部信息
    $response = $client->request('HEAD', $url, ['verify' => false]);
    // 判断是否有指定的文件类型
    if ($response->hasHeader('Content-Type')) {
        $header = current($response->getHeader('Content-Type'));
        $fileType = (new MimeTypes())->getExtensions($header)[0] ?? null;
    }
    // 判断是否有指定的文件名
    if ($response->hasHeader('Content-Disposition')) {
        $header = $response->getHeader('Content-Disposition');
        $header = current(Header::parse($header));
        if (isset($header['filename'])) {
            $filename = $header['filename'];
        }
    }
    $fileNames[$key] = $filename ?? pathinfo($url)['basename'];
    // 获取请求对象的大小
    if ($response->hasHeader('Content-Length')) {
        $length = current($response->getHeader('Content-Length'));
        if (Storage::disk('offline')->exists($fileNames[$key])) {
            $size = Storage::disk('offline')->getSize($fileNames[$key]);
            if ($length == $size) {
                $this->qiniuUpload($fileNames[$key], Storage::disk('offline')->path($fileNames[$key]));
                continue;
            }
        }
    }

    $promises[$key] = $client->getAsync($url, ["sink" => Storage::disk('offline')->path($fileNames[$key])]);
}

// 有一个出错则抛出异常
// $responses = Utils::unwrap($promises);
// 无论是否出错都等待执行完成
$results = Utils::settle($promises)->wait();

// 打印结果
foreach ($promises as $key => $promise) {
    if ($this->debug) {
        $this->qiniuUpload($fileNames[$key], Storage::disk('offline')->path($fileNames[$key]));
        echo $this->downloadSet[$key]."\t";
    }
    $promise->then(
        function (ResponseInterface $res) {
            $this->debug && $this->comment('## 下载完成 => '.$res->getStatusCode());
        },
        function (RequestException $e) {
            $this->debug && $this->error('## 下载失败 => '.$e->getResponse()->getStatusCode());
        }
    );
}