ccterran(原作) 作者:iwind 朋友用dreamweaver做了一個網站,沒有動態的內容,只是一些個人收藏的文章,個人介紹等等。現在內容比較多了,想叫我幫他做一個搜索引擎。說實在的,這是一個不難的問題,于是就隨手做了一個。現在我在其它論壇上也看到有人想做這個,于是就想說說這方面的知識,重在了解一下方法。 寫程序前先要想好一個思路,下面是我的思路,可能誰有更好的,但注意這只是一個方法問題 :遍歷所有文件 讀取內容 搜索關鍵字,如果匹配就放入一個數組 讀數組。在實現這些步驟之前,我假定你的網頁都是標準的,就是有標題(<title></title>),也有(<bod *></body>),如果你是用dreamweaver或者frontpage設計的,那么除非你故意刪掉,它們都在存在的。下面就讓我們一步步來完成并在工程中改善這個搜索引擎。 一,設計搜索表單 在網站的根目錄下建個search.htm,內容如下 <html> <head> <title>搜索表單</title> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> </head> <body bgcolor="#FFFFFF" text="#000000"> <form name="form1" method="post" action="search.php"> <table width="100%" cellspacing="0" cellpadding="0"> <tr> <td width="36%"> <div align="center"> <input type="text" name="keyword"> </div> </td> <td width="64%"> <input type="submit" name="Submit" value="搜索"> </td> </tr> </table> </form> </body> </html> 二,搜索程序 再在根目錄下建個search.php 的文件,用來處理search.htm表單傳過來的數據.內容如下 <?php //獲取搜索關鍵字 $keyword=trim($_POST[“keyword”]); //檢查是否為空 if($keyword==””){ echo”您要搜索的關鍵字不能為空”; exit;//結束程序 } ?>
這樣如果訪問者輸入的關鍵字為空時,可以做出提示。下面是遍歷所有文件。 我們可以用遞歸的方法遍歷所有的文件,可以用函數opendir,readdir,也可以用PHP Directory的類。我們現在用前者. <?php //遍歷所有文件的函數 function listFiles($dir){ $handle=opendir($dir); while(false!==($file=readdir($handle))){ if($file!="."&&$file!=".."){ //如果是目錄就繼續搜索 if(is_dir("$dir/$file")){ listFiles("$dir/$file"); } else{ //在這里進行處理 } } } } ?> 在紅字的地方我們可以對搜索到的文件進行讀取,處理.下面就是讀取文件內容,并檢查內容中是否含有關鍵字$keyword,如果含有就把文件地址賦給一個數組。 <?php //$dir是搜索的目錄,$keyword是搜索的關鍵字 ,$array是存放的數組 function listFiles($dir,$keyword,&$array){ $handle=opendir($dir); while(false!==($file=readdir($handle))){ if($file!="."&&$file!=".."){ if(is_dir("$dir/$file")){ listFiles("$dir/$file",$keyword,$array); } else{ //讀取文件內容 $data=fread(fopen("$dir/$file","r"),filesize("$dir/$file")); //不搜索自身 if($file!=”search.php”){ //是否匹配 if(eregi("$keyword",$data)){ $array[]="$dir/$file"; } } } } } } //定義數組$array $array=array(); //執行函數 listFiles(".","php",$array); //打印搜索結果 foreach($array as $value){ echo "$value"."<br>\n"; } ?> 現在把這個結果和開頭的一段程序結合起來,輸入一個關鍵字,然后就會發現你的網站中的相關結果都被搜索出來了。我們現在在把它完善一下。 1,列出內容的標題 把 if(eregi("$keyword",$data)){ $array[]="$dir/$file"; } 改成 if(eregi("$keyword",$data)){ if(eregi("<title>(.+)</title>",$data,$m)){ $title=$m["1"]; } else{ $title="沒有標題"; } $array[]="$dir/$file $title"; } 原理就是,如果在文件內容中找到<title>xxx</title>,那么就把xxx取出來作為標題,如果找不到那么就把標題命名未”沒有標題”. 2,只搜索網頁的內容的主題部分。 做網頁時一定會有很多html代碼在里面,而這些都不是我們想要搜索的,所以要去除它們。我現在用正則表達式和strip_tags的配合,并不能把所有的都去掉。 把 $data=fread(fopen("$dir/$file","r"),filesize("$dir/$file")); //不搜索自身 if($file!=”search.php”){ //是否匹配 if(eregi("$keyword",$data)){ 改為 $data=fread(fopen("$dir/$file","r"),filesize("$dir/$file")); if(eregi("<body([^>]+)>(.+)</body>",$data,$b)){ $body=strip_tags($b["2"]); } else{ $body=strip_tags($data); } if($file!="search.php"){ if(eregi("$keyword",$body)){ 3,標題上加鏈接 foreach($array as $value){ echo "$value"."<br>\n"; } 改成 foreach($array as $value){ //拆開 list($filedir,$title)=split(“[ ]”,$value,”2”); //輸出 echo "<a href=$filedir>$value</a>"."<br>\n"; } 4防止超時 如果文件比較多,那么防止PHP執行時間超時是必要的。可以在文件頭加上 set_time_limit(“600”); 以秒為單位,所以上面是設10分鐘為限。 所以完整的程序就是 <?php set_time_limit("600"); //獲取搜索關鍵字 $keyword=trim($_POST["keyword"]); //檢查是否為空 if($keyword==""){ echo"您要搜索的關鍵字不能為空"; exit;//結束程序 } function listFiles($dir,$keyword,&$array){ $handle=opendir($dir); while(false!==($file=readdir($handle))){ if($file!="."&&$file!=".."){ if(is_dir("$dir/$file")){ listFiles("$dir/$file",$keyword,$array); } else{ $data=fread(fopen("$dir/$file","r"),filesize("$dir/$file")); if(eregi("<body([^>]+)>(.+)</body>",$data,$b)){ $body=strip_tags($b["2"]); } else{ $body=strip_tags($data); } if($file!="search.php"){ if(eregi("$keyword",$body)){ if(eregi("<title>(.+)</title>",$data,$m)){ $title=$m["1"]; } else{ $title="沒有標題"; } $array[]="$dir/$file $title"; } } } } } } $array=array(); listFiles(".","$keyword",$array); foreach($array as $value){ //拆開 list($filedir,$title)=split("[ ]",$value,"2"); //輸出 echo "<a href=$filedir target=_blank>$title </a>"."<br>\n"; } ?>
到此為止,你已經做好了自己的一個搜索引擎,你也可以通過修改內容處理部分來改進它,可以實現搜索標題,或者搜索內容的功能。也可以考慮分頁。這些都留給你自己吧。 這里說明一下用preg_match代替eregi,會快很多。這里只是為了通俗易懂,所以使用了常用的eregi.
|