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一些有意思的小区别
Dec 06 PHP
简化php模板页面中分页代码的解析
Feb 06 PHP
php 静态化实现代码
Mar 20 PHP
利用Memcached在php下实现session机制 替换PHP的原生session支持
Aug 21 PHP
比较简单实用的PHP无限分类源码分享(思路不错)
Oct 13 PHP
ecshop实现smtp发送邮件
Feb 03 PHP
PHP实现的简单mock json脚本分享
Feb 10 PHP
在win系统安装配置 Memcached for PHP 5.3 图文教程
Mar 03 PHP
再推荐十款免费的php开发工具
Nov 09 PHP
浅谈PHP中try{}catch{}的使用方法
Dec 09 PHP
Laravel实现通过blade模板引擎渲染视图
Oct 25 PHP
如何用PHP实现分布算法之一致性哈希算法
May 26 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
PHP+Mysql无刷新问答评论系统(源码)
2016/12/20 PHP
JavaScript的单例模式 (singleton in Javascript)
2010/06/11 Javascript
Google AJAX 搜索 API实现代码
2010/11/17 Javascript
再论Javascript的类继承
2011/03/05 Javascript
jquery.Jwin.js 基于jquery的弹出层插件代码
2012/05/23 Javascript
javascript 禁用IE工具栏,导航栏等等实现代码
2013/04/01 Javascript
深入理解JavaScript高级之词法作用域和作用域链
2013/12/10 Javascript
使用 js+正则表达式为关键词添加链接
2014/11/11 Javascript
node.js中的forEach()是同步还是异步呢
2015/01/29 Javascript
javascript实现rgb颜色转换成16进制格式
2015/07/10 Javascript
如何解决hover在ie6中的兼容性问题
2016/12/15 Javascript
swiper在vue项目中loop循环轮播失效的解决方法
2018/09/15 Javascript
脚手架vue-cli工程webpack的作用和特点
2018/09/29 Javascript
vue+elementUI实现表单和图片上传及验证功能示例
2019/05/14 Javascript
Vue中的transition封装组件的实现方法
2019/08/13 Javascript
JS实现排行榜文字向上滚动轮播效果
2019/11/26 Javascript
利用Python实现命令行版的火车票查看器
2016/08/05 Python
Pandas中把dataframe转成array的方法
2018/04/13 Python
Python测试线程应用程序过程解析
2019/12/31 Python
Pycharm连接远程服务器过程图解
2020/04/30 Python
python os.listdir()乱码解决方案
2021/01/31 Python
html5 更新图片颜色示例代码
2014/07/29 HTML / CSS
购买大码女装:Lane Bryant
2016/09/07 全球购物
美体小铺法国官方网站:The Body Shop法国
2020/06/04 全球购物
日期和时间问题
2015/01/04 面试题
大学生求职工作的自我评价
2014/02/13 职场文书
幼儿园家长评语大全
2014/04/16 职场文书
大学学生会竞选演讲稿
2014/04/25 职场文书
项目投资建议书
2014/05/16 职场文书
民间个人借款协议书
2014/09/30 职场文书
党的群众路线对照检查材料思想汇报(学校)
2014/10/04 职场文书
公司承诺函范文
2015/01/21 职场文书
收入证明申请书
2015/06/12 职场文书
《实心球》教学反思
2016/02/23 职场文书
Mybatis-Plus进阶分页与乐观锁插件及通用枚举和多数据源详解
2022/03/21 Java/Android
腾讯云服务器部署前后分离项目之前端部署
2022/06/28 Servers