songah 发表于 2010-6-24 14:52:44

汉语转拼音helper函数,改自dedecms,随度老快了(代码见4楼)

本帖最后由 songah 于 2010-6-25 09:01 编辑

在做上传时发现汉语无法实现上传,而且又不想改文件名,于是想到把汉语转成拼音,扩展Upload类,这里使用了论坛上一个拼音类
http://codeigniter.org.cn/forums/viewthread.php?tid=5053&highlight=%E6%8B%BC%E9%9F%B3,不过使用起来发现效果不行,速度太慢,如果汉字超过十个基本就超时了,平均没转换一个汉字需要2s以上。然后还单独在控制器中做了测试,时间还是太慢。

class MY_Upload extends CI_Upload {

    function MY_Upload($props = array())
    {
      parent::CI_Upload($props);
    }

    function _prep_filename($filename)
    {
      $filenameReload = parent::_prep_filename($filename);

      $ext = $this->get_extension($filenameReload);

      $filenameOnly = str_replace($ext,'',$filenameReload);

      if(preg_match("/[\x{4e00}-\x{9fa5}]+/u",$filenameOnly))
      {
            $CI = &get_instance();
            $CI->load->library('pinyin');
            $CI->benchmark->mark('str2py');
            $filenameOnly = $CI->pinyin->str2py($filenameOnly);
            $CI->benchmark->mark('str2py_end');
      }

      return $filenameOnly.$ext;
    }

}

弄了很久,还是没有解决,然后忽然想到使用dedecms时那个转换速度非常不错,于是把dedecms的拼音转换函数拿过来试了一下,效果惊人,汉字的数目对于运行速度一点影响都没有,从1个汉字到十几个汉字都在1.5s以内完成。呵呵强悍吧。OK现在可以把下面那个函数放在helper中了,或者直接扩展到MY_Upload中,然后就可以把带汉字的文件名改为拼音了。当然也许可以在类中添加一个属性pinyins作为缓存——可以省去重复读取文件,这在dedecms中是通过定义全局变量实现的

    function str2py($word = '测试1')
    {
      $pinyin = $this->GetPinyin(iconv('UTF-8','GB2312',$word));
      echo $pinyin;
    }

    function GetPinyin($str,$ishead=0,$isclose=1)
    {
      $pinyins = array();
      $restr = '';
      $str = trim($str);
      $slen = strlen($str);
      if($slen<2)
      {
            return $str;
      }
      if(count($pinyins)==0)
      {
         //APPPATH下resources文件中有一个数据文件文件在附件中,解压缩放在application/resources/文件夹中就ok了
            $fp = fopen(APPPATH.'/resources/pinyin.dat','r');
            while(!feof($fp))
            {
                $line = trim(fgets($fp));
                $pinyins[$line.$line] = substr($line,3,strlen($line)-3);
            }
            fclose($fp);
      }
      for($i=0;$i<$slen;$i++)
      {
            if(ord($str[$i])>0x80)
            {
                $c = $str[$i].$str[$i+1];
                $i++;
                if(isset($pinyins[$c]))
                {
                  if($ishead==0)
                  {
                        $restr .= $pinyins[$c];
                  }
                  else
                  {
                        $restr .= $pinyins[$c];
                  }
                }else
                {
                  $restr .= "_";
                }
            }else if( eregi("",$str[$i]) )
            {
                $restr .= $str[$i];
            }
            else
            {
                $restr .= "_";
            }
      }
      if($isclose==0)
      {
            unset($pinyins);
      }
      return $restr;
    }

suncel0628 发表于 2010-6-24 15:21:49

:sleepy:,这个怎么用。。。?

songah 发表于 2010-6-24 17:03:55

本帖最后由 songah 于 2010-6-24 17:09 编辑

把str2py函数和GetPinyin函数放到一个控制器了,假设这个控制器是test,然后运行test/str2py,可以看到输出的结果了,然后还可以在test/str2py后面输入参数,比如test/str2py/大家一起来测试,这个需要论坛中中文uri支持http://codeigniter.org.cn/forums/viewthread.php?tid=5321&highlight=%E4%B8%AD%E6%96%87%2Buri
然后就会出现最后一个uri参数的拼音了,GetPinyin函数第一个参数是必须的,也就是传入的字符串,需要转化为gb2312编码,第二个参数是只显示第一个字母的,默认是显示全拼,最后一个参数是用来注销缓存的,但是这个函数没有缓存,其实也没有必要

注解中有关于附件使用的,怕大家没看到,也贴出来吧:APPPATH下resources文件中有一个数据文件文件在附件中,把后缀改为dat(因为不允许传dat文件,就顺便改成pdf的,大家不要被迷糊了哦),放在 application/resources/文件夹中就ok了

Hex 发表于 2010-6-24 21:52:11

其实楼主可以压缩一下,就可以传上来了,还不容易迷糊,我帮楼主压缩一下,呵呵

songah 发表于 2010-6-25 08:59:42

回复 4# Hex
噢,是啊,我怎么都给忘了呢呵呵
多谢管理员的厚爱啊,我把最后的文件都上传来吧,包括一个pinyin helper文件,一个MY_Upload.php文件,实现上传类把文件名中汉语转为拼音,具体使用方法见注解。

longjianghu 发表于 2010-6-30 13:38:40

有空再试

snllll 发表于 2010-7-2 00:00:49

好!有用!URL优化很有帮助。顶

织梦的蚂蚁 发表于 2011-7-12 11:14:27

哥们儿,你的帖子虽然很久了,但是帮了我很大的忙,谢谢你啦!

fltn03 发表于 2013-6-19 14:11:24

好帖!找了这么久,终于找到一个比较全面的了!

xie008 发表于 2014-5-8 14:41:51

嗯,很好啊!感谢。
页: [1] 2
查看完整版本: 汉语转拼音helper函数,改自dedecms,随度老快了(代码见4楼)