PHP surround search text with words The requirement: search a string in a text-string (from DB) and show additional info around when presenting the result.

Examples:

text string = "The Quick Brown Fox Jumps Over the Lazy Dog"

search ==> result:


"The" ==> "The Quick ..." 
"Quick" ==> "The Quick Brown ..."
"Brown" ==> "... Quick Brown Fox ..."
"Lazy" ==> "... the Lazy Dog"
"ump" ==> "... Fox Jumps Over ..."


Rules are:


aways complete word containing search string
the word before if exists
the word after if exists
if there is something before the "before" word, show "..." at beginning
if there is something after the "after" word, show "..." at end 


How I solved it:

// initialize text
$text_found = '';
// first eliminate line feeds, tabs, double spaces etc
$tmp = str_replace(array( "\r\n", "\r", "\n", "\t", "  " ), ' ', $text );
// now get starting position
$posStart = strpos( mb_convert_case( $tmp, MB_CASE_LOWER, 'UTF-8' ), $search );
// search first space before position
$space = strrpos( substr( $tmp, 0, $posStart +1 ), ' ', -1 );
if ( $space === FALSE ):
    // no earlier space found, so start from beginning
    $posStart = 0;
else:
    $posStart = $space;
    // check if there is an additional word before
    $space = strrpos( substr( $tmp, 0, $space ), ' ', -1 );
    if ( $space === FALSE ):
        $text_found .= substr( $tmp, 0, $posStart );
    else:
        $text_found .= '... ' . substr( $tmp, $space, $posStart - $space );
    endif;
endif;
// now we search first space after position
$space = strpos( substr( $tmp, $posStart +1 ), ' ' ) + 1;
if ( $space === FALSE ):
    // no space after found, so add text till end
    $text_found .= substr( $tmp, $posStart );
else:
    // check if there is an additional word after
    $space2 = strpos( substr( $tmp, $posStart + $space + 1 ), ' ' );
    if ( $space2 === FALSE ):
        $text_found .= substr( $tmp, $posStart );
    else:
        $text_found .= substr( $tmp, $posStart, $space2 + $space + 1 ) . ' ...';
    endif;
endif;


Question is if there is a more elegance solution ?
And if so how ?

Please see post below with my final outcome.
You say you want to search a text string from a database, but are not showing the database part.  This is key to think about, as I am guessing you could cut out all this work if you made appropriate search requests against an appropriately designed data store.  Most any modern relational database supports some level of natural language search, which would allow you to actually do this across more than a single string at a time.

This is not to mention the existence of data stores both open source and commercial geared specifically towards search cases, even allowing the ability to return search matches with context as you are trying to do.

Consider doing this sort of work with a tool that is optimized for this purpose.

Thoughts on code:


You are clearly working with multibyte strings yet are not using the multibyte versions of the the standards string manipulation functions.  This could lead to unexpected behavior. If you need to have string functions overloaded with mb counterparts, you might consider a comment in the code noting that this PHP setting needs to be turned on for this code to operate properly.
you should add vertical white space to you code around logical sections to help ease of reading. Think of empty lines like you would paragraphs in writing. They help break up your thoughts.
you are casting to lowercase only on haystack and not on needle.  Why is this? Typically if you are doing case insensitive search, you would cast both in same manner.
you may consider using regex with appropriate substring pattern capture and compare from a performance standpoint. I am not sure if it will perform as well, but it could certainly simplify your code, which can sometimes holds more value if performance is not too big of a trade off.
your code isn't designed to handle multiple matches. This may be OK with regards to the design, but figured I would point this out.  You could take your example haystack and search for "the", and never get the second occurrence found.
what happens if space is passed as search string?
what happens if single character is passed or other similar trivial or ambiguous search term? Do you have something up the call stack which weeds out these potentially undesirable use cases?