php实现文件编码批量转换


Posted in PHP onMarch 10, 2014

有些问题,不能重复转,比如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 {
}
PHP 相关文章推荐
PHP 和 MySQL 基础教程(二)
Oct 09 PHP
PHP 最大运行时间 max_execution_time修改方法
Mar 08 PHP
phpMyAdmin 链接表的附加功能尚未激活的问题
Aug 01 PHP
php array_intersect比array_diff快(附详细的使用说明)
Jul 03 PHP
php中的curl使用入门教程和常见用法实例
Apr 10 PHP
CI框架学习笔记(一) - 环境安装、基本术语和框架流程
Oct 26 PHP
php简单定时执行任务的实现方法
Feb 23 PHP
php冒泡排序与快速排序实例详解
Dec 07 PHP
PHP Callable强制指定回调类型的方法
Aug 30 PHP
yii2 上传图片的示例代码
Nov 02 PHP
php设计模式之观察者模式定义与用法经典示例
Sep 19 PHP
Laravel 框架控制器 Controller原理与用法实例分析
Apr 14 PHP
php导出word文档与excel电子表格的简单示例代码
Mar 08 #PHP
php 创建以UNIX时间戳命名的文件夹(示例代码)
Mar 08 #PHP
PHP_Cooikes不同页面无法传递的解决方法
Mar 07 #PHP
php function用法如何递归及return和echo区别
Mar 07 #PHP
详解PHP中strlen和mb_strlen函数的区别
Mar 07 #PHP
解决Codeigniter不能上传rar和zip压缩包问题
Mar 07 #PHP
php 生成自动创建文件夹并上传文件的示例代码
Mar 07 #PHP
You might like
推荐25款php中非常有用的类库
2014/09/29 PHP
PHP中执行cmd命令的方法
2014/10/11 PHP
ThinkPHP中__initialize()和类的构造函数__construct()用法分析
2014/11/29 PHP
php实现的单一入口应用程序实例分析
2015/09/23 PHP
PHP序列化操作方法分析
2016/09/28 PHP
php提交表单时保留多个空格及换行的文本样式的方法
2017/06/20 PHP
PHP如何解决微信文章图片防盗链
2020/12/09 PHP
JS BASE64编码 window.atob(), window.btoa()
2021/03/09 Javascript
如何使用jquery动态加载js,css文件实现代码
2013/04/03 Javascript
javascript浏览器兼容教程之事件处理
2014/06/09 Javascript
JavaScript中变量声明有var和没var的区别示例介绍
2014/09/15 Javascript
js中匿名函数的创建与调用方法分析
2014/12/19 Javascript
jQuery团购倒计时特效实现方法
2015/05/07 Javascript
一款简单的jQuery图片标注效果附源码下载
2016/03/22 Javascript
JS导出PDF插件的方法(支持中文、图片使用路径)
2016/07/12 Javascript
jQuery实现的简单百分比进度条效果示例
2016/08/01 Javascript
JavaScript数据结构之链表的实现
2017/03/19 Javascript
js实现简易聊天对话框
2017/08/17 Javascript
vue计算属性及使用详解
2018/04/02 Javascript
了解重排与重绘
2019/05/29 Javascript
linux系统使用python监测网络接口获取网络的输入输出
2014/01/15 Python
Python中Continue语句的用法的举例详解
2015/05/14 Python
pycharm中连接mysql数据库的步骤详解
2017/05/02 Python
基于Python闭包及其作用域详解
2017/08/28 Python
Python编程产生非均匀随机数的几种方法代码分享
2017/12/13 Python
python 使用socket传输图片视频等文件的实现方式
2019/08/07 Python
python中文分词库jieba使用方法详解
2020/02/11 Python
python 制作网站小说下载器
2021/02/20 Python
HTML5 canvas基本绘图之绘制矩形
2016/06/27 HTML / CSS
Pretty Little Thing美国:时尚女性服饰
2018/08/27 全球购物
请描述一下”is a”关系和”has a”关系
2015/02/03 面试题
旷课检讨书大全
2014/01/21 职场文书
求职信名称怎么写
2014/05/26 职场文书
学校推普周活动总结
2015/05/07 职场文书
2016年小学党支部创先争优活动总结
2016/04/05 职场文书
使用HttpSessionListener监听器实战
2022/03/17 Java/Android