сжатие — php gzcompress создает поврежденный файл .zip

Я должен изменить свой старый php-код, чтобы обновить нашу вики до 1.28.
У меня есть плагин экспорта, который сохраняет выбранные страницы в строки.
эта строка добавляется в zip-файл и сжимается gzcompress.

Я могу скачать файл, но когда я пытаюсь открыть его, он говорит: «Файл поврежден». Если я восстановлю архив с помощью winrar, я получу ожидаемый выходной файл. Как я могу решить, чтобы получить правильный .zipfile в первую очередь

Это может иметь какое-то отношение к старому ZipHelper, который мы используем, но на самом деле я понятия не имею, что там происходит, потому что я довольно новичок в php:

class ZipWriter
{
function __construct()
{
}

var $datasec            = array ();
var $ctrl_dir           = array ();
var $eof_ctrl_dir       = "\x50\x4b\x05\x06\x00\x00\x00\x00";
var $old_offset         = 0;
var $filename           = "";
var $filepointer;
var $writtenSizeCtrlDir = 0;
var $writtenSizeData    = 0;
var $writtenFiles       = 0;
var $completeBuffer;
var $stream             = false;

function addFile($data, $name, $time = 0)
{
$name = str_replace('\\', '/', $name);

$dtime    = dechex($this->unix2DosTime($time));
$hexdtime = '\x' . $dtime[6] . $dtime[7]
. '\x' . $dtime[4] . $dtime[5]
. '\x' . $dtime[2] . $dtime[3]
. '\x' . $dtime[0] . $dtime[1];
eval('$hexdtime = "' . $hexdtime . '";');

$fr = "\x50\x4b\x03\x04";
$fr .= "\x14\x00";            // ver needed to extract
$fr .= "\x00\x00";            // gen purpose bit flag
$fr .= "\x08\x00";            // compression method
$fr .= $hexdtime;             // last mod time and date

// "local file header" segment
$unc_len = strlen($data);
$crc     = crc32($data);
$zdata   = gzcompress($data);
$zdata   = substr(substr($zdata, 0, strlen($zdata) - 4), 2); // fix crc bug

$c_len = strlen($zdata);
$fr .= pack('V', $crc);             // crc32
$fr .= pack('V', $c_len);           // compressed filesize
$fr .= pack('V', $unc_len);         // uncompressed filesize
$fr .= pack('v', strlen($name));    // length of filename
$fr .= pack('v', 0);                // extra field length
$fr .= $name;

// "file data" segment
$fr .= $zdata;

// "data descriptor" segment (optional but necessary if archive is not
// served as file)
$fr .= pack('V', $crc);                 // crc32
$fr .= pack('V', $c_len);               // compressed filesize
$fr .= pack('V', $unc_len);             // uncompressed filesize

if ($this->stream) {
array_push($this->completeBuffer, $fr);
} else {
// write the compressed data to the zipfile
fputs($this->filepointer, $fr);
}

// count up the already written data size
$this->writtenSizeData = $this->writtenSizeData + strlen($fr);

//$new_offset        = strlen(implode('', $this->datasec));
$new_offset = $this->writtenSizeData;

// now add to central directory record
$cdrec = "\x50\x4b\x01\x02";
$cdrec .= "\x00\x00";                // version made by
$cdrec .= "\x14\x00";                // version needed to extract
$cdrec .= "\x00\x00";                // gen purpose bit flag
$cdrec .= "\x08\x00";                // compression method
$cdrec .= $hexdtime;                 // last mod time & date
$cdrec .= pack('V', $crc);           // crc32
$cdrec .= pack('V', $c_len);         // compressed filesize
$cdrec .= pack('V', $unc_len);       // uncompressed filesize
$cdrec .= pack('v', strlen($name)); // length of filename
$cdrec .= pack('v', 0);             // extra field length
$cdrec .= pack('v', 0);             // file comment length
$cdrec .= pack('v', 0);             // disk number start
$cdrec .= pack('v', 0);             // internal file attributes
$cdrec .= pack('V', 32);            // external file attributes - 'archive' bit set

$cdrec .= pack('V', $this->old_offset); // relative offset of local header
$this->old_offset = $new_offset;

$cdrec .= $name;

// save to central directory
$this->ctrl_dir[] = $cdrec;
// count up written files
$this->writtenFiles++;
} // end of the 'addFile()' method

}

0

Решение

Вы путаете разные форматы файлов. РНР gzcompress создает формат zlib, тогда как вы пытаетесь интерпретировать его как файл в формате .zip, а это не так.

Кроме того, названия этих функций в PHP ужасны и вводят в заблуждение, поскольку кто-то может подумать, что gzcompress будет производить формат GZIP. (Что, кстати, тоже не формат zip.) Но нет, gzcompress производит формат zlib Если вы хотите формат GZIP, вам нужно использовать gzencode, Если вам нужен формат raw deflate, тогда вам нужно использовать gzdeflate, Итак, три функции начинаются с gz, но только один производит формат GZIP.

Ни один из них не производит формат почтового индекса. Для этого, как отмечает symcbean, вы должны использовать ZipArchive класс.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]