예제 #1
0
파일: zipfile.php 프로젝트: rigidus/ea
 function extract($path)
 {
     self::$dir = $path;
     @mkdir(self::$dir);
     self::$datasec = array();
     // File information
     $mtime = filemtime(self::$zip);
     $size = filesize(self::$zip);
     // Read file
     $fh = fopen(self::$zip, "rb");
     $filedata = fread($fh, $size);
     fclose($fh);
     // Break into sections
     $filesecta = explode("PK", $filedata);
     // ZIP Comment
     $unpackeda = unpack('x16/v1length', $filesecta[1]);
     // Cut entries from the central directory
     $filesecta = explode("PK", $filedata);
     $filesecta = explode("PK", $filesecta[0]);
     array_shift($filesecta);
     // Removes empty entry/signature
     foreach ($filesecta as $filedata) {
         // CRC:crc, FD:file date, FT: file time, CM: compression method, GPF: general purpose flag, VN: version needed, CS: compressed size, UCS: uncompressed size, FNL: filename length
         $entrya = array();
         $entrya['error'] = "";
         $unpackeda = unpack("v1version/v1general_purpose/v1compress_method/v1file_time/v1file_date/V1crc/V1size_compressed/V1size_uncompressed/v1filename_length", $filedata);
         // Check for encryption
         $isencrypted = $unpackeda['general_purpose'] & 0x1 ? true : false;
         // Check for value block after compressed data
         if ($unpackeda['general_purpose'] & 0x8) {
             $unpackeda2 = unpack("V1crc/V1size_compressed/V1size_uncompressed", substr($filedata, -12));
             $unpackeda['crc'] = $unpackeda2['crc'];
             $unpackeda['size_compressed'] = $unpackeda2['size_uncompressed'];
             $unpackeda['size_uncompressed'] = $unpackeda2['size_uncompressed'];
             unset($unpackeda2);
         }
         $entrya['name'] = substr($filedata, 26, $unpackeda['filename_length']);
         if (substr($entrya['name'], -1) == "/") {
             continue;
         }
         if (!is_file($entrya['name'])) {
             @mkdir(self::$dir . dirname($entrya['name']));
         }
         $entrya['dir'] = dirname($entrya['name']);
         $entrya['dir'] = $entrya['dir'] == "." ? "" : $entrya['dir'];
         $entrya['name'] = basename($entrya['name']);
         $filedata = substr($filedata, 26 + $unpackeda['filename_length']);
         if (strlen($filedata) != $unpackeda['size_compressed']) {
             $entrya['error'] = "Compressed size is not equal to the value given in header.";
         }
         if ($isencrypted) {
             $entrya['error'] = "Encryption is not supported.";
         } else {
             switch ($unpackeda['compress_method']) {
                 case 0:
                     // Stored
                     // Not compressed, continue
                     break;
                 case 8:
                     // Deflated
                     $filedata = gzinflate($filedata);
                     break;
                 case 12:
                     // BZIP2
                     if (!extension_loaded("bz2")) {
                         @dl(strtolower(substr(PHP_OS, 0, 3)) == "win" ? "php_bz2.dll" : "bz2.so");
                     }
                     if (extension_loaded("bz2")) {
                         $filedata = bzdecompress($filedata);
                     } else {
                         $entrya['error'] = "Required BZIP2 Extension not available.";
                     }
                     break;
                 default:
                     $entrya['error'] = "Compression method ({$unpackeda['compress_method']}) not supported.";
             }
             if (!$entrya['error']) {
                 if ($filedata === false) {
                     $entrya['error'] = true;
                     //"Decompression failed.";
                 } elseif (strlen($filedata) != $unpackeda['size_uncompressed']) {
                     $entrya['error'] = "File size is not equal to the value given in header.";
                 } elseif (crc32($filedata) != $unpackeda['crc']) {
                     $entrya['error'] = "CRC32 checksum is not equal to the value given in header.";
                 }
             }
             $entrya['filemtime'] = mktime(($unpackeda['file_time'] & 0xf800) >> 11, ($unpackeda['file_time'] & 0x7e0) >> 5, ($unpackeda['file_time'] & 0x1f) << 1, ($unpackeda['file_date'] & 0x1e0) >> 5, $unpackeda['file_date'] & 0x1f, (($unpackeda['file_date'] & 0xfe00) >> 9) + 1980);
             $entrya['data'] = $filedata;
         }
         $files[] = $entrya;
     }
     //PrintR($files);
     //exit;
     foreach ($files as $v) {
         if ($v['error'] === true) {
             continue;
         }
         if ($v['dir']) {
             self::createDir($v['dir']);
             $file = self::$dir . $v['dir'] . '/' . $v['name'];
         } else {
             $file = self::$dir . $v['name'];
         }
         $fp = fopen($file, "w");
         fwrite($fp, $v['data']);
         fclose($fp);
     }
     self::$datasec = array();
     self::$ctrl_dir = array();
     self::$zip = '';
     self::$dir = '';
 }