汉字转拼音脚本

浏览:2150 发布日期:2014/09/03 分类:技术分享 关键字: 拼音 汉字 转换
PHP汉字转拼音引擎,CLI模式,直接入库。<?php
/**
 * ! CLI运行 !
 * 
 * 将指定字段的中文转换为拼音并存入指定字段
 * 如果发送冲突(拼音已存在),将使用其拼音+ID的形式进行生成,来保证唯一性
 * 如果不想保证唯一性,可把UNIQUENESS设置为false
 * 
 * @author Abel <i@iue.me>
 */

// 配置
const DB_HOST      = '127.0.0.1';                 // 主机地址
const DB_PORT      = '3306';                      // 端口
const DB_NAME      = 'databases';                 // 数据库名
const DB_USER      = 'root';                      // 用户
const DB_PWD       = '123456';                    // 密码
const TABLE_NAME   = 'table';                     // 表名
const FIELD_FROM   = 'name';                      // 中文字段名
const FIELD_TO     = 'pinyin';                    // 存放拼音的字段名
const FIELD_ID     = 'id';                        // Table主键字段
const FIELD_LETTER = 'letter';                    // 首字母字段
const UNIQUENESS   = true;                        // 保证唯一性

/**
 * 汉字转拼音
 * @param string  $string     需要转换的汉字
 * @param string  $split      每个汉字之间的分割符
 * @param boolean $firstUpper 首字母大写
 * @param boolean $isHead     是否为首字母
 * @param boolean $isClose    解析后是否释放资源
 * @return string 返回解析好的拼音
 * @author Web <Unknown>
 */
function Engine($string, $split = '', $firstUpper = false, $isHead = false, $isClose = false){
  global $pinyins;
  $pinyins      = array();
  $string       = iconv('utf-8','gbk//ignore',$string);
  $returnString = '';
  $string       = trim($string);
  $stringLength = strlen($string);
  // 编码长度不符合最低一个中文字符的要求,直接返回
  if($stringLength < 2) return $string;
  // 加载构建pinyins数据
  if(!count($pinyins)){
    $fp = fopen('./pinyin.dat', 'r');
    while(!feof($fp)){
      $line = trim(fgets($fp));
      $pinyins[$line[0].$line[1]] = substr($line, 3, strlen($line) - 3);
    }
    fclose($fp);
  }
  // 处理和识别
  for($i = 0; $i < $stringLength; $i++){
    if(ord($string[$i]) > 0x80){
      $c = $string[$i] .$string[$i + 1];
      $i++;
      if(isset($pinyins[$c])){
        if(!$isHead){
          $returnString .= $split .($firstUpper ? ucfirst($pinyins[$c]) : $pinyins[$c]);
        }else{
          $returnString .= $split .($firstUpper ? ucfirst($pinyins[$c][0]) : $pinyins[$c]);
        }
      }else{
        $returnString .= '_';
      }
    }elseif(preg_match("/[a-z0-9]/i", $string[$i])){
      $returnString .= $split .$string[$i];
    }else{
      $returnString .= $split;
    }
  }
  if($isClose) unset($pinyins);
  return trim($returnString, $split .'_');
}

/**
 * 在命令行输出一条警告信息
 * @param string $content 内容
 */
function info($content){
  echo iconv('utf-8', 'gb2312//ignore', '[信息]'.$content ."\n");
}

/**
 * 在命令行输出一条错误信息
 * @param  string  $content 内容
 * @param  boolean $die     是否终止脚本
 */
function error($content, $die = true){
  echo iconv('utf-8','gb2312//ignore', '[错误]'.$content ."\n");
  $die && die;
}


/**
 * 简易模型
 */
class Model{

  /**
   * 连接实例
   * @var resource
   */
  private $connection = null;
  
  /**
   * 初始化模型
   */
  public function __construct(){
    $this->connection = @mysql_connect(DB_HOST, DB_USER, DB_PWD);
    if(is_resource($this->connection)){
      info('已成功连接到数据库服务器并登录');
      if(mysql_select_db(DB_NAME, $this->connection)){
        info('成功切换到指定数据库');
        $this->query("SET NAMES 'utf8'");
      }else{
        error('切换至指定数据库失败,请确认数据库名称是否准确');
      }
    }else{
      error('连接到数据库服务失败,请确认数据库配置信息。'."\r\n".'错误信息:' .mysql_error());
    }
  }

