用户可以自己你添加单词和翻译,前提是这些单词没有被添加过,而且在redis里面不存在,也就是不允许有重复的单词存在,添加完之后,可以再前段通过查询,得到添加的对应的翻译。。。。
有一个功能是: 用户提交的词条会生成对应的索引,索引的形式是:该单词的前缀,单词本身,单词在数据库中的唯一ID,这些单词在数据库中也是分类存储的。。
(单词前缀,单词本身,唯一数据库ID )这个hash项是添加到redis中的,当存在巨大的用户添加词条时,仍然可以做到微妙的查询速度
一次性发完:
<?php
class AddRedis
{
private $redis=null;
private $host="localhost";
private $username="root";
private $passwd="cai123";
private $db="words";
private $conn=null;
public function __construct()
{
$this->redis=new Redis();
$this->redis->connect('127.0.0.1', 6379);
$this->redis->auth('caifangjie');
$this->conn=new mysqli($this->host, $this->username, $this->passwd) or die('连接mysql失败'.mysql_error);
$this->conn->select_db($this->db);
$this->conn->query("set names utf8");
}
//把添加的单词作为键,last_insert_id作为值,插入到redis
public function setIndex($wordzone, $word,$num_index)
{
$zone = $wordzone."::USER";
$this->redis->hSetNx($zone, $word, $num_index);
}
//从redis中获取last_insert_id,然后去数据库查询用户添加的单词
public function getIndex($word)
{
$zone = strtolower(substr($word, 0,1))."::USER";
if($this->redis->hExists($zone, $word))
{
return $this->redis->hGet($zone, $word);
}
else
{
return 0;
}
}
public function getTrans($word)
{
//从获取ID,去数据库中查询单词
$id = $this->getIndex($word);
if($id != 0)
{
$table = strtolower(substr($word, 0,1));
$sql = "SELECT trans FROM {$table} WHERE id = {$id}";
$res = $this->conn->query($sql);
if($this->conn->affected_rows)
{
$trans = $res->fetch_row()[0];
$res->free();
return array($trans);
}
else
{
return 0;
}
}
else
{
return 0;
}
}
}
/* $word = new AddRedis();
var_dump($word->getTrans("makebbb")); */
?>
<?php
require_once "addredis.class.php";
class Addword
{
private $host="localhost";
private $username="root";
private $passwd="cai123";
private $db="words";
private $conn=null;
public function __construct()
{
$this->conn=new mysqli($this->host, $this->username, $this->passwd) or die('连接mysql失败'.mysql_error);
$this->conn->select_db($this->db);
$this->conn->query("set names utf8");
}
public function setword($word, $trans)
{
$wordzone = substr($word,0,1);
$sql = "SHOW TABLES LIKE '$wordzone' ";
$this->conn->query($sql);
$last_id=null;
//表示此分类表已经存在,所以不用创建
if($this->conn->affected_rows)
{
$sql = "SELECT * FROM $wordzone WHERE word='$word' ";
$ifExists = $this->conn->query($sql);
//只有当待插入的单词在表中不存在时
if(!$this->conn->affected_rows)
{
$sql = "INSERT INTO $wordzone(word, trans) VALUES('$word', '$trans')";
$this->conn->query($sql);
//获取插入最近一次插入数据库的ID
$res=$this->conn->query("SELECT LAST_INSERT_ID() FROM $wordzone");
$last_id = $res->fetch_row()[0];
$res->free();
if(!$this->conn->affected_rows)
{
die("插入词条失败");
}
}
else
{
$ifExists->free();
die($word."已经存在于".$wordzone."表中,暂时禁止更新");
}
}
else
{ //当wordzone表不存在时,创建
$sql = "CREATE TABLE $wordzone(id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, word VARCHAR(32) NOT NULL DEFAULT '', trans VARCHAR(128) NOT NULL DEFAULT '')charset utf8";
$this->conn->query($sql);
$sql = "INSERT INTO $wordzone(word, trans) VALUES('$word', '$trans')";
$this->conn->query($sql);
$res=$this->conn->query("SELECT LAST_INSERT_ID() FROM $wordzone");
$last_id = $res->fetch_row()[0];
$res->free();
if(!$this->conn->affected_rows)
{
die("插入词条失败");
}
}
/*
*插入单词时可以返回wordzone( word(key) last_insert_id(value)),并插入redis缓存,用以索引
* redis->setIndex($wordzone, $word, $last_id);
*/
if($last_id)
{
$redis = new AddRedis();
$redis->setIndex($wordzone, $word, $last_id);
}
}
/*
public function getword($word)
{
$word = trim($word);
$wordzone=substr($word, 0,1);
$sql = "SHOW TABLES LIKE '$wordzone' ";
$ifExists = $this->conn->query($sql);
//表示此分类表已经存在,所以不用创建
if($this->conn->affected_rows)
{
$ifExists->free();
$sql = "SELECT trans FROM $wordzone WHERE word='$word' ";
$trans = $this->conn->query($sql);
if($this->conn->affected_rows)
{
$res = $trans->fetch_row()[0];
$trans->free();
return array($res);
}
else
{
return array($wordzone."表中不存在单词".$word);
}
}
else
{
return array("不存在".$wordzone."表,无法获取".$word."的翻译");
}
}*/
}
/*
$word = new Addword(); */
?>
///下面这段程序是控制器
会检查单词是否为英文,如果翻译比较长,会无损截断,再就是判断单词是否存在原始单词库中,判断该单词是否被其他用户添加过,并在用户添加完之后,返回一个成功或者失败的提示,当然是无刷新的
<?php
require_once "addword.class.php";
require_once "../processCheck.class.php";
require_once "../storeWord.class.php";
header("content-type: text/html");
if( !empty($_GET['word']) && !empty($_GET['trans']))
{
$word = trim($_GET["word"]);
$trans = trim($_GET["trans"]);
if(!preg_match('#[a-z]+#', $word)) die("添加的单词只能是英文");
//判断添加的词条是否已经存在
$check = new Check();
$redis = new StoreWord();
$wordzone = $check->matchDic($word);
if($redis->getWord($wordzone, $word)!= 0)
die($word."已经存在redis数据库中,禁止添加");
//判断提交的词条对应的翻译是否超过128,如果超过128则截断;
$string='';
if(strlen($trans)>128)
{
for($i=0; $i<128; $i++)
{
if(ord(substr($trans, $i, 1))>0xa0)
{
$string .= substr($trans, $i, 3);//因为是以UTF-8编码保存的
$i++;$i++;
}
else
{
$string .= $trans[$i];
}
}
$trans = $string;
}
if(strlen($word)>32) $word=substr($word, 0,32);
$words = new Addword();
$words->setword($word, $trans);
$red = dechex(mt_rand(0,255));
$green = dechex(mt_rand(0,255));
$blue = dechex(mt_rand(0,255));
$color="#".$red.$green.$blue;
echo "<span style='color:$color'>添加词条成功</span>";
}
else
{
echo "添加词条失败".basename(__FILE__)." ::". __LINE__;
}
?>
//这个事界面,可以添加词条和翻译,还有一个隐藏区域,在用户添加词条之后,用于无刷新显示,添加成功或者失败的原因,比如单词背添加过,或者存在原始的词库里,经过反复测试,可以做到不重复
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<style type="text/css">
#addword{position: absolute; left:410px; top:130px}
span{font-size: 25px; font-weight: 12pt; color: #ababab; background-color: #B9D3EE; margin-right: 10px; height:50px;}
span#addtrans{position: relative; top: -160px;}
#word{width: 625px; height: 40px; margin-bottom: 10px; }
input#word{font-size: 24px;padding-left: 5px;color:#CD661D;}
textarea#trans{font-size: 20px;padding-left: 5px;padding-top:5px;color:#1C86EE}
input#submit{width:65px;height:35px;padding: 1px;font-family: Arial,Helvetica,sans-serif; font-size:16px; position: absolute; left:670px;}
#feedback{position: absolute; left:110px; background-color:DBDBDB; color:#ee0000; height:30px;}
</style>
<script type="text/javascript">
function checkLength()
{
if(document.getElementById("trans").value.length >= 42)
{
alert("最多支持42个字符");
}
}
function clearTextarae()
{
document.getElementById("trans").value="";
}
function clearInput()
{
document.getElementById("word").value="";
}
function getXMLHttpRequest()
{
var xmlhttp=null;
if(window.ActiveXObject)
{
xmlhttp = new ActiveXObject("Microsoft.XMLHttp");
}
else
{
xmlhttp=new XMLHttpRequest();
}
return xmlhttp;
}
function sendQuery()
{
var xmlhttp = getXMLHttpRequest();
if(xmlhttp)
{
url="/ciba/niujin-alpha/addword/addword.process.php?";
var word = $("word").value;
var trans = $("trans").value;
var data="word="+word+"&trans="+trans;
xmlhttp.open("get", url+data, true);
xmlhttp.onreadystatechange=function()
{
if(xmlhttp.readyState==4 && xmlhttp.status==200)
{
var res = xmlhttp.responseText;
$("feedback").innerHTML=res;
}
}
xmlhttp.send(null);
}
}
function $(id)
{
return document.getElementById(id);
}
</script>
</head>
<body bgcolor="#RGB(67,65,65)">
<img src="../image/addci.jpg" style="margin-left: 400px;">
<div id="addword">
<span>添加单词</span><input type="text" value = "添加单词"id="word" name="word" οnclick="clearInput();"><br />
<span id="addtrans">添加翻译</span><textarea cols="60" rows="8" id="trans" name="trans" οnkeydοwn="checkLength();" οnclick="clearTextarae();">添加翻译,暂时只允许42字符</textarea><br />
<div id="feedback"></div><input type = "button" value="提交" id="submit" οnclick="sendQuery();">
</div>
</body>
</html>
//最重要的一点是:允许用户添加词条当然是对词库的补充和完善,当然添加后的词条,在前段是可以查询的到的。。。。。