tags:

views:

75

answers:

3

Hi I would like to limit the results returned depending on what type of product a user selects, $r[1] is the type of product with the array:

    foreach($list as $r) 
{ 
$row_color = ($row_count % 2) ? $color1 : $color2; 
$size2 = $r[2]; 
 echo "<tr>
        <td id=\"id\"><span id=\"non_sorting_header\">" .$r[0]. "</span></td>
        <td id=\"name\"><span id=\"non_sorting_header\">" .$r[1]. "</span></td>
        <td id=\"speed\"><span id=\"sorting_header\">" .kMGTB2($size2). "</span></td>
     <td id=\"download\"><span id=\"sorting_header\">" .$r[3]. " Gb<br />per month</span></td>
        <td id=\"contract\"><span id=\"sorting_header\">1<br />month</span></td>
        <td id=\"info\"><span id=\"non_sorting_header\">".$r[5]."</span></td>
        <td id=\"buy\"><span id=\"non_sorting_header\">".$r[4]."<br />".$r[6]."</span></td>
      </tr>"; 
$row_count++; 
}

So if the user enters 'banana' then the function will find all instances within the array where $r[1] starts with the word 'banana' - start is key as it could be 'banana 1' 'banana 2' etc....

I cannot figure out a slick way to do this...any help would be appreciated!

+1  A: 

You could use something like the following

function selectFromArray($prefix="", $productArray=array()) {

    return array_filter($productArray,
        create_function('$element', 
             'return (stripos($element[1],"'.$prefix.'") === 0); '));
}

Used like:

$list = selectFromArray("Banana", $list);

then proceed with the rest of your page.

That said, it's usually better to do this kind of filtering in your sql query with a WHERE clause

Jonathan Fingland
thanks for the answer, however call me dumb but I cannot get this to work with my code - get parse error - unexpected '}'
I think you need to use === otherwise you will get back matches that do not contain the prefix whatsoever ( 0 == false ).
Tom Haigh
Also $prefix will not be within the scope of the inner function.
Tom Haigh
@Bifter, there was a missing semicolon. totally my bad. @Tom. Quite right. thanks, and fixed
Jonathan Fingland
are you sure about that Tom? would the scope not expand to the outer function when it was not found?
Jonathan Fingland
get a srange error:Warning: stripos() [function.stripos]: needle is not a string or an integer
You can't create a closure in PHP < 5.3. In 5.3 you would need to use the use() construct like: function func use($prefix) { }
Tom Haigh
right again. I've edited the above to use create_function instead
Jonathan Fingland
Thanks for everyones help!!!!!!
+1 for the edits. One more thing - you could use var_export() on $prefix before you put in into the eval'd code, then you won't have problems if the string contains a single quote, and there will be less danger of code injection by someone entering a malicious search string.
Tom Haigh
Ok Tom, where would var_export() fit intothe function??
Like this: 'return (stripos($element[1],'.var_export($prefix, true).') === 0); '
Tom Haigh
One last question, then I promise to leave you all alone ;-) - If they dont enter anything, how would I get it to return all the products in the array?
put at the top: if (!strlen($prefix)) { return $productArray; }
Tom Haigh
Thanks for the assist Tom. Hugely appreciated.
Jonathan Fingland
A: 

I don't have enough rep to post a comment, but the above suggestion should work if you just put a semi-colon on the end of

return (stripos($element[1],$prefix) == 0)

so that it looks like:

return (stripos($element[1],$prefix) == 0);
miknight
@miknight: thanks, fixed.
Jonathan Fingland
A: 

I'm not sure if Jonathan's answer is really the best way to do this.

First of all, create_function() is best avoided. Even without that, though, when using a separate function for it, you're still looping through the list twice. First you loop through the entire list to filter it, and then you loop through the filtered list to print the details. You can easily combine those two:

foreach ($list as $r)
{
    if (stripos($r[1], $prefix) === 0) {
        continue;
    }

    // as before...
}

If that condition gets any more complicated you can of course split it out into a separate function as well.

mercator