手机浏览 RSS 2.0 订阅 膘叔的简单人生 , 腾讯云RDS购买 | 超便宜的Vultr , 注册 | 登陆
浏览模式: 标准 | 列表Tag:mbstring

PHP更改文件编码

PHP更改文件编码应该算是比较简单的事情,在使用uchome项目(UTF-8)的时候,发现程序的编码好奇怪,有ANSI的,和UTF-8的。
很妖的是,我在ubuntu下面打开这些ansi的文件时,由于文件中含 有中文,结果全显示乱码,编码还显示为latin1。然后拷到另外一个目录,编码显示就正常了,为CP936。
由于编辑器没有批量转换功能,固此,只能使用PHP自带的功能了。。。(关键我也不会其他语言)
由于转换的时候会需要判断一下编码,如果编码本身是UTF-8的,再使用mb_convert_encoding($data,'utf-8','gbk'),反而会导致乱码。。
所以。。。就有了以下程序
慎重申明:Dir类的rmdir有BUG,请勿使用。。。。写的时候,我没有考虑太多,如果设定了某个目录,最终是会把这个目录也会删除的,而与我事先想的。把该目录下的内容清空有误差。(当然也可以在删除后重建,但毕竟不是原来的权限了。)

代码如下:

PHP代码
  1. <?php  
  2.   
  3. $dirName = "./uchome";  
  4.   
  5. $files = Dirs::read( $dirName , true);  
  6.   
  7. foreach$files as $fileName )  
  8. {  
  9.     ifis_file$fileName ) && in_array(Files::extension( $fileName ) , array('php','html','htm'))){  
  10.         $fileData = Files::read( $fileName );  
  11.         $fileType = mb_detect_encoding($fileData , array('UTF-8','GBK','LATIN1','BIG5')) ;  
  12.         if$fileType == 'CP936'){  
  13.             $fileData = mb_convert_encoding($fileData ,'utf-8' , 'gbk');  
  14.             if( Files::save( $fileName , $fileData )){  
  15.                 echo "{$fileName} convert successed";  
  16.                 echo "<br />";            
  17.             }  
  18.         }  
  19.     }  
  20. }  
  21.   
  22.   
  23.   
  24. //dir  
  25. class Dirs  
  26. {  
  27.     static function read ( $dirname , $recursive = false)  
  28.     {  
  29.         static $allInfo;  
  30.         $dirname .= subStr$dirname, -1 ) == "/"  ? "" : "/";  
  31.         $dirInfo = glob$dirname . "*" );  
  32.         if ( $recursive == false ){  
  33.             return $dirInfo;  
  34.         }else{  
  35.             foreach ( $dirInfo as $info ){  
  36.                 if ( is_dir$info ) ){  
  37.                     if ( !is_readable$info ) ){  
  38.                         chmod$info, 0777 );  
  39.                     }  
  40.                     //$allInfo['dirs'][] = $info;  
  41.                     $allInfo[] = $info;  
  42.                     self::read( $info , true);  
  43.                 }else{  
  44.                     //$allInfo['files'][] = $info ;  
  45.                     $allInfo[] = $info;  
  46.                 }  
  47.             }  
  48.         }  
  49.         return $allInfo;  
  50.     }  
  51.   
  52.     static function rmdir ( $dirname )  
  53.     {  
  54.         if ( is_dir$dirname ) && !is_writeable$dirname ) ){  
  55.             if ( !chmod$dirname , 0666 ) ){  
  56.                 return false;  
  57.             }  
  58.         }else if ( !is_dir$dirname ) ){  
  59.             return false;  
  60.         }  
  61.         $dirname .= subStr$dirname, -1 ) == "/"  ? "" : "/";  
  62.         $dirInfo = glob$dirname . "*" );  
  63.         foreach ( $dirInfo as $info ){  
  64.             if ( is_dir$info ) ){  
  65.                 self::rmdir$info );  
  66.             }else{  
  67.                 unlink( $info );  
  68.             }  
  69.         }  
  70.         @rmdir$dirname );  
  71.     }  
  72.   
  73.     function mkdir($dir$mode = 0777)  
  74.     {  
  75.         if (!is_dir($dir)){  
  76.             $ret = @mkdir($dir$mode, true);  
  77.             if (!$ret){  
  78.                 exit('function:mkdirs failed');  
  79.             }  
  80.         }  
  81.         return true;  
  82.     }  
  83. }  
  84. //file  
  85. class Files  
  86. {  
  87.     static function read ( $filename )  
  88.     {  
  89.         if ( !is_readable$filename ) ){  
  90.             chmod$filename, 0644 );  
  91.         }  
  92.         return file_get_contents$filename );  
  93.     }  
  94.   
  95.     static function create ( $filename , $mod = 0666 )  
  96.     {  
  97.         if ( @touch( $filename ) == false){  
  98.             $fp = fopen$filename"a+" );  
  99.             if ( $fp ){  
  100.                 fclose( $fp );  
  101.             }  
  102.         }  
  103.         chmod$filename, 0666 );  
  104.     }  
  105.   
  106.     static function save ( $filename , $data , $append = false)  
  107.     {  
  108.         if ( !file_exists$filename ) ){  
  109.             self::create($filename);  
  110.             $append = false;  
  111.         }  
  112.         if ( $append == false ){  
  113.             return file_put_contents$filename , $data );  
  114.         }else{  
  115.             if ( !is_writeable$filename ) ){  
  116.                 chmod$filename, 0666 );  
  117.             }  
  118.             return file_put_contents$filename , $data , FILE_APPEND );  
  119.         }  
  120.     }  
  121.   
  122.     static function delete ( $filename )  
  123.     {  
  124.         if ( !is_array$filename ) ){  
  125.             $filenames = array($filename);  
  126.         }  
  127.         foreach ( $filenames as $filename ){  
  128.             if ( is_file$filename ) ){  
  129.                 if( !unlink( $filename ) ){  
  130.                     chmod$filename , 0666 );  
  131.                     unlink( $filename );  
  132.                 }  
  133.             }  
  134.         }  
  135.     }  
  136.       
  137.     static function extension( $filename ){  
  138.         return strtolower(pathinfo$filename , PATHINFO_EXTENSION ));  
  139.     }  
  140. }  

