Kevin Beal
Kevin Beal

Reputation: 10858

How do I not run code in loop for items producing "Undefined offset: 0"?

I'm trying to create my own search engine for a site I'm working on and I'm through the "title" and "description" field from a DB table containing a keyword and displaying the results. That works fine, but I wanted to get the page to display only the text around that keyword in the "description" result. I found a some code on StackOverflow (w00t!) to do this:

$string = $s->description;
$word = $item;
preg_match("/(\w+)? ?(\w+)? ?(\w+)? ?(\w+)? ?(\w+)? ?$word ?(\w+)? ?(\w+)? ?(\w+)? ?(\w+)? ?(\w+)?/i",$string,$result);
$description = preg_replace("/$word/","<B>$word</B>",$result[0]);

The problem is that this produces:

A PHP Error was encountered
Severity: Notice
Message: Undefined offset: 0
Filename: search/search.php
Line Number: 21

Line #21:

$description = preg_replace("/$word/","<B>$word</B>",$result[0]);

(From the above code.) But it only does this for some of the results. I haven't figured out what the bad ones have in common yet, but it's like 1 in 4 that don't work.

The solution I tried was to do a check in my foreach loop to see if the variable $description isset(). (Nice pun huh?)

if( !isset($description) ) {
    if(strlen($s->description) > 200) { 
        $description = substr($s->description, 0, 200).'...'; 
    } else { 
        $description = $s->description; 
    } 
}

Otherwise the variable is already defined above. This however does nothing different than doing no check and just echo-ing out $description as it is defined up top (producing the error).

I have searched "undefined offset: 0" and got a little overwhelmed by the programming terminology (of which I am only beginning to understand now).

I would greatly appreciate some kind of check that actually works or an alternative, because this is confusing the heck out of me.

Upvotes: 1

Views: 109

Answers (1)

Moak
Moak

Reputation: 12885

I'm not sure I understand the second part of the question correctly, but I can suggest this to get rid of the notice

$string = $s->description;
$word = $item;
if(preg_match("/(\w+)? ?(\w+)? ?(\w+)? ?(\w+)? ?(\w+)? ?$word ?(\w+)? ?(\w+)? ?(\w+)? ?(\w+)? ?(\w+)?/i",$string,$result)){
    $description = preg_replace("/$word/","<B>$word</B>",$result[0]);
}

By putting preg_match into the if condition, it will only assign description if a match was found.

$result will be an empty array() if no matches are found in other words, so there will be no value for $result[0] which would trigger your notice

Also, because $ has a special meaning in regular expressions I would take the variable out of the quotes to be "/(\w+)? ?(\w+)? ?(\w+)? ?(\w+)? ?".$word." ?(\w+)? ?(\w+)? ?(\w+)? ?(\w+)? ?(\w+)?/i" etc. Also make sure to use preg_quote() on $word when using user input in regular expressions, they tend to break unexpectedly

Upvotes: 4

Related Questions