轉換文件編碼,比如原來是gbk,轉換成utf-8的,可以轉單個文件也可以轉換整個目錄的文件,可選是否遞歸目錄
有些問題,不能重復轉,比如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 { }