PHP 搜索关键字

发布于 2024-12-20 17:12:22 字数 1925 浏览 1 评论 0原文

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

经过一系列过程后,我们获得了每个帖子的标题和标签,并将它们存储在名为 $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>';

     }
    }


}

$terms 可能包含用户为搜索输入的一些值,例如“红色汽车”;

$full 包含帖子标题和标签,所以它可能会这样说。 “红色 Vaxhaul 不太好,车辆,汽车,可怕,丑陋”

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

I have been building a PHP search facility for certain types of posts on the website (for the purpose of this please accept that mySQL is out of the question).

After a series of procedures we get the title, and the tags for each post and store them in a variable called $full.

The search terms sit in a variable called $terms

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

Both are converted to lower case.

We then want to look for similar words in $full using $terms

I tried this.

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

It works, but not quite as well as I need it to.

  • This will match similar words from the title and tags but does not deal with spaces at all. I tried removing spaces and comma, from titles and tags to no avail.
  • If the user types in someones name that is made up of two tags rather than one it will not find any results.
  • It cannot handle more than one word, let alone more than one term, both of which I want it to do.

Here is the complete script if it is of any help

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

     }
    }


}

THE VALUES

$terms may contain some values being entered by the user for a search say, 'red car';

$full contains the post title and the tags so it may say. 'The red vaxhaul is not very nice, vehicle, car, horrible, ugly'

So that should be found in that case.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不回头走下去 2024-12-27 17:12:22

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

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 相同的问题

希望有帮助

Theres a couple ways you could acheive it, I'll try and provide a few:

STRPOS

This will match red and then stop but it will also match non exact words for example car would also match cards etc..

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

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

Using 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;
}

A third approach could be to use regular expressions and preg_quote, but it would most likely have the same problem as strpos

Hope that helps

她如夕阳 2024-12-27 17:12:22

真正的搜索引擎执行此操作的方法是构建倒排索引,即以最简单的形式从每个单词到包含该单词的文档集及其出现次数的查找表。 (其中文档仅表示正在搜索的文本)在 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 中也有该信息。这种方法非常快,但你必须提前构建倒排索引,但它会比实际搜索快得多。

The way that a real search engine would go about doing this is to build an inverted index, i.e. in its simplest form a lookup table from each word to the set of documents that have that word in them and how many times. (where documents simply means the text being searched on) Pretty simple to do in 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]++;
}

after running that we have built the inverted index. Now to use it on your example the incoming query is 'red car'. split that up and look up $invertedIndex['red'] and $invertedIndex['car'] each of these will return arrays which have all documents with these words in them and how many times. To get documents with both use array_intersect to get documents with either use array_merge on the keys of these arrays:

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

Now the document index for every document with all the keywords will be in $validDocs and if you wanted to rank them by how many times the words appeared in the text you have that info too in the $invertedIndex. This method is extremely fast but you do have to build the inverted index ahead of time but it will be much much faster than actually searching.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文