php实现文件编码批量转换

php实现文件编码批量转换

转换文件编码,比如原来是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 {

}