PHP搜索关键字

时间:2011-12-08 14:29:29

标签: php search strpos

我一直在为网站上的某些类型的帖子构建一个PHP搜索工具(为了这个目的,请接受mySQL是不可能的)。

在一系列程序之后,我们获得每个帖子的标题和标签,并将它们存储在名为$full的变量中。

搜索字词位于名为$terms

的变量中
$full = $title . ' ' . $tago[$result->ID];

两者都转换为小写。

然后,我们希望使用$full

$terms中查找类似的字词

我试过了。

$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>';

     }
    }


}

价值观

$ terms可能包含用户为搜索输入的一些值,例如'red car';

$ full包含帖子标题和标签,所以它可能会说。 '红色vaxhaul不是很好,车辆,汽车,可怕,丑陋'

所以应该在那种情况下找到。

2 个答案:

答案 0 :(得分:0)

Theres有几种方法可以实现它,我会尝试提供一些:

<强> STRPOS

这将匹配红色然后停止,但它也会匹配非确切的单词,例如汽车也会匹配卡等。

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

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

使用Array 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具有相同的问题

希望有所帮助

答案 1 :(得分: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中也会有这些信息。这种方法非常快,但你必须提前构建倒排索引,但它比实际搜索要快得多。