2017-02-02 4 views
0

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

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

Возможно, это связано с тем, что мы используем старый 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 

} 

ответ

1

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

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

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

+0

В интересах полноты .... PHP поддерживает ZIP-файлы с расширением ZIP: http://php.net/manual/en/book.zip.php – symcbean

Смежные вопросы