  /**
   * 解析MYSQL查询结果
   * @param  result $result MYSQL查询结果
   * @return array
   */
  public function parse($result){
    $array = array();
    while($tmp = mysql_fetch_array($result)) $array[] = $tmp;
    return $array;
  }

  /**
   * 执行一条SQL语句
   * @param  string $sql 需要执行的SQL语句
   * @return result
   */
  public function query($sql){ return mysql_query($sql); }

  /**
   * 获取记录
   * @return array
   */
  public function getRecord(){
    $sql = "SELECT `" .FIELD_ID ."`,`" .FIELD_TO ."`,`" .FIELD_FROM ."` FROM `" .TABLE_NAME ."` WHERE `" .FIELD_TO ."` IS NULL";
    
    return $this->parse($this->query($sql));
  }

  /**
   * 检测是否存在记录,防止冲突
   * @param string $content 内容
   * @return boolean
   */
  public function existRecord($content){
    $data = $this->parse($this->query("SELECT `" .FIELD_ID ."` FROM `" .TABLE_NAME ."` WHERE `" .FIELD_TO."` = '{$content}'"));
    return (boolean)count($data);
  }

  /**
   * 设置记录
   * @param  integer $id      记录ID
   * @param  string  $content 内容
   * @return boolean 
   */
  public function setRecord($id, $content){
    return (boolean)$this->query("UPDATE `" .TABLE_NAME ."` SET `" .FIELD_TO."` = '{$content}' WHERE `".FIELD_ID."` = {$id}");
  }

  /**
   * 设置首字母
   * @param integer $id     ID
   * @param string  $letter 首字母
   * @return boolean
   */
  public function setLetter($id, $letter){
    return (boolean)$this->query("UPDATE `" .TABLE_NAME ."` SET `" .FIELD_LETTER."` = '{$letter}' WHERE `".FIELD_ID."` = {$id}");
  }

  /**
   * 析构函数,关闭数据库连接,释放资源
   */
  public function __destruct(){
    info('数据库连接已断开');
    is_resource($this->connection) && mysql_close($this->connection);
  }
}

// 实例化模型对象
$model = new Model();
$data = $model->getRecord();

// 总计数据
$count = count($data);
info("共计 $count 条记录");

// 记录开始时间
$beginTime = microtime(true);

// 成功和失败计次
$success = 0;
$error = 0;

foreach($data as $k => $i){
  $per = sprintf("%.2f" ,(++$k) / $count * 100);
  info("正在处理【{$i[FIELD_FROM]}】,第 {$k} 条,共计 {$count} 条,完成 {$per}%");
  $py = Engine($i[FIELD_FROM]);
  if($model->existRecord($py) && UNIQUENESS){
    $py .= '-' .$i[FIELD_ID];
    // 已存在
    info("【{$i[FIELD_FROM]}】的拼音已存在,采用替代方案{$py}");
  }
  info("正在添加【{$i[FIELD_FROM]}】的拼音为{$py}");
  if($model->setRecord($i[FIELD_ID], $py)){
    if(FIELD_LETTER){
      // 添加首字母
      $letter = ucfirst(substr($py, 0, 1));    // 首字母
      info("正在添加【{$i[FIELD_FROM]}】的首字母为{$letter}");
      if($model->setLetter($i[FIELD_ID], $letter)){
        info("【{$i[FIELD_FROM]}】首字母添加成功");
      }else{
        info("【{$i[FIELD_FROM]}】首字母添加失败");
      }
    }

    info("【{$i[FIELD_FROM]}】处理成功,处理下一条");
    $success ++;
  }else{
    error("【{$i[FIELD_FROM]}】处理失败,跳过,继续处理下一条", false);
    $error ++;
  }
}

$time = sprintf("%.2f", ((microtime(true) - $beginTime))); // s

echo "\n";
info("全部处理完毕,共计处理 {$count} 条,成功 {$success} 条,失败 {$error} 条,耗时:{$time} s");
最佳答案
评论() 相关
后面还有条评论,点击查看>>