Hi all,

I'm currently putting together a search engine for my website, and so far, everything is going pretty smoothly.

The only thing left that I would like to do is when the search results are displayed, I want to be able to highlight the search term entered in the page that displays the results of the query.

For example, if I search for the term "dog grooming", here is a possible result, with the term "dog grooming" bolded:

"Acme Dog Grooming offers the finest and most affordable dog grooming service in your area. Contact us at (555)123-4567 for more details".

Below is a class that I am using, and would like to know how I can modify it so that I can highlight the search term entered. In the code below, the variable $_POST['searchbox'] is the search term being entered and what I'd like to hightlight.

class SearchAboutMe extends Search{
        public function __construct()
        {

            $db = new PDO(### Database connection details ###);
            $q = $db->prepare(" SELECT something FROM somewhere WHERE somecolumn LIKE ? ");
            $q->execute(array('%'.$_POST['searchbox'].'%')); ### Here the query is being executed
            $q->setFetchMode(PDO::FETCH_ASSOC);

            $r = $q->fetch();
            $this->username = $r['username'];
            $this->city = $r['city'];
            $this->state = ucwords(strtolower($r['state']));
            $this->zipcode = $r['zip'];
            $this->info = $r['info'];

            ### Here is where the search results get displayed

            $count = $q->rowCount();
            if($count >= 1){

            ### Results were found for search term, and the search term is contained somewhere inside
            ### the $this->info property

                echo "<div class=results>
                      <a href=". $this->username .">" . $this->info . "</a></div>";
            }else{
                 $count == 0;
                 echo "<div class=\"alert alert-error\"><button type=\"button\" class=\"close\" data-dismiss=\"alert\">×</button>No results found for: <strong> " . $_POST['searchbox'] . "</strong></div>";
            }
        }
}

So in the example code above, the property $this->info will contain the search term ($_POST['searchbox']). How can I extract the search term from it?

Thanks very much for any help!

Dani AI

Generated

Good quick fix from — the simple replace that implemented is a perfectly fine, minimal solution for exact, case-sensitive matches. It’s worth calling out the common pitfalls you’ll hit as you make the search UI more robust: case-insensitivity, phrase vs. token matching, accidental highlighting inside HTML tags or attributes, multibyte (UTF-8) text, overlapping/partial matches (e.g. cat vs caterpillar) and XSS/sanitization concerns when results contain user-supplied HTML.

If you want something more robust but still straightforward, split the result HTML into “tag” vs “text” chunks, only run replacements on text chunks, build a safe regex from the search terms (use preg_quote), sort terms by length (longest first) to avoid partial matches, and use the i + u flags for case-insensitive Unicode matching. Example function (works on HTML or on escaped/plain text):

function highlight_terms_in_html($html, $query){
    $query = trim($query);
    if ($query === '') return $html;

    $terms = preg_split('/\s+/u', $query, -1, PREG_SPLIT_NO_EMPTY);
    usort($terms, function($a,$b){ return mb_strlen($b,'UTF-8') - mb_strlen($a,'UTF-8'); });
    $pattern = '/(' . implode('|', array_map(function($t){ return preg_quote($t,'/'); }, $terms)) . ')/iu';

    $parts = preg_split('/(<[^>]+>)/', $html, -1, PREG_SPLIT_DELIM_CAPTURE);
    $skipTags = array('script','style','noscript'); $skip = false; $openTag = '';
    foreach ($parts as $i => $part) {
        if ($part === '') continue;
        if ($part[0] === '<') {
            if (preg_match('/^<\s*\/\s*([a-z0-9:-]+)/i',$part,$m)) {
                $tag = strtolower($m[1]); if ($skip && $tag === $openTag) { $skip = false; $openTag = ''; }
            } elseif (preg_match('/^<\s*([a-z0-9:-]+)/i',$part,$m)) {
                $tag = strtolower($m[1]); if (in_array($tag,$skipTags)) { $skip = true; $openTag = $tag; }
            }
            continue;
        }
        if ($skip) continue;
        $parts[$i] = preg_replace_callback($pattern, function($m){ return '<strong>' . $m[0] . '</strong>'; }, $part);
    }
    return implode('', $parts);
}

Usage notes: if $this->info is plain text, echo highlight_terms_in_html(htmlspecialchars($this->info, ENT_QUOTES, 'UTF-8'), $_POST['searchbox']);. If it contains HTML you want to preserve, sanitize allowed tags first (e.g. HTMLPurifier or an allowlist) then pass the raw HTML into the function. For older PHP (pre-5.3) replace closures with named callbacks. Consider using <mark> or a .highlight span for styling instead of <strong> if you want purely visual emphasis.

Recommended Answers

All 4 Replies

I suggest you do a str_replace, replacing the searched text with the searched text pre-/appended with the bold tag, in the info field.

Thank you pritaeas, let me make sure I am understanding correctly.

Are you are suggesting that I do something like this:

str_replace($_POST['searchbox'],$this->info,"<strong>" . $_POST['searchbox'] . "</strong>")

Nevermind, got it working thanks to pritaeas for the idea...you are awesome!

Just in case this might help someone else, here is the final code:

I replaced this in the original code:

 if($count >= 1){
### Results were found for search term, and the search term is contained somewhere inside
### the $this->info property
echo "<div class=results>
<a href=". $this->username .">" . $this->info . "</a></div>";
}

with this below:

        if($count >= 1){
            $result = str_replace($_POST['searchbox'], "<strong>" . $_POST['searchbox'] . "</strong>", $this->info);
            echo $result;
        }
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.