Search Highlight Builder
Builds safe highlighted snippets for matched search terms.
Function signature
ogBuildSearchHighlights(content, terms = array(), max_length = 220)
Categories
- Search and Discovery
Parameters
contentSource content.termsTerms to highlight.max_lengthMaximum excerpt length.Return value
Public-safe status string returned by the function.
- success
- message
- data
Compatibility
Existing function name, slug, path, and call order preserved; advertised metadata corrected to the actual source behavior.
Minimum PHP version: 7.4
Security notes
Use caller-owned allowlists and procedural mysqli prepared execution where SQL plans are returned; validate file paths, MIME policies, and permissions before file or download workflows.
Code
<?php
/*
* Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
* Free for personal and internal use. Paid project use requires visible credit
* to Jeffery L. Paris. Corporate use requires a paid license fee unless a
* separate written license states otherwise.
*/
/**
* Builds safe highlighted snippets for matched search terms.
*
* Content is escaped before highlight markup is added. Search terms are escaped and
* applied conservatively to avoid scriptable output.
*
* @param string $content Source content.
* @param array $terms Terms to highlight.
* @param int $max_length Maximum excerpt length.
* @return array Highlighted search excerpt.
*/
function ogBuildSearchHighlights($content, $terms = array(), $max_length = 220) {
$result = array(
'success' => false,
'message' => '',
'data' => array()
);
$content = trim(strip_tags((string)$content));
$max_length = (int)$max_length;
if ($max_length < 40) {
$max_length = 40;
}
if (empty($content)) {
$result['message'] = 'Content is required.';
return $result;
}
$excerpt = $content;
if (strlen($excerpt) > $max_length) {
$excerpt = substr($excerpt, 0, $max_length);
$last_space = strrpos($excerpt, ' ');
if ($last_space !== false) {
$excerpt = substr($excerpt, 0, $last_space);
}
$excerpt = rtrim($excerpt, ' .,;:-') . '...';
}
$safe_excerpt = htmlspecialchars($excerpt, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
$clean_terms = array();
foreach ((array)$terms as $term) {
$term = trim((string)$term);
if (strlen($term) < 2) {
continue;
}
$clean_terms[] = $term;
}
usort($clean_terms, function($a, $b) {
return strlen($b) - strlen($a);
});
foreach ($clean_terms as $term) {
$escaped_term = preg_quote(htmlspecialchars($term, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'), '/');
if (!empty($escaped_term)) {
$safe_excerpt = preg_replace('/(' . $escaped_term . ')/i', '<mark>$1</mark>', $safe_excerpt);
}
}
$result['success'] = true;
$result['message'] = 'Search highlight excerpt built.';
$result['data'] = array(
'excerpt' => $safe_excerpt,
'plain_excerpt' => $excerpt,
'terms_used' => $clean_terms
);
return $result;
}