HOWTO Combine array_filter() and create_function() in PHP
October 15th, 2007In PHP, to successively filter data in one array based on some data in each row of another, array_filter() can be combined with create_function().
The function array_filter() takes the array to be filtered as its first argument, and a callback function as its second. The callback function is a function with one parameter, which is also the array to be filtered; it is applied to each element, and if it returns false for a particular element, that element is filtered out of the result set.
The function create_function() creates an anonymous function and returns a unique function name as a string. As its first parameter, create_function() takes a string which is a comma-separated list of arguments (in our case, a single parameter $a). The second parameter is the body of the function, as a string.
In the example below, we have an array $people (a list of people) and an array $hobbies (a list of hobbies). There is a one to many relationship from $people to $hobbies on ($people['id'], $hobbies['person_id']). We want to filter the $hobbies array for each person, and display those results along with the data for each person.
$people = array();
$hobbies = array();
array_push($people, array('id' => 1, 'name' => 'Ryan', 'gender' => 'male'));
array_push($people, array('id' => 2, 'name' => 'Helen', 'gender' => 'female'));
array_push($people, array('id' => 3, 'name' => 'Riley', 'gender' => 'male'));
array_push($hobbies, array('person_id' => '1', 'hobby' => 'guitar'));
array_push($hobbies, array('person_id' => '1', 'hobby' => 'programming'));
array_push($hobbies, array('person_id' => '1', 'hobby' => 'bad jokes'));
array_push($hobbies, array('person_id' => '2', 'hobby' => 'painting'));
array_push($hobbies, array('person_id' => '2', 'hobby' => 'singing'));
array_push($hobbies, array('person_id' => '2', 'hobby' => 'complaining'));
array_push($hobbies, array('person_id' => '3', 'hobby' => 'babbling'));
array_push($hobbies, array('person_id' => '3', 'hobby' => 'drooling'));
array_push($hobbies, array('person_id' => '3', 'hobby' => 'laughing'));
array_push($hobbies, array('person_id' => '3', 'hobby' => 'crying'));
foreach ($people as $person) {
// Build the function body, which evaluates if $a['person_id'] == $person['id'],
// where $person['id'] is a value replaced for each iteration of people
$fxBody = 'return $a[\'person_id\'] == '. $person['id'] . ';';
// Create the anonymous function
$filter = create_function('$a', $fxBody);
// Apply the filter
$filteredHobbies = array_filter($hobbies, $filter);
// Show our results
echo "<h2>{$person['name']}, a {$person['gender']}, enjoys:</h2>";
foreach ($filteredHobbies as $hobby) {
echo "{$hobby['hobby']}<br />";
}
}
And of course, a working example.
