在 Laravel 6 中基于 ZipStream PHP ,将 zip 文件流式传输到 S3 存储桶

1、当在请求 S3 存储桶时,遇到了限流问题:Please reduce your request rate,进而导致请求失败。如图1

图1

2、最终实现代码如下

$name = $themeId . '/assets.zip';

$zip = new ZipStream($name);

$zip->addFile('apps/internal/back-top/assets/app.9ce8af2.js', '0000000000000');

$res = Storage::disk(config('theme_asset.filesystem.disk'))->put(
 $name,
 $zip->finish(),
 config('theme_asset.filesystem.options')
);

3、在浏览器中打开 S3 对应的 CDN 地址:https://xxx.cloudfastin.com/static/xxx/98cb73f9-e61a-40b1-a27a-3beb99015e5e/assets.zip 。文件可下载,确认文件上传至 S3 成功。如图2

图2

3、将下载后的文件解压缩,失败,提示:该文件为非压缩文件,无法打开。如图3

图3

4、使用 putStream 方法,且设置 ZipStream 对象的选项中,输出流。下载后,解压缩成功。如图4

图4

$name = $themeId . '/assets.zip';

$tmp = tempnam(sys_get_temp_dir(), 'zip_stream');
$stream = fopen($tmp, 'w+');

$options = new Archive();
//$options->setContentType('application/x-zip-compressed');
$options->setOutputStream($stream);
$zip = new ZipStream($name, $options);

$zip = new ZipStream($name);

$zip->addFile('apps/internal/back-top/assets/app.9ce8af2.js', '0000000000000');

$zip->finish();

$res = Storage::disk(config('theme_asset.filesystem.disk'))->putStream(
 $name,
 $stream,
 config('theme_asset.filesystem.options')
);


fclose($stream);

5、但是,如果路径中包含反斜杠,例,路径为:css\app.6156ec.css 的文件,其路径已经变化为:css_app.6156ec.css。如图5

图5

6、需要将 路径为:css\app.6156ec.css 的文件,替换为:css/app.6156ec.css。上传至 S3,下载后解压缩,目录结构正常。如图6

图6

$zip->addFile(str_replace('\\', '/', 'css\\app.6156ec.css'), $file->getContents());
永夜