//這個功能充分檢驗了英語六級是多麼菜,如果你去聽美國總統的演講,基本是聽不懂的,因爲太多單詞不懂。 這個模塊的功能主要是,可以閱讀美國曆屆總統的演講,在遇到不懂的單詞時,可以雙加單詞,或者劃選單詞,然後,,然後,對應的翻譯就出來了,而且是秒速度。。。。
//這個英語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萬多個單詞,還是太弱了,,也難怪牛津詞典會世界聞名,,也就不會覺得奇怪了