欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

批量或者单个转换文件编码

程序员文章站 2022-06-08 19:33:55
...
转换文件编码,比如原来是gbk,转换成utf-8的,可以转单个文件也可以转换整个目录的文件,可选是否递归目录。
有些问题,不能重复转,比如gbk转到utf8,然后有在转成utf8,这样会乱码,我本来试图在转换之前去检测编码的,貌似失败了。我特意试了一个文件,我检测它是是否是gbk或者是utf-8,都返回true。这就不懂了。
  1. /**
  2. * 转换文件编码
  3. * 依赖的扩展filesystem 和 mbstring
  4. * @example
  5. *
    
    
  6. * include_once 'ConvertEncode.php';
  7. * $convert = new ConvertEncode();
  8. * try{
  9. * $convert->setPath('my', true, true);//目录
  10. * //$convert->setPath('my.php');//单文件
  11. * $convert->setEncode('GBK', 'UTF-8');
  12. * $convert->convert();
  13. * }catch(ConvertException $e) {
  14. * echo $e->getMessage();
  15. * }
  16. *
  17. */
  18. class ConvertEncode {
  19. /**
  20. * 要转换成的编码
  21. * @var string
  22. */
  23. private $_to_encoding;
  24. /**
  25. * 转换前的编码
  26. * @var string
  27. */
  28. private $_from_encoding;
  29. /**
  30. * 要转换的的目录或者单文件
  31. * @var string
  32. */
  33. private $_path;
  34. /**
  35. * 是否是一个目录,当给出的是目录是才设置
  36. * @var boolean
  37. */
  38. private $_directory;
  39. /**
  40. * 是否递归遍历,仅对目录有效
  41. * @var boolean
  42. */
  43. private $_recursion;
  44. /**
  45. * 保存所有待转换的文件,仅当转换目录里面的文件时才用
  46. * @var array
  47. */
  48. private $_files = array();
  49. /**
  50. * 构造函数
  51. */
  52. public function __construct() {
  53. if( ! function_exists('mb_convert_encoding') ) {
  54. throw new ConvertException('mbstring extension be required');
  55. }
  56. }
  57. /**
  58. * 设置需要转换的目录或者单文件
  59. * @param string $path 目录或者文件
  60. * @param boolean 是否是目录
  61. * @param boolean 是否递归目录
  62. * @return boolean
  63. */
  64. public function setPath($path, $is_dir = false, $rec = false) {
  65. $this->_path = $path;
  66. $this->_directory = $is_dir;
  67. $this->_recursion = $rec;
  68. return true;
  69. }
  70. /**
  71. * 设置转换前的编码和要转换到的编码
  72. * @param string $encode 转换前的编码
  73. * @param string $encode 转换到的编码
  74. * @return boolean
  75. */
  76. public function setEncode($encode_from, $encode_to) {
  77. $this->_from_encoding = $encode_from;
  78. $this->_to_encoding = $encode_to;
  79. return true;
  80. }
  81. /**
  82. * 转换编码,根据是否是目录的设置分别转换
  83. * @return boolean
  84. */
  85. public function convert() {
  86. if($this->_directory ) {
  87. return $this->_convertDirectory();
  88. }
  89. return $this->_convertFile();
  90. }
  91. /**
  92. * 转换文件
  93. * @throws ConvertException
  94. * @return boolean
  95. */
  96. private function _convertFile() {
  97. if( ! file_exists($this->_path) ) {
  98. $message = $this->_path . ' does not exist.';
  99. throw new ConvertException($message);
  100. }
  101. if( ! is_file($this->_path) ) {
  102. $message = $this->_path . ' is not a file.';
  103. throw new ConvertException($message);
  104. }
  105. if( ! $this->_isWR() ) {
  106. $message = $this->_path . ' must can be read and write.';
  107. throw new ConvertException($message);
  108. }
  109. $file_real_path = realpath($this->_path);
  110. $file_content_from = file_get_contents( $file_real_path );
  111. if( mb_check_encoding($file_content_from, $this->_from_encoding) ) {
  112. $file_content_to = mb_convert_encoding( $file_content_from, $this->_to_encoding, $this->_from_encoding );
  113. file_put_contents( $file_real_path, $file_content_to );
  114. }
  115. return true;
  116. }
  117. /**
  118. * 转换目录
  119. * @throws ConvertException
  120. * @return boolean
  121. */
  122. private function _convertDirectory() {
  123. if( ! file_exists($this->_path) ) {
  124. $message = $this->_path . ' does not exist.';
  125. throw new ConvertException($message);
  126. }
  127. if( ! is_dir($this->_path) ) {
  128. $message = $this->_path . ' is not a directory.';
  129. throw new ConvertException($message);
  130. }
  131. if( ! $this->_isWR() ) {
  132. $message = $this->_path . ' must can be read and write.';
  133. throw new ConvertException($message);
  134. }
  135. $this->_scanDirFiles();
  136. if( empty($this->_files) ) {
  137. $message = $this->_path . ' is a empty directory.';
  138. throw new ConvertException($message);
  139. }
  140. foreach( $this->_files as $value ) {
  141. $file_content_from = file_get_contents( $value );
  142. if( mb_check_encoding($file_content_from, $this->_from_encoding) ) {
  143. $file_content_to = mb_convert_encoding( $file_content_from, $this->_to_encoding, $this->_from_encoding );
  144. file_put_contents( $value, $file_content_to );
  145. }
  146. }
  147. return true;
  148. }
  149. /**
  150. * 判断文件或者目录是否可读写
  151. * @return boolean 可读写时返回true,否则返回false
  152. */
  153. private function _isWR() {
  154. if( is_readable($this->_path) && is_writable($this->_path) ) {
  155. return true;
  156. }
  157. return false;
  158. }
  159. /**
  160. * 遍历目录,找出所有文件,加上绝对路径
  161. * @return boolean
  162. */
  163. private function _scanDirFiles($dir = '') {
  164. $base_path = empty( $dir ) ? realpath($this->_path) . DIRECTORY_SEPARATOR : realpath($dir) . DIRECTORY_SEPARATOR;
  165. $files_tmp = empty( $dir ) ? scandir($this->_path) : scandir($dir);
  166. foreach( $files_tmp as $value ) {
  167. if( $value == '.' || $value == '..' || ( strpos($value, '.') === 0 ) ) {
  168. continue;
  169. }
  170. $value = $base_path . $value;
  171. if( is_dir($value) ) {
  172. if( $this->_recursion ) {
  173. $this->_scanDirFiles($value);
  174. }
  175. }
  176. elseif( is_file($value) ) {
  177. $this->_files[] = $value;
  178. }
  179. }
  180. return true;
  181. }
  182. }
  183. /**
  184. * 转换异常
  185. *
  186. */
  187. class ConvertException extends Exception {
  188. }
复制代码