PHP is a great little language with a lot of neat functions to help you manipulate arrays and strings. It’s obvious why it is one of the more popular languages for developing on the backend of web sites.
Often I find myself needing to wrap an array of strings in a list of HTML or XML elements, and as far as I am aware, whilst PHP can do all sorts of wonderful tricks, this is one of those functions that seems to be sorely missing.
For the easiest solution to this problem, check the bottom of this article, otherwise, read on to learn.
On the PHP.net website there are a multitude of solutions to this problem, many of which I have tried out myself or figured out myself.
I particularly like this one I came up with using the new closure ability of PHP 5.3:
function implode_wrap($glue, $before, $after, $array)
{
array_walk($array,
function(&$array) use ($before, $after)
{
$item= $before . $item . $after;
}
);
return implode($glue, $array);
}
But it needs to do an awful lot of processing for something so simple and in the process alters the original array of strings. Not a good side effect to have lurking in your code.
And this I thought clever, which is taken directly from PHP.net :
function implode_wrapped($before, $after, $glue, $array)
{
$output = '';
foreach($array as $item)
{
$output .= $before . $item . $after . $glue;
}
return substr($output, 0, -strlen($glue));
}
Which performs the implode by iterating over the array, and then cutting off the final few characters of the compiled string. Very neat.
There’s several more solutions if you want to visit the website, some of the solutions are quite clever and some of them quite elegant, but they all seem to miss the fact that PHP practically hands you solution.
The PHP implode()
function will convert an array of text strings in to one long string, each element in the array separated by whatever glue characters you want.
To illustrate this, the code:
implode(", ", array(1, 2, 3, 4, 5));
will return a text string of:
1, 2, 3, 4, 5
which has effectively taken each integer element in the array and joined it together in one long string, separating each element by a comma followed by a space. Notice that the fifth and final element is not followed by a comma. A neat little function that.
However, what to do if I want to convert the same list of integers in to an ordered list wrapped in the appropriate HTML tags? If I try using the implode()
function with the LI tags, I won’t receive the output I expect.
implode("<li></li>", array(1, 2, 3, 4, 5));
produces:
1<li></li>2<li></li>3<li></li>4<li></li>5
Not quite what I want.
How about if I reverse the tags?
implode("</li><li>", array(1, 2, 3, 4, 5));
Now I get:
1</li><li>2</li><li>3</li><li>4</li><li>5
Closer, but still no cookie.
Ah, but how about?
"<li>" . implode("</li><li>", array(1, 2, 3, 4, 5)) . "</li>"
And the output becomes:
<li>1</li><li>2</li><li>3</li><li>4</li><li>5</li>
Which is perfect, exactly what I wanted.
A few final touch ups will make the output perfect:
"<ol>\n<li>” . implode(“</li>\n<li>”, array(1, 2, 3, 4, 5)) . “</li>\n</ol>";
Produces:
<ol>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ol>
Perfect output!
Let’s turn that in to a reusable function:
function implode_wrap($glue, $before, $after, $array)
{
return $before . implode($after . $glue . $before, $array) . $after);
}
And I can call it with:
“<ol>\n” . implode_wrap(“\n”, “<li>”, “</li>”, array(1, 2, 3, 4, 5)) . “\n</ol>”;
Which will produce the output:
<ol>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ol>
The standard implode()
function of PHP is used to join an array of strings together, separated by the specified glue, before and after strings, which in this case are the HTML tags for representing a list of items.
I also stated that between each list item a new line should be output to make it easy to read for a human being examining the output.
Once implode()
has done its job, I stick the before and after strings around the resulting output from implode()
so that the entire string is wrapped correctly. Remember that implode()
does not place the glue string after the last item in the list. Without wrapping before and after around the result our output looks like the second listing of 1<li></li>2<li></li>3<li></li>4<li></li>5
.
With all of the list item tags now properly opened and closed, I can finally wrap that output in the HTML tags that denote an ordered list.
The elegance of this solution is that it is a single line of code, which can be wrapped in a function, and if you understand how implode()
works, then you inherently understand how the new implode_wrap()
function works too. The speed difference, and amount of additional code, between this solution and the native PHP implode()
function is negligible.