📄 zip.php
字号:
} else {
$this->set('error.message', 'Unable to open archive');
return false;
}
return true;
}
/**
* Get the list of files/data from a ZIP archive buffer.
*
* @access private
* @param string $data The ZIP archive buffer.
* @return array Archive metadata array
* <pre>
* KEY: Position in zipfile
* VALUES: 'attr' -- File attributes
* 'crc' -- CRC checksum
* 'csize' -- Compressed file size
* 'date' -- File modification time
* 'name' -- Filename
* 'method' -- Compression method
* 'size' -- Original file size
* 'type' -- File type
* </pre>
* @since 1.5
*/
function _getZipInfo(& $data)
{
// Initialize variables
$entries = array ();
// Get details from Central directory structure.
$fhStart = strpos($data, $this->_ctrlDirHeader);
do {
if (strlen($data) < $fhStart +31) {
$this->set('error.message', 'Invalid ZIP data');
return false;
}
$info = unpack('vMethod/VTime/VCRC32/VCompressed/VUncompressed/vLength', substr($data, $fhStart +10, 20));
$name = substr($data, $fhStart +46, $info['Length']);
$entries[$name] = array('attr' => null, 'crc' => sprintf("%08s", dechex($info['CRC32'] )), 'csize' => $info['Compressed'], 'date' => null, '_dataStart' => null, 'name' => $name, 'method' => $this->_methods[$info['Method']], '_method' => $info['Method'], 'size' => $info['Uncompressed'], 'type' => null);
$entries[$name]['date'] = mktime((($info['Time'] >> 11) & 0x1f), (($info['Time'] >> 5) & 0x3f), (($info['Time'] << 1) & 0x3e), (($info['Time'] >> 21) & 0x07), (($info['Time'] >> 16) & 0x1f), ((($info['Time'] >> 25) & 0x7f) + 1980));
if (strlen($data) < $fhStart +43) {
$this->set('error.message', 'Invalid ZIP data');
return false;
}
$info = unpack('vInternal/VExternal', substr($data, $fhStart +36, 6));
$entries[$name]['type'] = ($info['Internal'] & 0x01) ? 'text' : 'binary';
$entries[$name]['attr'] = (($info['External'] & 0x10) ? 'D' : '-') .
(($info['External'] & 0x20) ? 'A' : '-') .
(($info['External'] & 0x03) ? 'S' : '-') .
(($info['External'] & 0x02) ? 'H' : '-') .
(($info['External'] & 0x01) ? 'R' : '-');
} while (($fhStart = strpos($data, $this->_ctrlDirHeader, $fhStart +46)) !== false);
// Get details from local file header.
$fhStart = strpos($data, $this->_fileHeader);
do {
if (strlen($data) < $fhStart +34) {
$this->set('error.message', 'Invalid ZIP data');
return false;
}
$info = unpack('vMethod/VTime/VCRC32/VCompressed/VUncompressed/vLength/vExtraLength', substr($data, $fhStart +8, 25));
$name = substr($data, $fhStart +30, $info['Length']);
$entries[$name]['_dataStart'] = $fhStart +30 + $info['Length'] + $info['ExtraLength'];
} while (strlen($data) > $fhStart +30 + $info['Length'] && ($fhStart = strpos($data, $this->_fileHeader, $fhStart +30 + $info['Length'])) !== false);
$this->_metadata = array_values($entries);
return true;
}
/**
* Returns the file data for a file by offsest in the ZIP archive
*
* @access private
* @param int $key The position of the file in the archive.
* @return string Uncompresed file data buffer
* @since 1.5
*/
function _getFileData($key) {
if ($this->_metadata[$key]['_method'] == 0x8) {
// If zlib extention is loaded use it
if (extension_loaded('zlib')) {
return @ gzinflate(substr($this->_data, $this->_metadata[$key]['_dataStart'], $this->_metadata[$key]['csize']));
}
}
elseif ($this->_metadata[$key]['_method'] == 0x0) {
/* Files that aren't compressed. */
return substr($this->_data, $this->_metadata[$key]['_dataStart'], $this->_metadata[$key]['csize']);
} elseif ($this->_metadata[$key]['_method'] == 0x12) {
// Is bz2 extension loaded? If not try to load it
if (!extension_loaded('bz2')) {
if (JPATH_ISWIN) {
@ dl('php_bz2.dll');
} else {
@ dl('bz2.so');
}
}
// If bz2 extention is sucessfully loaded use it
if (extension_loaded('bz2')) {
return bzdecompress(substr($this->_data, $this->_metadata[$key]['_dataStart'], $this->_metadata[$key]['csize']));
}
}
return '';
}
/**
* Converts a UNIX timestamp to a 4-byte DOS date and time format
* (date in high 2-bytes, time in low 2-bytes allowing magnitude
* comparison).
*
* @access private
* @param int $unixtime The current UNIX timestamp.
* @return int The current date in a 4-byte DOS format.
* @since 1.5
*/
function _unix2DOSTime($unixtime = null) {
$timearray = (is_null($unixtime)) ? getdate() : getdate($unixtime);
if ($timearray['year'] < 1980) {
$timearray['year'] = 1980;
$timearray['mon'] = 1;
$timearray['mday'] = 1;
$timearray['hours'] = 0;
$timearray['minutes'] = 0;
$timearray['seconds'] = 0;
}
return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) | ($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1);
}
/**
* Adds a "file" to the ZIP archive.
*
* @todo Review and finish implementation
*
* @access private
* @param array $file File data array to add
* @param array $contents An array of existing zipped files.
* @param array $ctrldir An array of central directory information.
* @return void
* @since 1.5
*/
function _addToZIPFile(& $file, & $contents, & $ctrldir) {
$data = & $file['data'];
$name = str_replace('\\', '/', $file['name']);
/* See if time/date information has been provided. */
$ftime = null;
if (isset ($file['time'])) {
$ftime = $file['time'];
}
/* Get the hex time. */
$dtime = dechex($this->_unix2DosTime($ftime));
$hexdtime = chr(hexdec($dtime[6] . $dtime[7])) .
chr(hexdec($dtime[4] . $dtime[5])) .
chr(hexdec($dtime[2] . $dtime[3])) .
chr(hexdec($dtime[0] . $dtime[1]));
$fr = $this->_fileHeader; /* Begin creating the ZIP data. */
$fr .= "\x14\x00"; /* Version needed to extract. */
$fr .= "\x00\x00"; /* General purpose bit flag. */
$fr .= "\x08\x00"; /* Compression method. */
$fr .= $hexdtime; /* Last modification time/date. */
/* "Local file header" segment. */
$unc_len = strlen($data);
$crc = crc32($data);
$zdata = gzcompress($data);
$zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2);
$c_len = strlen($zdata);
$fr .= pack('V', $crc); /* CRC 32 information. */
$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 name. */
/* "File data" segment. */
$fr .= $zdata;
/* Add this entry to array. */
$old_offset = strlen(implode('', $contents));
$contents[] = & $fr;
/* Add to central directory record. */
$cdrec = $this->_ctrlDirHeader;
$cdrec .= "\x00\x00"; /* Version made by. */
$cdrec .= "\x14\x00"; /* Version needed to extract */
$cdrec .= "\x00\x00"; /* General purpose bit flag */
$cdrec .= "\x08\x00"; /* Compression method */
$cdrec .= $hexdtime; /* Last mod time/date. */
$cdrec .= pack('V', $crc); /* CRC 32 information. */
$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', $old_offset); /* Relative offset of local
header. */
$cdrec .= $name; /* File name. */
/* Optional extra field, file comment goes here. */
// Save to central directory array. */
$ctrldir[] = & $cdrec;
}
/**
* Creates the ZIP file.
* Official ZIP file format: http://www.pkware.com/appnote.txt
*
* @todo Review and finish implementation
*
* @access private
* @param array $contents An array of existing zipped files.
* @param array $ctrldir An array of central directory information.
* @param string $path The path to store the archive.
* @return boolean True if successful
* @since 1.5
*/
function _createZIPFile(& $contents, & $ctrlDir, $path)
{
$data = implode('', $contents);
$dir = implode('', $ctrlDir);
$buffer = $data . $dir . $this->_ctrlDirEnd .
/* Total # of entries "on this disk". */
pack('v', count($ctrlDir)) .
/* Total # of entries overall. */
pack('v', count($ctrlDir)) .
/* Size of central directory. */
pack('V', strlen($dir)) .
/* Offset to start of central dir. */
pack('V', strlen($data)) .
/* ZIP file comment length. */
"\x00\x00";
if (JFile::write($path, $buffer) === false) {
return false;
} else {
return true;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -