Filtering Array Elements in PHP Using an Anonymous Function


== UPDATE ==
This is now basically obsolete thanks to PHP 5.3’s closures

I’ve used PHP’s array_filter() in the past to filter elements from an array, but occasionally I find that I need to pass an additional value to the function in order to determine whether to keep the element. This just came up in a case where I was using GET variables to filter search results on a large array.

I have a large 2D array of books where each record has some information such as title, author, publisher, ISBN, etc. I include search boxes for each column when I draw the table to the screen, so the user can search a specific column for some text.

<?php
$data = array(
    0 => array('Title' => "Career and Life Planning",  'Author' => "Michel Ozzi",      'ISBN' => "978-0-07-284262-3"),
    1 => array('Title' => "Beginning Algebra",         'Author' => "Blitzer",          'ISBN' => "978-0-555-03971-7"),
    2 => array('Title' => "Primary Flight Briefing",   'Author' => "Federal Aviation", 'ISBN' => "978-1-5602755-7-2")
);
 
foreach( $_GET as $k=>$v )
{
	$data = array_filter($data, create_function('$data', 'return ( stripos($data["'.$k.'"], "'.$v.'") !== false );'));
}
 
?>

Notice the values of $k and $v are actually written into the PHP code, whereas $data is written to the function as a variable name. If you were to echo the body of the function, it would actually look something like this:

return ( stripos($data["ISBN"], "555") !== false );

In each iteration of the loop the function is re-created, and the key/value pair are essentially hard-coded into the function instead of being variables.

So there you go! A real-live use for anonymous functions in PHP!

, , , ,

  1. #1 by Paul on February 9th, 2009

    You can achieve the same functionality about 10x faster using static variables.

    foreach ($_GET as $k => $v) {
    filterer($k, $v);
    $data = array_filter($data, ‘filterer’);
    }

    function filterer($var, $val = false) {
    static $key, $value;
    if ($val) {
    $key = $var;
    $value = $val;
    return;
    }
    return strpos($var[$key], $value) !== false;
    }

  2. #2 by Paul on February 9th, 2009

    I was testing with a filter set that returned no results O.O it’s still about 2x faster.

(will not be published)

  1. No trackbacks yet.