龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > web编程 > php编程 >

批量或者单个转换文件编码

时间:2014-07-22 14:48来源: 作者: 点击:
分享到:
转换文件编码,比如原来是gbk,转换成utf-8的,可以转单个文件也可以转换整个目录的文件,可选是否递归目录。有些问题,不能重复转,比如gbk转到utf8,然后有在转成utf8,这样会乱码,
转换文件编码,比如原来是gbk,转换成utf-8的,可以转单个文件也可以转换整个目录的文件,可选是否递归目录。
有些问题,不能重复转,比如gbk转到utf8,然后有在转成utf8,这样会乱码,我本来试图在转换之前去检测编码的,貌似失败了。我特意试了一个文件,我检测它是是否是gbk或者是utf-8,都返回true。这就不懂了。
<?php
/**
 * 转换文件编码
 * 依赖的扩展filesystem 和 mbstring
 * @example
 * <pre>
 * include_once 'ConvertEncode.php';
 * $convert = new ConvertEncode();
 * try{
 *	  $convert->setPath('my', true, true);//目录
 *    //$convert->setPath('my.php');//单文件
 *	  $convert->setEncode('GBK', 'UTF-8');
 *	  $convert->convert();
 * }catch(ConvertException $e) {
 *	  echo $e->getMessage();
 * }
 * </pre>
 */
class ConvertEncode {
	
	/**
	 * 要转换成的编码
	 * @var string
	 */
	private $_to_encoding;
	
	/**
	 * 转换前的编码
	 * @var string
	 */
	private $_from_encoding;
	
	/**
	 * 要转换的的目录或者单文件
	 * @var string
	 */
	private $_path;
	
	/**
	 * 是否是一个目录,当给出的是目录是才设置
	 * @var boolean
	 */
	private $_directory;
	
	/**
	 * 是否递归遍历,仅对目录有效
	 * @var boolean
	 */
	private $_recursion;
	
	/**
	 * 保存所有待转换的文件,仅当转换目录里面的文件时才用
	 * @var array
	 */
	private $_files = array();
	
	/**
	 * 构造函数
	 */
	public function __construct() {
		if( ! function_exists('mb_convert_encoding') ) {
			throw new ConvertException('mbstring extension be required');
		}
	}
	
	/**
	 * 设置需要转换的目录或者单文件
	 * @param string $path 目录或者文件
	 * @param boolean 是否是目录
	 * @param boolean 是否递归目录
	 * @return boolean
	 */
	public function setPath($path, $is_dir = false, $rec = false) {
		$this->_path = $path;
		$this->_directory = $is_dir;
		$this->_recursion = $rec;
		return true;
	}
	
	/**
	 * 设置转换前的编码和要转换到的编码
	 * @param string $encode 转换前的编码
	 * @param string $encode 转换到的编码
	 * @return boolean
	 */
	public function setEncode($encode_from, $encode_to) {
		$this->_from_encoding = $encode_from;
		$this->_to_encoding   = $encode_to;
		return true;
	}
	
	/**
	 * 转换编码,根据是否是目录的设置分别转换
	 * @return boolean
	 */
	public function convert() {
		if($this->_directory ) {
			return $this->_convertDirectory();
		}
		return $this->_convertFile();
	}
	
	/**
	 * 转换文件
	 * @throws ConvertException
	 * @return boolean
	 */
	private function _convertFile() {
		if( ! file_exists($this->_path) ) {
			$message = $this->_path . ' does not exist.';
			throw new ConvertException($message);
		}
		if( ! is_file($this->_path) ) {
			$message = $this->_path . ' is not a file.';
			throw new ConvertException($message);
		}
		if( ! $this->_isWR() ) {
			$message = $this->_path . ' must can be read and write.';
			throw new ConvertException($message);
		}
		$file_real_path    = realpath($this->_path);
		$file_content_from = file_get_contents( $file_real_path );
		if( mb_check_encoding($file_content_from, $this->_from_encoding) ) {
			$file_content_to   = mb_convert_encoding( $file_content_from, $this->_to_encoding, $this->_from_encoding );
			file_put_contents( $file_real_path, $file_content_to );
		}
		return true;
		
	}
	
	/**
	 * 转换目录
	 * @throws ConvertException
	 * @return boolean
	 */
	private function _convertDirectory() {
		if( ! file_exists($this->_path) ) {
			$message = $this->_path . ' does not exist.';
			throw new ConvertException($message);
		}
		if( ! is_dir($this->_path) ) {
			$message = $this->_path . ' is not a directory.';
			throw new ConvertException($message);
		}
		if( ! $this->_isWR() ) {
			$message = $this->_path . ' must can be read and write.';
			throw new ConvertException($message);
		}
		$this->_scanDirFiles();
		if( empty($this->_files) ) {
			$message = $this->_path . ' is a empty directory.';
			throw new ConvertException($message);
		}
		foreach( $this->_files as $value ) {
			$file_content_from = file_get_contents( $value );
			if( mb_check_encoding($file_content_from, $this->_from_encoding) ) {
				$file_content_to   = mb_convert_encoding( $file_content_from, $this->_to_encoding, $this->_from_encoding );
				file_put_contents( $value, $file_content_to );
			}
		}
		return true;
	}
	
	/**
	 * 判断文件或者目录是否可读写
	 * @return boolean 可读写时返回true,否则返回false
	 */
	private function _isWR() {
		if( is_readable($this->_path) && is_writable($this->_path) ) {
			return true;
		}
		return false;
	}
	
	/**
	 * 遍历目录,找出所有文件,加上绝对路径
	 * @return boolean
	 */
	private function _scanDirFiles($dir = '') {
		$base_path = empty( $dir ) ? realpath($this->_path) . DIRECTORY_SEPARATOR : realpath($dir) . DIRECTORY_SEPARATOR;
		$files_tmp = empty( $dir ) ? scandir($this->_path) : scandir($dir);
		foreach( $files_tmp as $value ) {
			if( $value == '.' || $value == '..' || ( strpos($value, '.') === 0 ) ) {
				continue;
			}
			$value = $base_path . $value;
			if( is_dir($value) ) {
				if( $this->_recursion ) {
					$this->_scanDirFiles($value);
				}
			}
			elseif( is_file($value) ) {
				$this->_files[] = $value;
			}
		}
		return true;
	}
}

/**
 * 转换异常
 *
 */
class ConvertException extends Exception {
	
}
精彩图集

赞助商链接