Highlighting Keywords in Search Results

I am creating a search application and need some help with highlighting search terms (keywords) in retrieved document text. The application has three sections: 1) Search Form for search criteria input, 2) Search Results summary list with links, and 3) Full Document display in html. I need for the “search” term keywords from step 1 to be highlighted in the step 3 Full Document.

Here is the application code:

[php]

<?php ini_set('display_errors',1); error_reporting(E_ALL); $doctype = isset($_GET['doctype']) ? $_GET['doctype'] : ''; $search = isset($_GET['search']) ? $_GET['search'] : ''; if($search){ mysql_connect("xx", "xx", "xx") or die(mysql_error()); mysql_select_db("xx") or die(mysql_error()); $result = mysql_query( "SELECT FullDocumentID, CONCAT(ReadingNo, '-', SequenceNo) AS full_doc_number FROM Full_Documents WHERE SectionText LIKE '%$search%' AND SectionTypeID = '$doctype' Order By FullDocumentID"); $num_records = mysql_num_rows($result); // this code expects the result resource from the query to be in $result if(mysql_num_rows($result) > 0){ $links = array(); while ($row = mysql_fetch_assoc($result)){ $links[] = $row; } } } $doc = mysql_query( "SELECT SectionText FROM Full_Documents WHERE FullDocumentID = " . $_GET['FullDocumentID']); ?> .highlight_word{ background-color: yellow; }

Search Form

<form  method="get" action="" id="search_criteria"> 
    Search Term <input type="text" id="" name="search"></br> 
    Document Type <select name="doctype"></br>
        <option value="1">Text</option>
	    <option value="3">Background</option>
	    <option value="2">Reports</option>
	    <option value="4">Index</option>
    </select></br>	
    <input type="submit" name="submit" value="Submit">
</form>

<h3>Search Results</h3>

<p>for: <span style="font-size: 14px; font-weight: bold; color: red;"><? echo $search; ?></span> </p>
<p>documents found: <span style="font-size: 14px; font-weight: bold; color: red;"><? echo $num_records; ?></span></p>
<?php if($search){ if(isset($links)){ // output document links echo 'Select a document to view:
'; foreach($links as $link){ $_GET['FullDocumentID'] = $link['FullDocumentID']; // add document id to (any) existing get parameters $qs = http_build_query($_GET, '', '&'); // build the current url query string echo "{$link['full_doc_number']}
"; } } else { echo 'No matching documents found.'; } } ?>
    <h3>Document Text</h3>    

   //DOCUMENT DATA DISPLAY BEGINS HERE//

    echo "<table border='1' width='800px'>
    <tr class=\"style3\">
    ";
    while($row = mysql_fetch_array($doc))
    {
    echo "<tr class=\"style2\">";
    echo "<td style=\"width: 700px; padding: 10px;\"><p>" .     
         preg_replace("/\r\n|\r|\n/", "</p><p>", $row['SectionText']) .   
         "</p></td>";
    echo "</tr>";
    }
    echo "</table>";
    ?>

   </div> <!--END OF DOCUMENT TEXT DIV-->
</body>

[/php]

I have been looking at several highlight functions from sites on the web, and it seemed this one is relatively simple, but I don’t know if it’s workable for my need.

[php]
function highlightWords($text, $words)
{
/*** loop of the array of words /
foreach ($words as $word)
{
/
quote the text for regex /
$word = preg_quote($word);
/
highlight the words /
$text = preg_replace("/\b($word)\b/i", ‘\1’, $text);
}
/
return the text ***/
return $text;
}
[/php]

I have tried various way of integrating it with the application, but no luck. Do I understand correctly that $words are keywords from the search form and $text is the full document output in step 3 of my application?

More broadly, is this function a workable solution? Or is there something better suited to this application? Any help with this would be greatly appreciated. - Dave

$words is an array of words you want highlighted. The function should work as you expect and I see no real problems with it. Just add css rules to the highlight_word class and youre good to go

Please stop writing new code and take some time to convert what you already have to use PDO or mysqli with parameterized queries. Atm you are vulnerable to sql injection

Thanks for your feedback. I have begun converting my code as suggested.

As advised, I have converted my code to PDO and resumed working on the highlighting feature described above. I am able to highlight search keywords, but have not been able to get the full document text loaded, unless I rely on a hardcoded string (“Hello World”)

$words – These are the search keywords chosen by the user via an input form. I have this working when using the hardcoded string.

$text – This is the full document text that is chosen from a search results list (document numbers). If I don’t use the highlight function, I am able to load this document just fine, so I know the query is working, producing the appropriate FullDocID in the Business Login side of the application. In the Presentation side, I request the specific field (SectionText) that contains the document text. I wonder if that is part of the problem I am having getting this to work?

Here is the relevant section code with some of the $text variations I have tried (commented out):

[php]
try{
$dbh = new PDO(“mysql:host=$dbhost; dbname=$dbname”, $dbuser, $dbpass);
$stmt2 = $dbh->prepare(“SELECT SectionText FROM Full_Documents WHERE FullDocumentID = :fdi”);
$stmt2->bindParam(’:fdi’, $FullDocID);
$stmt2->execute();

if($stmt2 === false){
    die("Error executing the query: $sql");
}
}catch (PDOException $e){
   echo $e->getMessage();
}

// Highlight Function
    function highlightWords($text, $words)
    {
    /*** loop of the array of words ***/
    foreach ($words as $word)
    {
            /*** quote the text for regex ***/
            $word = preg_quote($word);
            /*** highlight the words ***/
            $text = preg_replace("/\b($word)\b/i", '<span class="highlight_word">\1</span>', $text);
    }
    /*** return the text ***/
    return $text;
    }

  $words = array($search); //THIS WORKS

// $text = array($row[‘SectionText’]); // this echos “Array” as string with default doc present but no new docs
// $text = $row = $stmt2->fetch(PDO::FETCH_ASSOC); //ONLY ARRAY - NO DOCUMENT BELOW
// $text = ($stmt2->fetch(PDO::FETCH_ASSOC)); // only “array” - no content
// $text = $stmt2->fetch(PDO::FETCH_ASSOC); // only “array” - no content
// $text = $stmt2->fetch(); //ARRAY STRING ONLY
// $text = $stmt2->fetch($row[‘SectionText’]); // array string Only
$text = ‘Hello World’; // This hardcoded string shows me that the highlighter works.

$text = highlightWords($text, $words);
[/php]

In the Presentation side of my code I have used the following code to test the hardcoded string (and some other much more extensive texts), to be sure it will display with highlights and styling, etc:

[php]

<? echo nl2br($text); ?>

[/php]

After I converted my code to PDO, but before trying to get the highlighting to work, the full document text was effectively presented like this:

[php]

<?php while($row = $stmt2->fetch(PDO::FETCH_ASSOC)) : ?> <?php endwhile; ?>
<?php echo nl2br($row['SectionText']); ?>
[/php]

I don’t know if the above piece of code is relevant to the $text issue. As you will notice I have tried to incorporate some of this syntax into my coding attempts above. Most of my attempts at getting the $text argument solved result in the word “array” appearing in the document area of the page. But there is no actual text content. And it is not responsive to changing the document request from the links in the search results list. I would greatly appreciate any help in sorting out how to work with the $text variable. Thanks in advance for any help provided in getting this to work.

Imploding the array makes it work:

[php]
$text = implode($stmt2->fetch(\PDO::FETCH_ASSOC));
[/php]

Sponsor our Newsletter | Privacy Policy | Terms of Service