archive_tar.php

来自「国外免费开源的内容管理系统」· PHP 代码 · 共 1,665 行 · 第 1/4 页

PHP
1,665
字号
<?php
/* vim: set ts=4 sw=4: */
// +----------------------------------------------------------------------+
// | PHP Version 4														|
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group								|
// +----------------------------------------------------------------------+
// | This source file is subject to version 3.0 of the PHP license,		|
// | that is bundled with this package in the file LICENSE, and is		|
// | available through the world-wide-web at the following url:			|
// | http://www.php.net/license/3_0.txt.								  |
// | If you did not receive a copy of the PHP license and are unable to	|
// | obtain it through the world-wide-web, please send a note to		  |
// | license@php.net so we can mail you a copy immediately.				|
// +----------------------------------------------------------------------+
// | Author: Vincent Blavet <vincent@blavet.net>						  |
// +----------------------------------------------------------------------+
//
// $Id: Tar.php 6474 2007-02-03 10:47:26Z pasamio $

// Check to ensure this file is within the rest of the frameworkdefined('JPATH_BASE') or die();
jimport('pear.PEAR');

define ('ARCHIVE_TAR_ATT_SEPARATOR', 90001);

/**
* Creates a (compressed) Tar archive
*
* @author	Vincent Blavet <vincent@blavet.net>
* @version  $Revision: 47 $
* @package  Archive
*/
class Archive_Tar extends PEAR
{
	/**
	* @var string Name of the Tar
	*/
	var $_tarname='';

	/**
	* @var boolean if true, the Tar file will be gzipped
	*/
	var $_compress=false;

	/**
	* @var string Type of compression : 'none', 'gz' or 'bz2'
	*/
	var $_compress_type='none';

	/**
	* @var string Explode separator
	*/
	var $_separator=' ';

	/**
	* @var file descriptor
	*/
	var $_file=0;

	/**
	* @var string Local Tar name of a remote Tar (http:// or ftp://)
	*/
	var $_temp_tarname='';

	// {{{ constructor
	/**
	* Archive_Tar Class constructor. This flavour of the constructor only
	* declare a new Archive_Tar object, identifying it by the name of the
	* tar file.
	* If the compress argument is set the tar will be read or created as a
	* gzip or bz2 compressed TAR file.
	*
	* @param	string  $p_tarname  The name of the tar archive to create
	* @param	string  $p_compress can be null, 'gz' or 'bz2'. This
	*					parameter indicates if gzip or bz2 compression
	*					is required.  For compatibility reason the
	*					boolean value 'true' means 'gz'.
	* @access public
	*/
	function Archive_Tar($p_tarname, $p_compress = null)
	{
		$this->PEAR();
		$this->_compress = false;
		$this->_compress_type = 'none';
		if ($p_compress === null) {
			if (@file_exists($p_tarname)) {
				if ($fp = @fopen($p_tarname, "rb")) {
					// look for gzip magic cookie
					$data = fread($fp, 2);
					fclose($fp);
					if ($data == "\37\213") {
						$this->_compress = true;
						$this->_compress_type = 'gz';
					// No sure it's enought for a magic code ....
					} elseif ($data == "BZ") {
						$this->_compress = true;
						$this->_compress_type = 'bz2';
					}
				}
			} else {
				// probably a remote file or some file accessible
				// through a stream interface
				if (substr($p_tarname, -2) == 'gz') {
					$this->_compress = true;
					$this->_compress_type = 'gz';
				} elseif ((substr($p_tarname, -3) == 'bz2') ||
						  (substr($p_tarname, -2) == 'bz')) {
					$this->_compress = true;
					$this->_compress_type = 'bz2';
				}
			}
		} else {
			if (($p_compress === true) || ($p_compress == 'gz')) {
				$this->_compress = true;
				$this->_compress_type = 'gz';
			} else if ($p_compress == 'bz2') {
				$this->_compress = true;
				$this->_compress_type = 'bz2';
			}
		}
		$this->_tarname = $p_tarname;
		if ($this->_compress) { // assert zlib or bz2 extension support
			if ($this->_compress_type == 'gz')
				$extname = 'zlib';
			else if ($this->_compress_type == 'bz2')
				$extname = 'bz2';

			if (!extension_loaded($extname)) {
				PEAR::loadExtension($extname);
			}
			if (!extension_loaded($extname)) {
				die("The extension '$extname' couldn't be found.\n".
					"Please make sure your version of PHP was built ".
					"with '$extname' support.\n");
				return false;
			}
		}
	}
	// }}}

