<?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"); 最佳答案