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解答方法
Feb 04 PHP
php实现与erlang的二进制通讯实例解析
Jul 23 PHP
php网站被挂木马后的修复方法总结
Nov 06 PHP
ThinkPHP中I(),U(),$this-&gt;post()等函数用法
Nov 22 PHP
PHP简单实现数字分页功能示例
Aug 24 PHP
php遍历替换目录下文件指定内容的方法
Nov 10 PHP
PHP输出多个元素的排列或组合的方法
Mar 14 PHP
PHP实现的链式队列结构示例
Sep 15 PHP
PHP SPL 被遗落的宝石【SPL应用浅析】
Apr 20 PHP
PHP基于cookie实现统计在线人数功能示例
Jan 16 PHP
PHP fprintf()函数用法讲解
Feb 16 PHP
Yii框架函数简单用法分析
Sep 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
javascript 表单的友好用户体现
2009/01/07 Javascript
javascript 实现字符串反转的三种方法
2013/11/23 Javascript
a标签click和href执行顺序探讨
2014/06/23 Javascript
JavaScript及jquey实现多个数组的合并操作
2014/09/06 Javascript
jQuery实现高亮显示的方法
2015/03/10 Javascript
JavaScript tab选项卡插件实例代码
2016/02/23 Javascript
JavaScript函数柯里化详解
2016/04/29 Javascript
Svg.js实例教程及使用手册详解(一)
2016/05/16 Javascript
Bootstrap中的Dropdown下拉菜单更改为悬停(hover)触发
2016/08/31 Javascript
微信小程序实现列表下拉刷新上拉加载
2020/07/29 Javascript
iview tabs 顶部导航栏和模块切换栏的示例代码
2019/03/04 Javascript
vue 使用element-ui中的Notification自定义按钮并实现关闭功能及如何处理多个通知
2019/08/17 Javascript
vue+moment实现倒计时效果
2019/08/26 Javascript
react 不用插件实现数字滚动的效果示例
2020/04/14 Javascript
js实现简单贪吃蛇游戏
2020/05/15 Javascript
Vue实现开关按钮拖拽效果
2020/09/22 Javascript
vue 实现click同时传入事件对象和自定义参数
2021/01/29 Vue.js
[39:53]完美世界DOTA2联赛PWL S2 LBZS vs Forest 第一场 11.19
2020/11/19 DOTA
Python制作刷网页流量工具
2017/04/23 Python
python二维列表一维列表的互相转换实例
2018/07/02 Python
python 实现将字典dict、列表list中的中文正常显示方法
2018/07/06 Python
详解用python写一个抽奖程序
2019/05/10 Python
详解python调用cmd命令三种方法
2019/07/08 Python
用Python抢火车票的简单小程序实现解析
2019/08/14 Python
德国专业木制品经销商:Holz-Direkt24
2019/12/26 全球购物
资产评估专业学生的自我鉴定
2013/11/14 职场文书
社区交通安全实施方案
2014/03/22 职场文书
计算机毕业生求职信
2014/06/10 职场文书
应届生求职信范文
2014/06/30 职场文书
2014年教师节红领巾广播稿
2014/09/10 职场文书
乡镇领导干部个人对照检查材料思想汇报
2014/09/23 职场文书
五年级语文教学反思
2016/03/03 职场文书
Spring Boot 启动、停止、重启、状态脚本
2021/06/26 Java/Android
apache虚拟主机配置的三种方式(小结)
2022/07/23 Servers
Centos7 Shell编程之正则表达式、文本处理工具详解
2022/08/05 Servers
MySQL索引失效十种场景与优化方案
2023/05/08 MySQL