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检测useragent版本示例
Mar 24 PHP
php实现singleton()单例模式实例
Nov 06 PHP
javascript some()函数用法详解
Nov 13 PHP
php实现RSA加密类实例
Mar 26 PHP
PHP嵌套输出缓冲代码实例
May 12 PHP
在Mac OS上自行编译安装Apache服务器和PHP解释器
Dec 24 PHP
php实现微信企业号支付个人的方法详解
Jul 26 PHP
PHP实现负载均衡下的session共用功能
Apr 17 PHP
Laravel5框架添加自定义辅助函数的方法
Aug 01 PHP
PHP支付宝当面付2.0代码
Dec 21 PHP
thinkphp5实现无限级分类
Feb 18 PHP
PHP批斗大会之缺失的异常详解
Jul 09 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 Session变量不能传送到下一页的解决方法
2009/11/27 PHP
php实现可以设置中奖概率的抽奖程序代码分享
2014/01/19 PHP
php上传大文件失败的原因及应对策略
2015/10/20 PHP
php+jQuery实现的三级导航栏下拉菜单显示效果
2017/08/10 PHP
javascript中的undefined 与 null 的区别  补充篇
2010/03/17 Javascript
可以用来调试JavaScript错误的解决方案
2010/08/07 Javascript
JavaScript语言核心数据类型和变量使用介绍
2013/08/23 Javascript
最好用的省市二级联动 原生js实现你值得拥有
2013/09/22 Javascript
js将当前时间格式转换成时间搓(自写)
2013/09/26 Javascript
Jquery中ajax方法data参数的用法小结
2014/02/12 Javascript
JavaScript字符串对象split方法入门实例(用于把字符串分割成数组)
2014/10/16 Javascript
js获取字符串最后一位方法汇总
2014/11/13 Javascript
Jquery实现由下向上展开效果的例子
2014/12/08 Javascript
javascript带回调函数的异步脚本载入方法实例分析
2015/07/02 Javascript
jQuery控制DIV层实现由大到小,由远及近动画变化效果
2015/10/09 Javascript
JS+CSS实现的竖向简洁折叠菜单效果代码
2015/10/22 Javascript
Javascript数组Array基础介绍
2016/03/13 Javascript
vue的diff算法知识点总结
2018/03/29 Javascript
JS数组方法join()用法实例分析
2020/01/18 Javascript
vue3.0自定义指令(drectives)知识点总结
2020/12/27 Vue.js
[59:48]DOTA2-DPC中国联赛 正赛 VG vs Magma BO3 第一场 1月26日
2021/03/11 DOTA
Python3.2中的字符串函数学习总结
2015/04/23 Python
Python实现嵌套列表去重方法示例
2017/12/28 Python
python素数筛选法浅析
2018/03/19 Python
pytorch训练imagenet分类的方法
2018/07/27 Python
Django框架创建项目的方法入门教程
2019/11/04 Python
用python求一重积分和二重积分的例子
2019/12/06 Python
pymysql模块的操作实例
2019/12/17 Python
css3实现3D色子翻转特效
2014/12/23 HTML / CSS
俄罗斯电子产品、计算机和家用电器购物网站:OLDI
2019/10/27 全球购物
年度献血先进个人事迹材料
2014/02/14 职场文书
节水倡议书范文
2014/04/15 职场文书
学生自我鉴定格式及范文
2014/09/16 职场文书
停电调休通知
2015/04/16 职场文书
MySQL去除密码登录告警的方法
2022/04/20 MySQL
python playwright之元素定位示例详解
2022/07/23 Python