//这个功能充分检验了英语六级是多么菜,如果你去听美国总统的演讲,基本是听不懂的,因为太多单词不懂。 这个模块的功能主要是,可以阅读美国历届总统的演讲,在遇到不懂的单词时,可以双加单词,或者划选单词,然后,,然后,对应的翻译就出来了,而且是秒速度。。。。
//这个英语6级的单词词库是网上找的,就是sql语句组成的,所以省了不少事,需要的可以留言
封装了一些对数据库的操作,虽然对于1万多条单词,MySQL满足查询可以毫无压力,不过我还是添加了划词分类和索引以及唯一的ID形成一个item存到对应的redis哈希表中,这样从原理上说,速度肯定是更快的,但是单词不算多,这样也无伤大雅
<?php
require_once 'redis.class.php';
require_once 'format.class.php';
class Sql
{
private $host="localhost";
private $username="root";
private $passwd="cai123";
private $db="words";
private $conn=null;
private $errMsg=0;
private $id;
private $redis=null;
public function __construct()
{
$this->conn=new mysqli($this->host, $this->username, $this->passwd) ;
if(!$this->conn)
{
$this->errMsg = '连接数据库失败'.__LINE__;
exit();
}
$this->conn->select_db($this->db);
$this->conn->query("set names utf8");
$this->redis = new RedisServer();
}
//根据单词去redis中寻找ID
public function getId($word)
{
$temp = $this->redis->getIndex($word);
if($temp ==="none")
{
die( "没有对应的翻译");
}
else
{
$this->id = intval($temp, 10);
}
}
//根据ID获取简明翻译
public function getMeaning()
{
$sql = "SELECT meaning FROM cetsix WHERE id = ".$this->id;
$result = $this->conn->query($sql);
if($this->conn->affected_rows > 0)
{
$word = $result->fetch_row()[0];
$result->free();
return $word;
}
else
{
return "没有对应的翻译";
}
}
//根据id获取例句
public function getExt()
{
$sql = "SELECT lx FROM cetsix WHERE id = ".$this->id;
$result = $this->conn->query($sql);
if($this->conn->affected_rows > 0)
{
$lx = $result->fetch_row()[0];
$result->free();
return $lx;
}
else
{
return "没有对应的翻译";
}
}
//获取简明翻译和例句,以字符串的形式返回
public function getAllWithString()
{
$sql = "SELECT meaning, lx FROM cetsix WHERE id = ".$this->id;
$result = $this->conn->query( $sql);
if($this->conn->affected_rows > 0)
{
$items = $result->fetch_assoc();
$meaning = $items['meaning'];
$lx = $items['lx'];
$result->free();
return $meaning."---".$lx;
}
else
{
return "没有对应的翻译";
}
}
//返回翻译和例句,以数组的形式返回
public function getAllWithArray()
{
$sql = "SELECT meaning, lx FROM cetsix WHERE id = ".$this->id;
$result = $this->conn->query( $sql);
if($this->conn->affected_rows > 0)
{
$items = $result->fetch_assoc();
$meaning = $items['meaning'];
$lx = $items['lx'];
$result->free();
return array($meaning, $lx);
}
else
{
return "没有对应的翻译";
}
}
public function __destruct()
{
$this->conn->close();
}
}
//$sql = new Sql();
//$sql -> getId("able");
//$format = new Format();
//var_dump( $format->stripBreak($sql->getAllWithArray()));
?>
//下面这个类比较纯洁.......构建索引,查询索引
<?php
class RedisServer
{
private $redis=null;
private $prefix="index::";
public function __construct()
{
$this->redis=new Redis();
$this->redis->connect('127.0.0.1', 6379);
$this->redis->auth('caifangjie');
}
//设置索引,索引的形式是 (前缀+单词首字母, 单词,数字索引【对应数据库】)
public function setIndex(&$index)
{
foreach($index as $item)
{
$this->redis->hSet($this->prefix.$item[0], $item[1], $item[2]);
}
}
//返回单词对应的数字索引
public function getIndex($word)
{
$zone = substr(strtolower(trim($word)), 0,1);
if($this->redis->hExists($this->prefix.$zone, $word))
{
return $this->redis->hGet($this->prefix.$zone, $word);
}
else
{
return "none";
}
}
}
?>
//这个类更加纯洁,划词,构建索引
<?php
/*
本类的工作主要是负责根据id和单词(id, word)建立索引,
索引的形式是(前缀,单词,id)
*/
require_once "redis.class.php";
class BuildIndex
{
private $host="localhost";
private $username="root";
private $passwd="cai123";
private $db="words";
private $conn=null;
private $wordsNum;
private $errMsg=0;
private $redis=null;
public function __construct()
{
$this->conn=new mysqli($this->host, $this->username, $this->passwd) ;
if(!$this->conn)
{
$this->errMsg = '连接数据库失败'.__LINE__;
exit();
}
$this->conn->select_db($this->db);
$this->conn->query("set names utf8");
$sql = "SELECT COUNT(*) FROM cetsix";
$result = $this->conn->query($sql);
if($this->conn->affected_rows > 0)
{
$this->wordsNum = $result->fetch_row()[0];
$result->free();
}
else
{
$this->errMsg="查询词条总数失败".__LINE__;
exit();
}
$this->redis = new RedisServer();
$this->buildIndex();
}
private function buildIndex()
{
$onceReadSize = 500;
$loop= ceil($this->wordsNum/500);
for($i=1; $i<=$loop; $i++)
{
$sql = "SELECT id, word FROM cetsix LIMIT ".($i-1)*$onceReadSize." , ".$onceReadSize;
$result = $this->conn->query($sql);
$index = array();
while($row = $result->fetch_assoc())
{
$word = strtolower(trim($row['word']));
$index[] = array(substr($word, 0, 1), $word,$row['id']);
}
$this->redis->setIndex($index);
unset($index);
$result->free();
echo str_repeat(" ", 2048);
echo "创建索引".$i*$onceReadSize."条,Ok..<br />";
sleep(2);
}
echo "索引创建完毕";
}
public function __destruct()
{
$this->conn->close();
}
}
set_time_limit(1000);
ob_implicit_flush(true);
$index = new BuildIndex();
?>
//下面这个更简单,启动后台服务。。。。
<?php
require_once 'readSpeech.class.php';
require_once 'readDir.class.php';
class ServerForSpeech
{
static public function init()
{
$dir = new Dir('E:\CodeEdit\php\ciba\niujin-alpha\paragraph\data');
$list = $dir->getFileList();
$readSpeech = new ReadSpeech();
foreach($list as $name => $path)
{
$readSpeech->setSpech($name, $path);
if($readSpeech->errMsg !=0) die("导入失败");
}
echo "导入OK";
}
}
ServerForSpeech::init();
?>
//这个类也比较纯洁,迭代出总统演讲那个目录下的文件
<?php
class Dir
{
private $fileList=array();
public function __construct($path)
{
$this->readFileList($path);
}
function readFileList($path)
{
$path=$this->transPathSep($path);
$encode=mb_detect_encoding($path, array('GB2312','GBK','UTF-8','BIG5','LATIN1'));
$path=mb_convert_encoding($path, 'GB2312', $encode);
//用于路径读取时用UTF编码会失败,所以先转成GB2312
if ($fd=opendir($path))
{
while($fileName=readdir($fd))
{
//如果不是当前目录和上级目录
if($fileName !="." && $fileName !="..")
{
//如果是一个文件
if(is_file($path.'/'.$fileName))
{
$extName=pathinfo($path."/".$fileName)["extension"];
if(strtolower($extName)=='txt')
{
//上面把路径转成了GB2312,这里再转换会UTF-8编码
$temp=mb_convert_encoding($path.'/'.$fileName, 'UTF-8', $encode);
$groupName=$this->groupFile($temp);
$this->fileList[$groupName]=$temp;
}
}
//如果是一个目录,则继续递归读取
else if(is_dir($path.'/'.$fileName))
{
$this->readFileList($path.'/'.$fileName);
}
}
}
}
@closedir($fd);
}
public function getFileList()
{
return $this->fileList;
}
//提取单词分类,比如从A-Z
private function groupFile($filename)
{
$pos=strtolower(strripos($filename, '/'));
$word=trim(basename(substr($filename, $pos+1),'.txt'));
return $word;
}
//转换window环境下路径的默认分隔符\为PHP识别更好的/
//因为路径名中包含汉字时,必须转换为gb2312时,php才能识别
//而在转换为gb2312后,如果路径名是以windows下的\分隔的,则被转换为gb2312的中文会被转义
//最后就会导致读取对应的路径失败
//******所以在{路径名}中包含中文时,一定要先转换路径分隔符,然后转换为gb2312编码
private function transPathSep($path)
{
$system=$_SERVER["SERVER_SOFTWARE"];
$pat="#\((.*?)\)#";
$sysVer=null;
if(preg_match($pat,$system,$match))
{
$sysVer=$match[1];
}
else
{
die("匹配系统类型失败<br />");
}
if(strtolower($sysVer)=="win32")
{
$realPath=str_replace("\\","/",$path);
return $realPath;
}
}
}
/* $dir=new Dir('E:\CodeEdit\php\ciba\niujin-alpha\paragraph\data');
$list=$dir->getFileList();
echo "<pre>";
foreach ($list as $name => $path)
{
echo $name.'-----'.mb_strlen($name).'------'.$path.'------'.mb_strlen($path)."<br />";
}
echo "</pre>"; */
?>
//这个类也比较纯洁,封装了对总统演讲对应的文件的名字和路径到数据库,并提供查询功能
<?php
class ReadSpeech
{
private $host="localhost";
private $username="root";
private $passwd="cai123";
private $db="words";
private $conn=null;
public $errMsg=0;
public function __construct()
{
$this->conn=new mysqli($this->host, $this->username, $this->passwd) ;
if(!$this->conn)
{
$this->errMsg = '连接数据库失败'.__LINE__;
exit();
}
$this->conn->select_db($this->db);
$this->conn->query("set names utf8");
}
public function setSpech($name, $path)
{
$sql = "INSERT INTO presidentSpeech(name, path) VALUES('$name' , '$path')";
$this->conn->query($sql);
if(!($this->conn->affected_rows > 0))
{
$this->errMsg="写入名字和路径失败".__LINE__;
exit();
}
}
public function getSpeechById($id)
{
$sql = "SELECT name,path FROM presidentSpeech WHERE id = ".$id;
$result = $this->conn->query($sql);
if($this->conn->affected_rows > 0)
{
$items = $result->fetch_row();
$name = $items[0];
$path = $items[1];
$result->free();
return array($name,$path);
}
else
{
$this->errMsg="获取路径失败".__LINE__;
exit();
}
}
public function getAllSpeech()
{
$sql = "SELECT id , name FROM presidentSpeech ";
$result = $this->conn->query($sql);
$res=array();
if($this->conn->affected_rows > 0)
{
while($rows = $result->fetch_assoc())
{
$id = $rows['id'];
$name = $rows['name'];
$res[] = array($id, $name);
}
$result->free();
return $res;
}
else
{
$this->errMsg="总统演讲信息失败".__LINE__;
exit();
}
}
public function __destruct()
{
$this->conn->close();
}
}
?>
下面的事就比较简单了
首先肯定要生成总统演讲的界面:
<html>
<head>
<style text="text/css">
*{margin:0px; padding:0px;}
div#link{margin-left:510px; margin-top:50px; width:700px;}
a#speech{
font-family: arial; font-size:22px; color: #888888;
margin-bottom: 15px;
}
</style>
</head>
<body bgcolor="#RGB(67,65,65)">
<img src="../image/speech.jpg" style="margin-left:410px; margin-top:2px;" /><br />
<div id="link">
<?php
require_once 'readSpeech.class.php';
$readSpeech = new ReadSpeech();
$items = $readSpeech->getAllSpeech();
foreach ($items as $item)
{
echo "<a id='speech' href='speechContent.php?id={$item[0]}' target='_blank'>{$item[1]} </a><br /><br />";
}
?>
</div>
</body>
</html>
<html>
<head>
<style text="text/css">
*{margin:0px; padding: 0px;}
div#layout{margin-left: 410px; width:700px;}
span#title{font-family: arial;
font-size: 18px;
color:#eebb00;
margin-top: 20px;
margin-left: 200px; }
span#trans{position:fixed;
margin-left: 410px;
margin-top:0px;
font-family: arial;
font-size: 16px;
color:#ee00ab;
background-color: #666;
border:1px solid #eebcbc;
width:700px;
display:none;}
#content{width:720px;height:100%; border:0px ; overflow-y:scroll;margin-top:1px;
font-family: arial; font-size: 18px; color:#666;
line-height: 25px;padding:10px;}
</style>
<script type="text/javascript">
function getXMLHttpRequest()
{
var xmlhttp=null;
if(window.ActiveXObject)
{
xmlhttp = new ActiveXObject("Microsoft.XMLHttp");
}
else
{
xmlhttp=new XMLHttpRequest();
}
return xmlhttp;
}
function query(word)
{
var url="./trans.process.php?word="+word;
var xhr = getXMLHttpRequest();
if(xhr)
{
xhr.open("get", url ,true);
xhr.onreadystatechange = function()
{
if(xhr.readyState ==4 && xhr.status==200)
{
var trans = xhr.responseText;
showTrans();
$("trans").innerHTML =word+": "+ trans;
setTimeout("hiddenTrans()",5000);
}
}
xhr.send(null);
}
}
function getSelectText(event){
//捕捉选取的文本
var txt = $("content").value.substring($("content").selectionStart, $("content").selectionEnd);
var regx = /[a-z]+/i;
//截取首个单词
var word = txt.match(regx);
query(word);
}
function $(id)
{
return document.getElementById(id);
}
function showTrans()
{
var trans = $("trans");
trans.style.display="block";
}
function hiddenTrans()
{
var trans = $("trans");
trans.style.display="none";
}
</script>
</head>
<body bgcolor="#RGB(67,65,65)">
<img src="../image/speech.jpg" style="margin-left:410px; margin-top:2px;" /><br />
<span id='trans'>hello</span>;
<div id="layout">
<?php
require_once 'readSpeech.class.php';
if(!empty($_GET['id']))
{
$id = $_GET['id'];
$readSpeech = new ReadSpeech();
$result = $readSpeech->getSpeechById($id);
$content = file_get_contents($result[1]);
echo "<span id='title'>{$result[0]}</span><br />";
echo "<textarea id='content' οnselect='getSelectText();'>{$content}</textarea>";
}
?>
</div>
</body>
</html>
<!--阅读界面,可以单击或者划选不认识的单词,然后翻译揪出来了-->
/这个事控制器,回显翻译,简单吧
<?php
require_once 'format.class.php';
require_once 'sql.class.php';
if(!empty($_GET['word']))
{
$word = strtolower(trim($_GET['word']));
$sql = new Sql();
$sql->getId($word);
$trans = $sql->getMeaning();
echo $trans;
}
?>
虽然我的英语没有过6级,,不过这里充分的检验了英语6级不过如此,对于每一个没有查询到对应翻译的单词,我都反复确认过,保证不存在遗漏的问题,所以虽然1万多个单词,还是太弱了,,也难怪牛津词典会世界闻名,,也就不会觉得奇怪了