	// {{{ destructor
	function _Archive_Tar()
	{
		$this->_close();
		// ----- Look for a local copy to delete
		if ($this->_temp_tarname != '')
			@unlink($this->_temp_tarname);
		$this->_PEAR();
	}
	// }}}

	// {{{ create()
	/**
	* This method creates the archive file and add the files / directories
	* that are listed in $p_filelist.
	* If a file with the same name exist and is writable, it is replaced
	* by the new tar.
	* The method return false and a PEAR error text.
	* The $p_filelist parameter can be an array of string, each string
	* representing a filename or a directory name with their path if
	* needed. It can also be a single string with names separated by a
	* single blank.
	* For each directory added in the archive, the files and
	* sub-directories are also added.
	* See also createModify() method for more details.
	*
	* @param array  $p_filelist An array of filenames and directory names, or a single
	*							string with names separated by a single blank space.
	* @return					true on success, false on error.
	* @see createModify()
	* @access public
	*/
	function create($p_filelist)
	{
		return $this->createModify($p_filelist, '', '');
	}
	// }}}

	// {{{ add()
	/**
	* This method add the files / directories that are listed in $p_filelist in
	* the archive. If the archive does not exist it is created.
	* The method return false and a PEAR error text.
	* The files and directories listed are only added at the end of the archive,
	* even if a file with the same name is already archived.
	* See also createModify() method for more details.
	*
	* @param array  $p_filelist An array of filenames and directory names, or a single
	*							string with names separated by a single blank space.
	* @return					true on success, false on error.
	* @see createModify()
	* @access public
	*/
	function add($p_filelist)
	{
		return $this->addModify($p_filelist, '', '');
	}
	// }}}

	// {{{ extract()
	function extract($p_path='')
	{
		return $this->extractModify($p_path, '');
	}
	// }}}

	// {{{ listContent()
	function listContent()
	{
		$v_list_detail = array();

		if ($this->_openRead()) {
			if (!$this->_extractList('', $v_list_detail, "list", '', '')) {
				unset($v_list_detail);
				$v_list_detail = 0;
			}
			$this->_close();
		}

		return $v_list_detail;
	}
	// }}}

	// {{{ createModify()
	/**
	* This method creates the archive file and add the files / directories
	* that are listed in $p_filelist.
	* If the file already exists and is writable, it is replaced by the
	* new tar. It is a create and not an add. If the file exists and is
	* read-only or is a directory it is not replaced. The method return
	* false and a PEAR error text.
	* The $p_filelist parameter can be an array of string, each string
	* representing a filename or a directory name with their path if
	* needed. It can also be a single string with names separated by a
	* single blank.
	* The path indicated in $p_remove_dir will be removed from the
	* memorized path of each file / directory listed when this path
	* exists. By default nothing is removed (empty path '')
	* The path indicated in $p_add_dir will be added at the beginning of
	* the memorized path of each file / directory listed. However it can
	* be set to empty ''. The adding of a path is done after the removing
	* of path.
	* The path add/remove ability enables the user to prepare an archive
	* for extraction in a different path than the origin files are.
	* See also addModify() method for file adding properties.
	*
	* @param array  $p_filelist	 An array of filenames and directory names, or a single
	*								string with names separated by a single blank space.
	* @param string $p_add_dir	  A string which contains a path to be added to the
	*								memorized path of each element in the list.
	* @param string $p_remove_dir	A string which contains a path to be removed from
	*								the memorized path of each element in the list, when
	*								relevant.
	* @return boolean				true on success, false on error.
	* @access public
	* @see addModify()
	*/
	function createModify($p_filelist, $p_add_dir, $p_remove_dir='')
	{
		$v_result = true;

		if (!$this->_openWrite())
			return false;

		if ($p_filelist != '') {
			if (is_array($p_filelist))
				$v_list = $p_filelist;
			elseif (is_string($p_filelist))
				$v_list = explode($this->_separator, $p_filelist);
			else {
				$this->_cleanFile();
				$this->_error('Invalid file list');
				return false;
			}

			$v_result = $this->_addList($v_list, $p_add_dir, $p_remove_dir);
		}

		if ($v_result) {
			$this->_writeFooter();
			$this->_close();
		} else
			$this->_cleanFile();

		return $v_result;
	}
	// }}}

