📄 class.em_unzip.php
字号:
<?php/**************************************************************** Copyright notice** (c) Vincent Blavet <vincent@phpconcept.net>* (c) 2005-2006 Karsten Dambekalns <karsten@typo3.org>* All rights reserved** This library is free software; you can redistribute it and/or* modify it under the terms of the GNU Lesser General Public* License as published by the Free Software Foundation; either* version 2.1 of the License, or (at your option) any later version.** This library is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU* Lesser General Public License for more details.** You should have received a copy of the GNU Lesser General Public* License along with this library; if not, write to the Free Software* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,* MA 02110-1301 USA** This copyright notice MUST APPEAR in all copies of the script!***************************************************************//** * Module: Extension manager * * $Id: class.em_unzip.php 1869 2006-12-12 11:57:52Z k-fish $ * * @author Vincent Blavet <vincent@phpconcept.net> * @author Karsten Dambekalns <karsten@typo3.org> */// Constantsdefine( 'ARCHIVE_ZIP_READ_BLOCK_SIZE', 2048 );// File list separatordefine( 'ARCHIVE_ZIP_SEPARATOR', ',' );define( 'ARCHIVE_ZIP_TEMPORARY_DIR', '' );// Error codesdefine( 'ARCHIVE_ZIP_ERR_NO_ERROR', 0 );define( 'ARCHIVE_ZIP_ERR_WRITE_OPEN_FAIL', -1 );define( 'ARCHIVE_ZIP_ERR_READ_OPEN_FAIL', -2 );define( 'ARCHIVE_ZIP_ERR_INVALID_PARAMETER', -3 );define( 'ARCHIVE_ZIP_ERR_MISSING_FILE', -4 );define( 'ARCHIVE_ZIP_ERR_FILENAME_TOO_LONG', -5 );define( 'ARCHIVE_ZIP_ERR_INVALID_ZIP', -6 );define( 'ARCHIVE_ZIP_ERR_BAD_EXTRACTED_FILE', -7 );define( 'ARCHIVE_ZIP_ERR_DIR_CREATE_FAIL', -8 );define( 'ARCHIVE_ZIP_ERR_BAD_EXTENSION', -9 );define( 'ARCHIVE_ZIP_ERR_BAD_FORMAT', -10 );define( 'ARCHIVE_ZIP_ERR_DELETE_FILE_FAIL', -11 );define( 'ARCHIVE_ZIP_ERR_RENAME_FILE_FAIL', -12 );define( 'ARCHIVE_ZIP_ERR_BAD_CHECKSUM', -13 );define( 'ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );define( 'ARCHIVE_ZIP_ERR_MISSING_OPTION_VALUE', -15 );define( 'ARCHIVE_ZIP_ERR_INVALID_PARAM_VALUE', -16 );// Warning codesdefine( 'ARCHIVE_ZIP_WARN_NO_WARNING', 0 );define( 'ARCHIVE_ZIP_WARN_FILE_EXIST', 1 );// Methods parametersdefine( 'ARCHIVE_ZIP_PARAM_PATH', 'path' );define( 'ARCHIVE_ZIP_PARAM_ADD_PATH', 'add_path' );define( 'ARCHIVE_ZIP_PARAM_REMOVE_PATH', 'remove_path' );define( 'ARCHIVE_ZIP_PARAM_REMOVE_ALL_PATH', 'remove_all_path' );define( 'ARCHIVE_ZIP_PARAM_SET_CHMOD', 'set_chmod' );define( 'ARCHIVE_ZIP_PARAM_EXTRACT_AS_STRING', 'extract_as_string' );define( 'ARCHIVE_ZIP_PARAM_NO_COMPRESSION', 'no_compression' );define( 'ARCHIVE_ZIP_PARAM_PRE_EXTRACT', 'callback_pre_extract' );define( 'ARCHIVE_ZIP_PARAM_POST_EXTRACT', 'callback_post_extract' );define( 'ARCHIVE_ZIP_PARAM_PRE_ADD', 'callback_pre_add' );define( 'ARCHIVE_ZIP_PARAM_POST_ADD', 'callback_post_add' );/*** Class for unpacking zip archive files** @author Vincent Blavet <vincent@blavet.net>* @author Karsten Dambekalns <karsten@typo3.org>*/class em_unzip { /** * The filename of the zip archive. * * @var string Name of the Zip file */ var $_zipname=''; /** * File descriptor of the opened Zip file. * * @var int Internal zip file descriptor */ var $_zip_fd=0; /** * @var int last error code */ var $_error_code=1; /** * @var string Last error description */ var $_error_string=''; /** * em_unzip Class constructor. This flavour of the constructor only * declare a new em_unzip object, identifying it by the name of the * zip file. * * @param string $p_zipname The name of the zip archive to create * @access public */ function em_unzip($p_zipname) { // Check the zlib if (!extension_loaded('zlib')) { die("The extension 'zlib' couldn't be found.\n". "Please make sure your version of PHP was built ". "with 'zlib' support.\n"); } // Set the attributes $this->_zipname = $p_zipname; $this->_zip_fd = 0; return; } /** * This method extract the files and folders which are in the zip archive. * It can extract all the archive or a part of the archive by using filter * feature (extract by name, by index, by ereg, by preg). The extraction * can occur in the current path or an other path. * All the advanced features are activated by the use of variable * parameters. * The return value is an array of entry descriptions which gives * information on extracted files (See listContent()). * The method may return a success value (an array) even if some files * are not correctly extracted (see the file status in listContent()). * The supported variable parameters for this method are : * 'add_path' : Path where the files and directories are to be extracted * * @access public * @param mixed $p_params An array of variable parameters and values. * @return mixed An array of file description on success, * 0 on an unrecoverable failure, an error code is logged. */ function extract($p_params=0) { $this->_errorReset(); // Check archive if (!$this->_checkFormat()) { return(0); } // Set default values if ($p_params === 0) { $p_params = array(); } if ($this->_check_parameters($p_params, array ('extract_as_string' => false, 'add_path' => '', 'remove_path' => '', 'remove_all_path' => false, 'callback_pre_extract' => '', 'callback_post_extract' => '', 'set_chmod' => 0) ) != 1) { return 0; } // Call the extracting fct $v_list = array(); if ($this->_extractByRule($v_list, $p_params) != 1) { unset($v_list); return(0); } return $v_list; } /** * Method that gives the lastest error code. * * @access public * @return integer The error code value. */ function errorCode() { return($this->_error_code); } /** * This method gives the latest error code name. * * @access public * @param boolean $p_with_code If true, gives the name and the int value. * @return string The error name. */ function errorName($p_with_code=false) { $v_const_list = get_defined_constants(); // Extract error constants from all const. for (reset($v_const_list); list($v_key, $v_value) = each($v_const_list);) { if (substr($v_key, 0, strlen('ARCHIVE_ZIP_ERR_')) =='ARCHIVE_ZIP_ERR_') { $v_error_list[$v_key] = $v_value; } } // Search the name form the code value $v_key=array_search($this->_error_code, $v_error_list, true); if ($v_key!=false) { $v_value = $v_key; } else { $v_value = 'NoName'; } if ($p_with_code) { return($v_value.' ('.$this->_error_code.')'); } else { return($v_value); } } /** * This method returns the description associated with the latest error. * * @access public * @param boolean $p_full If set to true gives the description with the * error code, the name and the description. * If set to false gives only the description * and the error code. * @return string The error description. */ function errorInfo($p_full=false) { if ($p_full) { return($this->errorName(true)." : ".$this->_error_string); } else { return($this->_error_string." [code ".$this->_error_code."]"); } } /** * em_unzip::_checkFormat() * * { Description } * * @param integer $p_level */ function _checkFormat($p_level=0) { $v_result = true; // Reset the error handler $this->_errorReset(); // Look if the file exits if (!is_file($this->_zipname)) { // Error log $this->_errorLog(ARCHIVE_ZIP_ERR_MISSING_FILE, "Missing archive file '".$this->_zipname."'"); return(false); } // Check that the file is readeable if (!is_readable($this->_zipname)) { // Error log $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->_zipname."'"); return(false); } // Check the magic code // TBC // Check the central header // TBC // Check each file header // TBC // Return return $v_result; } /** * em_unzip::_openFd() * * { Description } * */ function _openFd($p_mode) { $v_result=1; // Look if already open if ($this->_zip_fd != 0) { $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->_zipname.'\' already open'); return em_unzip::errorCode(); } // Open the zip file if (($this->_zip_fd = @fopen($this->_zipname, $p_mode)) == 0) { $this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->_zipname .'\' in '.$p_mode.' mode'); return em_unzip::errorCode(); } // Return return $v_result; } /** * em_unzip::_closeFd() * * { Description } * */ function _closeFd() { $v_result=1; if ($this->_zip_fd != 0) @fclose($this->_zip_fd); $this->_zip_fd = 0; // Return return $v_result; } /** * em_unzip::_convertHeader2FileInfo() * * { Description } * */ function _convertHeader2FileInfo($p_header, &$p_info) { $v_result=1; // Get the interesting attributes $p_info['filename'] = $p_header['filename']; $p_info['stored_filename'] = $p_header['stored_filename']; $p_info['size'] = $p_header['size']; $p_info['compressed_size'] = $p_header['compressed_size']; $p_info['mtime'] = $p_header['mtime']; $p_info['comment'] = $p_header['comment']; $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010); $p_info['index'] = $p_header['index']; $p_info['status'] = $p_header['status']; // Return return $v_result; } // Function : _extractByRule() // Description : // Extract a file or directory depending of rules (by index, by name, ...) // Parameters : // $p_file_list : An array where will be placed the properties of each // extracted file // $p_path : Path to add while writing the extracted files // $p_remove_path : Path to remove (from the file memorized path) while writing the // extracted files. If the path does not match the file path, // the file is extracted with its memorized path. // $p_remove_path does not apply to 'list' mode. // $p_path and $p_remove_path are commulative. // Return Values : // 1 on success,0 or less on error (see error code list) /** * em_unzip::_extractByRule() * * { Description } * */ function _extractByRule(&$p_file_list, &$p_params) { $v_result=1; $p_path = $p_params['add_path']; $p_remove_path = $p_params['remove_path']; $p_remove_all_path = $p_params['remove_all_path']; // Check the path if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../") && (substr($p_path,1,2)!=":/"))) $p_path = "./".$p_path; // Reduce the path last (and duplicated) '/' if (($p_path != "./") && ($p_path != "/")) { // Look for the path end '/' while (substr($p_path, -1) == "/") { $p_path = substr($p_path, 0, strlen($p_path)-1); } } // Open the zip file if (($v_result = $this->_openFd('rb')) != 1) { return $v_result; } // Read the central directory informations $v_central_dir = array(); if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1) { // Close the zip file $this->_closeFd(); return $v_result; } // Start at beginning of Central Dir $v_pos_entry = $v_central_dir['offset']; // Read each entry $j_start = 0; for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) { // Read next Central dir entry @rewind($this->_zip_fd); if (@fseek($this->_zip_fd, $v_pos_entry)) { $this->_closeFd(); $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); return em_unzip::errorCode(); } // Read the file header $v_header = array(); if (($v_result = $this->_readCentralFileHeader($v_header)) != 1) { $this->_closeFd(); return $v_result; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -