在内存中下载并解压 zip 存档

发布于 2024-12-04 11:05:36 字数 408 浏览 0 评论 0原文

我想下载一个 zip 存档并使用 PHP 将其解压缩到内存中。

这就是我今天所拥有的(对我来说文件处理太多了:)):

// download the data file from the real page
copy("http://www.curriculummagic.com/AdvancedBalloons.kmz", "./data/zip.kmz");

// unzip it
$zip = new ZipArchive;
$res = $zip->open('./data/zip.kmz');
if ($res === TRUE) {
    $zip->extractTo('./data');
    $zip->close();
}

// use the unzipped files...

I would like to download a zip archive and unzip it in memory using PHP.

This is what I have today (and it's just too much file-handling for me :) ):

// download the data file from the real page
copy("http://www.curriculummagic.com/AdvancedBalloons.kmz", "./data/zip.kmz");

// unzip it
$zip = new ZipArchive;
$res = $zip->open('./data/zip.kmz');
if ($res === TRUE) {
    $zip->extractTo('./data');
    $zip->close();
}

// use the unzipped files...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

雪若未夕 2024-12-11 11:05:36

警告:这不能在内存中完成 - ZipArchive 无法使用“内存映射文件”

您可以使用 file_get_contents文档,因为它支持zip:// 流包装器Docs

$zipFile = './data/zip.kmz';     # path of zip-file
$fileInZip = 'test.txt';         # name the file to obtain

# read the file's data:
$path = sprintf('zip://%s#%s', $zipFile, $fileInZip);
$fileData = file_get_contents($path);

您只能使用zip://或通过ZipArchive访问本地文件。为此,您可以首先将内容复制到临时文件并使用它:

$zip = 'http://www.curriculummagic.com/AdvancedBalloons.kmz';
$file = 'doc.kml';

$ext = pathinfo($zip, PATHINFO_EXTENSION);
$temp = tempnam(sys_get_temp_dir(), $ext);
copy($zip, $temp);
$data = file_get_contents("zip://$temp#$file");
unlink($temp);

Warning: This cannot be done in memory — ZipArchive cannot work with "memory mapped files".

You can obtain the data of a file inside a zip-file into a variable (memory) with file_get_contentsDocs as it supports the zip:// Stream wrapper Docs:

$zipFile = './data/zip.kmz';     # path of zip-file
$fileInZip = 'test.txt';         # name the file to obtain

# read the file's data:
$path = sprintf('zip://%s#%s', $zipFile, $fileInZip);
$fileData = file_get_contents($path);

You can only access local files with zip:// or via ZipArchive. For that you can first copy the contents to a temporary file and work with it:

$zip = 'http://www.curriculummagic.com/AdvancedBalloons.kmz';
$file = 'doc.kml';

$ext = pathinfo($zip, PATHINFO_EXTENSION);
$temp = tempnam(sys_get_temp_dir(), $ext);
copy($zip, $temp);
$data = file_get_contents("zip://$temp#$file");
unlink($temp);
最后的乘客 2024-12-11 11:05:36

就像这样简单:

$zipFile = "test.zip";
$fileInsideZip = "somefile.txt";
$content = file_get_contents("zip://$zipFile#$fileInsideZip");

As easy as:

$zipFile = "test.zip";
$fileInsideZip = "somefile.txt";
$content = file_get_contents("zip://$zipFile#$fileInsideZip");
飞烟轻若梦 2024-12-11 11:05:36

老话题但仍然相关,因为我问自己同样的问题,但没有找到答案。

我最终编写了这个函数,它返回一个数组,其中包含存档中包含的每个文件的名称以及该文件的解压缩内容:

function GetZipContent(String $body_containing_zip_file) {

    $sectors = explode("\x50\x4b\x01\x02", $body_containing_zip_file);
    array_pop($sectors);
    $files = explode("\x50\x4b\x03\x04", implode("\x50\x4b\x01\x02", $sectors));
    array_shift($files);

    $result = array();
    foreach($files as $file) {
        $header = unpack("vversion/vflag/vmethod/vmodification_time/vmodification_date/Vcrc/Vcompressed_size/Vuncompressed_size/vfilename_length/vextrafield_length", $file);
        array_push($result, [
            'filename' => substr($file, 26, $header['filename_length']),
            'content' => gzinflate(substr($file, 26 + $header['filename_length'], -12))
        ]);
    }
    
    return $result;
}

Old subject but still relevant since I asked myself the same question, without finding an answer.

I ended up writing this function which returns an array containing the name of each file contained in the archive, as well as the decompressed contents of that file:

function GetZipContent(String $body_containing_zip_file) {

    $sectors = explode("\x50\x4b\x01\x02", $body_containing_zip_file);
    array_pop($sectors);
    $files = explode("\x50\x4b\x03\x04", implode("\x50\x4b\x01\x02", $sectors));
    array_shift($files);

    $result = array();
    foreach($files as $file) {
        $header = unpack("vversion/vflag/vmethod/vmodification_time/vmodification_date/Vcrc/Vcompressed_size/Vuncompressed_size/vfilename_length/vextrafield_length", $file);
        array_push($result, [
            'filename' => substr($file, 26, $header['filename_length']),
            'content' => gzinflate(substr($file, 26 + $header['filename_length'], -12))
        ]);
    }
    
    return $result;
}
晨敛清荷 2024-12-11 11:05:36

您可以获取 zip 内文件的流并将其提取到变量中:

$fp = $zip->getStream('test.txt');
if(!$fp) exit("failed\n");

while (!feof($fp)) {
    $contents .= fread($fp, 1024);
}

fclose($fp);

You can get a stream to a file inside the zip and extract it into a variable:

$fp = $zip->getStream('test.txt');
if(!$fp) exit("failed\n");

while (!feof($fp)) {
    $contents .= fread($fp, 1024);
}

fclose($fp);
另类 2024-12-11 11:05:36

如果您可以使用系统调用,最简单的方法应该如下所示(bzip2 情况)。您只需使用标准输出即可。

$out=shell_exec('bzip2 -dkc '.$zip);

If you can use system calls, the simplest way should look like this (bzip2 case). You just use stdout.

$out=shell_exec('bzip2 -dkc '.$zip);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文