Functions Beget Functions

When web programming in PHP it’s not often that you get to delve into the functional-style, but when you do, the moment is truly glorious! 🙂 Here’s a problem I ran into recently: I wanted a string containing the current post tags but with each prefixed by another string (e.g. our friend the octothorpe ‘#’) and delimited by another string (e.g. a space).

Here’s how we get the tags of the current post:

$tags = get_the_tags($post->ID);

This however returns an array of tag objects. We want a new array that contains only the tag names, but prefixed by a string. For that, we’ll turn to the array_map function:

$tags = array_map(prefix_tag_f('#'), $tags));

The magic happens when array_map calls at run-time our own function prefix_tag_f. This function returns another function (an anonymous one) that actually does the work for array_map. (Note: you’ll need at least PHP 5.3 to use anonymous functions this way.)

function prefix_tag_f($prefix = '') {
$f = function($a) use($prefix) {
return $prefix . $a->name;
};
return $f;
}

Using this function, we pass the desired prefix for each tag name when asked for by the array_map function as it iterates over each item in the array. Viola!

I prefer this method of function-passing to using the function name as a string. It’s much more elegant and adaptable in other situations.

Now that we’ve got our list of tags prefixed with a ‘#’, we can use implode to get our space-delimited string of tag names:

$tagstring = implode(' ', $tags);

Nice!

Leave a Reply