Tach!
foreach (explode(" ", utf8_decode($userquery)) as $query) {
Welche Bewandnis hat das utf8_decode() hier? Damit gehen dir potentiell Zeichen verloren. Wenn du UTF-8 haben willst, mit allem drum und dran, dann solltest du nicht in eine "geringere" Kodierung umkodieren.
if (preg_match("/" . $query . "/i", $text, $match)) {
stripos() würde das Ergebnis kostengünsiger liefern.
$text = str_replace($match[0], "<span class='highlight'>" . $match[0] . "</span>", $text);
Aber beide Zeilen brauchst du nicht. Zudem fehlt die Beachtung des Kontextwechsels beim Einsetzen der Benutzereingabe in den HTML-Code.
nun bekomme ich als Antwort das hier:
<span class='high<span class='highlight'>li</span>ght'>vari</span>able <span class='highlight'>li</span>ghte
Und wie man sieht wurde da der HTML Code falsch ersetzt.
Ja, so arbeitet str_replace(), sowohl wenn man es wiederholt auf den bereits ersetzten Text anwendet, also auch wenn man die Array-Variante nimmt. Die Funktion strtr() in ihrer zweiten Variante kann das besser.
Du brauchst zunächst ein Array, bestehend aus den Suchtextteilen als Keys und den Ersatztexten als Werte. Das kannst du in der foreach-Schleife erzeugen (htmlspecialchars() nicht vergessen und das utf8_decode() weglassen). Anschließend ein strtr()-Aufruf und alles wird gut.
Dummerweise arbeitet strtr() nicht case-insensitive. Es gibt aber in den Userkommentaren eine solche Version. Probier aber mal, ob sie ebenfalls wie strtr() das bereits Ersetzte in Ruhe lässt.
dedlfix.