Why I prefer array functions over loops
I’ve come to prefer using array functions over foreach
loops in PHP. And while the syntax isn’t as nice as in
JavaScript, I still think they work better than a ’normal’ loop.
What are array functions
In PHP you have quite some array functions, each with their own use. For this post I’m talking about the functions that loop over an array, and execute a function for each item in that array.
You can think of functions like array_reduce
, array_map
, array_filter
etc. Each of these functions does a specific thing
for each element of that array, and returns a new value.
Why use an array function
Communicate intent
I think the most important factor for me is the fact that with an array function you are communicating your intent.
The function call makes it clear what you are trying to achieve. array_filter
? You’re filtering your array. array_map
?
You are changing each element of the array, but keeping its structure. array_reduce
? You are changing your array to a new structure.
This means I can see what someone is trying to do by just reading the function call, so that reduces the mental space I need in order to understand the function
Everything happens inside the function
Everything that the array function does happens inside the function. Take a look at the next example.
In the loop part, the $newNumbers
is not part of the loop, and lives above it. While in this example its not
that big of a deal, I’ve seen the declaration of the new variable being miles away form the loop, due to refactors, and
other things happening.
$newNumbers = [];
foreach ($array as $key => $number) {
$newNumbers[$key] = $number + 2;
}
$newNumbers = array_map(
fn (int $number) => $number + 2,
$array
);
Less chance for side effects
In PHP we can write 2 type of closures. with the function($parameter) use($uses)
and the fn($parameters)
syntax.
Since the second one only allows 1 statement, the chance of having side effects is much lower already.
And in the first example, anything that isn’t passed in as a function needs to be added through the use()
.
This means we can clearly see what this loop is using. And the use
doesn’t pass values by reference (by default).
So if you change a variable in the loop, it resets again for the next iteration.
And there is no chance of accidentally overriding a variable that lives outside the loop.
$value = 3;
$new = [];
foreach ($array as $value) {
$new[] = $value +1;
}
// $value is now the last item of the array;
$value = 3;
array_map(function (int $value) {
return $value + 1;
}, $array);
// $value is still 3;
When not to use an array function
These functions aren’t always the best solution. For example, if you need to do both a filter and a map, then you
can do this in a single foreach
loop. But if you use array_filter
and array_map
, this will actually loop over the array twice.
While this probably isn’t a huge bottleneck for most applications, if you have millions of elements this can make a difference.
For example, looping over 100k elements, where the filter call filtered out 10%, I got a difference of 0.002
to 0.003
seconds in runtime
on my machine.
And sometimes you just need the function to manipulate multiple variables, and have the side effects, in that case, using a loop is probably better.
But, if you have a clear case of having to filter an array, change the elements to something else, or having to ‘reduce’ it to another structure, using an array function wil keep it more readable, maintainable, and less prone to bugs that a loop.
If you want to get notified of my next blog post, join the newsletter