Why I prefer array functions over loops

Aug 12, 2024·
Gert de Pagter
Gert de Pagter
· 3 min read

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