2017-02-02 9 views
0

Ich muss einen alten PHP-Code umgestalten, um unser Wiki auf 1.28 zu aktualisieren. Ich habe ein Export-Plugin, das ausgewählte Seiten in Strings speichert. Diese Zeichenfolgen wurden zu einer Zip-Datei hinzugefügt und von gzcompress komprimiert.php gzcompress erzeugt eine beschädigte .zip-Datei

Ich kann die Datei herunterladen, aber wenn ich versuche, es zu öffnen, sagt es "Datei ist beschädigt". Wenn ich das Archiv mit winrar repariere, bekomme ich die erwartete Ausgabedatei. Wie kann ich lösen, um die richtige .zipfile an erster Stelle zu bekommen

Es mag etwas mit dem alten ZipHelper zu tun haben, den wir verwenden, aber ich habe eigentlich keine Ahnung, was dort passiert, weil ich ziemlich neu bin 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 

} 

Antwort

1

Sie verwirren verschiedene Dateiformate. PHP gzcompress erzeugt das ZLIB-Format, während Sie versuchen, es als eine Datei im ZIP-Format zu interpretieren, was es nicht ist.

Nebenbei sind die Namen dieser Funktionen in PHP schrecklich und irreführend, da jemand denken könnte, dass gzcompress das gzip-Format erzeugen würde. (Was übrigens ist auch nicht das Zip-Format.) Aber nein, gzcompress produziert das zlib-Format. Wenn Sie das gzip-Format verwenden möchten, müssen Sie gzencode verwenden. Wenn Sie das Raw Deflate-Format verwenden möchten, müssen Sie gzdeflate verwenden. Zwei der Funktionen beginnen also mit gz, aber nur einer erzeugt das gzip-Format.

Keine von denen produzieren das Zip-Format. Dazu würden Sie, wie von symcbean angemerkt, die ZipArchive class verwenden.

+0

Aus Gründen der Vollständigkeit .... PHP unterstützt ZIP-Dateien mit der ZIP-Erweiterung: http://php.net/manual/en/book.zip.php – symcbean

Verwandte Themen