Tags: php, mbstring

关于 PHP 中的 iconv 函数的一点小问题[转]

作者:andot,来自:www.coolcode.cn,出处:http://www.coolcode.cn/show-41-1.html

原文如下
  1. 昨天在调试 WAP 网站时发现,在增加了 GB2312 到 UTF-8 转化以后,有些页面显示不正常了——有些页面只有一半的内容,另一半被截掉了。因为被截掉的部分包含了<p>的后半个标签</p>,因此整个页面都显示不出来,而报告错误。经过猜测、尝试,最后终于把问题集中在了 iconv 函数上。在经过高人指点以后,发现这个函数的第二个参数,除了可以指定要转化到的编码以外,还可以增加两个后缀://TRANSLIT 和 //IGNORE,其中 //TRANSLIT 会自动将不能直接转化的字符变成一个或多个近似的字符,//IGNORE 会忽略掉不能转化的字符,而默认效果是从第一个非法字符截断。但是我尝试了//TRANSLIT 和 //IGNORE 这两个后缀,效果还是不对。于是我想问题可能不是出在这里。从 GB2312 到 UTF-8 转化应该不会有不能转化的字符,因为 UTF-8 的字符集完全包含了 GB2312 中的字符,所以我想大概是前面要转化的字符集指定错了,于是我尝试着把 GB2312 改成 GBK,问题解决!虽然那两个后缀在这里没派上用场,不过也算学了一招,以后肯定会用到的。补记:改成 GBK 后,发现仍然有一封邮件的内容解析不正确。在另一位高人指点下,先换成 GB18030,问题依旧,然后改用 mb_convert_encoding 进行转换,问题解决!不知道是 mb_convert_encoding 问题,还是我的系统问题,我用 mb_convert_encoding 时不支持 GB18030 编码。另外,用 GBK 或者GB18030 作为输入编码,并在输出编码中加上 //IGNORE 后缀,用 iconv 函数也能解决那封含有错误编码的邮件内容解析不正确的问题。不过用 mb_convert_encoding 可以指定多种输入编码,它会根据内容自动识别,这个比 iconv 要好的多。  

其实,同事在生成图片文字水印的时候也遇到了这种问题,同事最初用的是GB2312字符集,结果直接报错,说是字符串的offset有问题,但仔细检查后却没有这种问题。后来才发现是直接调用的这个iconv转换出错了。
原来的转换是从gb2312往 UTF8转换,表面上确实没有什么问题,然而,现在的人特别爱装酷,受影响的那位同志,用的是繁体字,繁体字的字库大多情况是属于GBK的,所以后来换成GBK后就正常了。
估计以后再遇上用火星文的朋友,就真的只能使用andot提出的这种方法了。转换成18030,再使用ignore参数。哈哈

mbstring好象最初的版本里没有使用,如果换成这个,估计代码工作量非常大,先将就着点了

Tags: 字符转换, php, iconv, mbstring, convert