2011-12-08 207 views
0

我一直在建立對某些類型的網站上發佈了一個關於PHP搜索工具(本作的目的,請接受MySQL是不可能的)。PHP搜索關鍵字

經過一系列的程序,我們獲得了冠軍,併爲每個崗位的標籤並將其存儲在一個名爲$full變量。

搜索字詞坐在稱爲$terms

$full = $title . ' ' . $tago[$result->ID]; 

兩者都轉換爲小寫變量。

然後,我們想用$terms

我想這對尋找類似的話在$full

$final = strpos($full,$terms); 

它的工作原理,但不是我所需要的。

  • 這將匹配來自標題和標籤的類似單詞,但根本不處理空格。我嘗試刪除空格和逗號,從標題和標籤無濟於事。
  • 如果用戶在某人的名字是由兩個標籤,而不是一個不會找到任何結果的。
  • 它不能處理超過一個字,更不用說超過一個任期,這兩個我想要它做的。

下面是完整的劇本,如果它是有幫助

$proto = $_GET['p']; 
$terms = $_GET['s']; 

$terms = strtolower($terms); 
$terms = str_replace(' ', '', $terms); 

$ids = array(); 

if($proto == 'inline') { 

    $search = get_posts('post_type=post&post_status=publish'); 

    foreach($search as $result) { 

     $title = get_the_title($result); 

     $tags = wp_get_post_tags($result->ID); 

     foreach($tags as $tag){ $tago[$result->ID].= $tag->name;} 

     $full = $title . ' ' . $tago[$result->ID]; 
     $full = strtolower($full); 
     $final = strpos($full,$terms); 


     if($final != false){ 

      $ids[] = $result->ID; 

     } 

    } 
    if ($ids[0] == '') { 
     echo '<div align="center" style="text-align:center; color:#FFF;">No Results Found</div>'; 
    return false; } else { 
    $args = array('post__in' => $ids); 

    $srs = get_posts($args); 

    foreach($srs as $sr) { 

    echo '<a href="'.$sr->post_slug.'"><img src=""/><b>'.$sr->post_title.'</b>'. $tago[$result->ID].'<span>'.date('dS M Y', strtotime($sr->post_date)).'</span></a>'; 

    } 
    } 


} 

$條款可能包含某些值由用戶輸入的搜索說,「紅車」 ;

$完全包含文章標題和標籤,因此可能會說。 「紅色vaxhaul是不是很好,車輛,汽車,可怕,醜陋」

所以應該在這種情況下被發現。

+0

你可以舉一個你想要它找到的例子,顯示$ full和$ terms的值可能會更容易爲你創建一個解決方案 –

+0

@Jason完成更新 –

回答

0

即使世界,你可以acheive這幾種方法,我會盡力提供一些:

STRPOS

這將匹配紅色,然後停止,但它也將匹配,例如非原話車也將匹配卡等。

$words = explode(' ', $terms); 

foreach ($words as $word) 
{ 
    if (false !== strpos()) { 
     $ids[] = $result->ID; 
    } 
} 

使用數組INTERSEC

//create an array of searched terms 
$words = explode(' ', $terms); 

//remove non letter numbers 
$fullClean = preg_replace('/[^a-z\d\s]/', '', $full); 

//Create an array of words 
$criteria = explode(' ', $fullClean); 

//find if any elements of $words exist in $criteria 
if (count(array_intersect($words, $criteria))) { 
    $ids[] = $result->ID; 
} 

第三種辦法可能是使用正則表達式和preg_quote,但它最有可能也有同樣的問題,因爲strpos

希望幫助

0

,一個真正的搜索引擎會去這樣做的方式這是建立一個倒排索引,即以最簡單的形式從每個單詞到包含該單詞的文檔集以及多少次的查找表。 (其中的文件只是意味着被搜索的文本)很簡單的PHP做:

foreach($documents as $docIndex => $documentText) { 
    //remove all types of punctuation and other characters here 
    $documentText = str_replace(array(',','.','?','!'),"",$documentText); 
    $words = explode(" ",$documentText); 
    foreach($words as $word) $invertedIndex[$word][$docIndex]++; 
} 

運行,我們已經建立倒排索引之後。現在在你的例子中使用它,傳入的查詢是'紅色汽車'。將其分開並查找$ invertedIndex ['red']和$ invertedIndex ['car'],其中每一個都會返回包含所有包含這些單詞的文檔以及多少次的數組。要獲得都使用array_intersect文件,以獲得與要麼使用array_merge這些陣列上的按鍵文件:

foreach($keywords as $count => $keyword) { 
    if($count == 0) $validDocs = keys($invertedIndex[$keyword]); 
    $validDocs = array_intersect(keys($invertedIndex[$keyword]),$validDocs); 
} 

現在的文件索引的所有關鍵字的每個文檔將在$ validDocs,如果你想排名他們的文字出現在$ invertedIndex中的文字中,你也有這些信息。這種方法非常快,但你必須提前構建倒排索引,但它比實際搜索要快得多。