从ZIP字符串中提取文件

tra*_*lad 20 php

我有一个包含一个XML文件的zip文件的BASE64字符串.

关于如何在不必处理磁盘上的文件的情况下获取XML文件内容的任何想法?

我非常希望将整个过程保留在内存中,因为XML只有1-5k.

必须编写zip,提取XML然后加载它并删除所有内容会很烦人.

Hen*_*ash 16

经过几个小时的研究后,我认为不可能在没有临时文件的情况下处理zip:

  1. 第一次尝试php://memory将无法正常工作,因为它是一个无法通过file_get_contents()或等功能读取的流ZipArchive::open().在评论中是一个链接到php-bugtracker缺乏这个问题的文档.
  2. 有一个流支持ZipArchive::getStream()而是按照手册中的规定,它仅支持一个打开的文件读取操作.因此,您无法即时构建存档.
  3. zip://包装也只读:创建fopen()函数包装ZIP文件
  4. 我也尝试过其他php包装器/协议

     file_get_contents("zip://data://text/plain;base64,{$base64_string}#test.txt")
     $zip->open("php://filter/read=convert.base64-decode/resource={$base64_string}")
     $zip->open("php://filter/read=/resource=php://memory")
    
    Run Code Online (Sandbox Code Playgroud)

    但对我来说,他们根本不工作,即使手册中有这样的例子.所以你必须吞下药丸并创建一个临时文件.


原答案:

这只是临时存储的方式.我希望你自己管理xml的zip处理和解析.

使用php php://memory(doc)包装器.请注意,这仅对小文件有用,因为它存储在内存中 - 显然.否则请php://temp改用.

<?php

// the decoded content of your zip file
$text = 'base64 _decoded_ zip content';

// this will empty the memory and appen your zip content
$written = file_put_contents('php://memory', $text);

// bytes written to memory
var_dump($written);

// new instance of the ZipArchive
$zip = new ZipArchive;

// success of the archive reading
var_dump(true === $zip->open('php://memory'));
Run Code Online (Sandbox Code Playgroud)

  • 是的,抱歉 - 在这种情况下我的代码是错误的.file_put_contents()方法不适用于i/o流:https://bugs.php.net/bug.php?id = 50886&edit = 2.所以你必须使用`fopen()`,`fwrite()`和`stream_get_contents()`来写/读到`php:// memory` (2认同)

tos*_*-cx 14

我有类似的问题,我最终手动完成了.
https://www.pkware.com/documents/casestudies/APPNOTE.TXT

这会提取单个文件(只是第一个),没有错误/ crc检查,假设使用了deflate.

// zip in a string
$data = file_get_contents('test.zip');

// magic
$head = unpack("Vsig/vver/vflag/vmeth/vmodt/vmodd/Vcrc/Vcsize/Vsize/vnamelen/vexlen", substr($data,0,30));
$filename = substr($data,30,$head['namelen']);
$raw = gzinflate(substr($data,30+$head['namelen']+$head['exlen'],$head['csize']));

// first file uncompressed and ready to use
file_put_contents($filename,$raw);
Run Code Online (Sandbox Code Playgroud)