	// {{{ addModify()
	/**
	* This method add the files / directories listed in $p_filelist at the
	* end of the existing archive. If the archive does not yet exists it
	* is created.
	* The $p_filelist parameter can be an array of string, each string
	* representing a filename or a directory name with their path if
	* needed. It can also be a single string with names separated by a
	* single blank.
	* The path indicated in $p_remove_dir will be removed from the
	* memorized path of each file / directory listed when this path
	* exists. By default nothing is removed (empty path '')
	* The path indicated in $p_add_dir will be added at the beginning of
	* the memorized path of each file / directory listed. However it can
	* be set to empty ''. The adding of a path is done after the removing
	* of path.
	* The path add/remove ability enables the user to prepare an archive
	* for extraction in a different path than the origin files are.
	* If a file/dir is already in the archive it will only be added at the
	* end of the archive. There is no update of the existing archived
	* file/dir. However while extracting the archive, the last file will
	* replace the first one. This results in a none optimization of the
	* archive size.
	* If a file/dir does not exist the file/dir is ignored. However an
	* error text is send to PEAR error.
	* If a file/dir is not readable the file/dir is ignored. However an
	* error text is send to PEAR error.
	*
	* @param array	  $p_filelist	 An array of filenames and directory names, or a single
	*									string with names separated by a single blank space.
	* @param string	 $p_add_dir	  A string which contains a path to be added to the
	*									memorized path of each element in the list.
	* @param string	 $p_remove_dir	A string which contains a path to be removed from
	*									the memorized path of each element in the list, when
	*									relevant.
	* @return							true on success, false on error.
	* @access public
	*/
	function addModify($p_filelist, $p_add_dir, $p_remove_dir='')
	{
		$v_result = true;

		if (!@is_file($this->_tarname))
			$v_result = $this->createModify($p_filelist, $p_add_dir, $p_remove_dir);
		else {
			if (is_array($p_filelist))
				$v_list = $p_filelist;
			elseif (is_string($p_filelist))
				$v_list = explode($this->_separator, $p_filelist);
			else {
				$this->_error('Invalid file list');
				return false;
			}

			$v_result = $this->_append($v_list, $p_add_dir, $p_remove_dir);
		}

		return $v_result;
	}
	// }}}

	// {{{ addString()
	/**
	* This method add a single string as a file at the
	* end of the existing archive. If the archive does not yet exists it
	* is created.
	*
	* @param string	 $p_filename	 A string which contains the full filename path
	*									that will be associated with the string.
	* @param string	 $p_string		The content of the file added in the archive.
	* @return							true on success, false on error.
	* @access public
	*/
	function addString($p_filename, $p_string)
	{
		$v_result = true;

		if (!@is_file($this->_tarname)) {
			if (!$this->_openWrite()) {
				return false;
			}
			$this->_close();
		}

		if (!$this->_openAppend())
			return false;

		// Need to check the get back to the temporary file ? ....
		$v_result = $this->_addString($p_filename, $p_string);

		$this->_writeFooter();

		$this->_close();

		return $v_result;
	}
	// }}}

	// {{{ extractModify()
	/**
	* This method extract all the content of the archive in the directory
	* indicated by $p_path. When relevant the memorized path of the
	* files/dir can be modified by removing the $p_remove_path path at the
	* beginning of the file/dir path.
	* While extracting a file, if the directory path does not exists it is
	* created.
	* While extracting a file, if the file already exists it is replaced
	* without looking for last modification date.
	* While extracting a file, if the file already exists and is write
	* protected, the extraction is aborted.
	* While extracting a file, if a directory with the same name already
	* exists, the extraction is aborted.
	* While extracting a directory, if a file with the same name already
	* exists, the extraction is aborted.
	* While extracting a file/directory if the destination directory exist
	* and is write protected, or does not exist but can not be created,
	* the extraction is aborted.
	* If after extraction an extracted file does not show the correct
	* stored file size, the extraction is aborted.
	* When the extraction is aborted, a PEAR error text is set and false
	* is returned. However the result can be a partial extraction that may
	* need to be manually cleaned.
	*
	* @param string $p_path		 The path of the directory where the files/dir need to by
	*								extracted.
	* @param string $p_remove_path  Part of the memorized path that can be removed if
	*								present at the beginning of the file/dir path.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?