2011-12-08 168 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中的文字中,你也有这些信息。这种方法非常快,但你必须提前构建倒排索引,但它比实际搜索要快得多。