Cookies

This website uses cookies to obtain statistics from users navigation. If you go on browsing we consider you accept them.

Functional PHP

Functional programming. What is that thing some software gurus talk about? I am going to try to explain it with a basic example in PHP to show you how you can use this paradigm for your daily work, demistifying its difficulty in the process. And, yeah, you can use functional programming in PHP, well, with a PHP flavour.

What is functional programming?

The functional programming paradigm is not modern at all. It is based on Lambda Calculus. One of the first languages that allowed programming using this technique was Lisp.

Functional programming is all about functions and data structures, there are no objects in there. Pure functional programming languages do not allow mixing data with behaviour. But some pieces of this paradigm have been used since the beginning of other languages, like function pointers in C. Usually, pure functional languages like Haskell have capabilities that are out of the scope of this post, like Currying, Pattern Matching and Lazy Initialization.

Given it is usually difficult to understand, we are going to show an example of functional programming using PHP. The example in this post is quite simple, and it solves a mundane problem using functional programming, filtering a collection or array.

An example

<?php

function index_and_value_are_even($arr)
{
    $result = [];
    foreach($arr as $index => $value) {
        if ($value % 2 == 0 && $index % 2 == 0) {
            $result[$index] = $value;
        }
    }

    return $result;
}

var_export(index_and_value_are_even([1, 2, 3]));

This code fragment exports an empty array, provided the array values and indices are not even in any element.

In many applications, pieces of code like these can be found, traversing a collection and applying a filter over it is a common task. It is not a bad way to solve the problem, it is simple, standard and easy, but if we solve it like this, we have to write tons of syntax that we actually don't need, repeating the same pattern over and over again and, in real world applications, the problem solved by the foreach body isn't usually just like in the example, it can also be a cumbersome piece of code.

Let's see how this function would be implemented using the functional paradigm.

<?php
function is_even($n)
{
    return $n % 2 == 0;
}

function index_and_value_are_even($arr) {
    return array_filter($arr, function($index, $value) {
        return is_even($index) && is_even($value);
    });
}

Isn't this solution much better? It's obviously a subjective matter but in my opinion the code is more expressive using functional programming.

Even though this piece of code is incorrect. array_filter native function doesn't send the index to the called filter function. This can make this function useless for your needs, more if the array keys have a meaning in your application. But, we are programmers, aren't we? Let's do our own implementation.

<?php

function array_filter_with_indices(array $arr, callable $fn)
{
    $result = [];
    foreach($arr as $key => $value) {
        if ($fn($key, $value)) {
            $result[$key] = $value;
        }
    }

    return $result;
}

Yes, it's a pretty straightforward implementation. Now we can reuse this filter function applying an anonymous function over it to decide which elements fulfill the provided conditions. This implementation also preserves the original indices, not like the native array_filter.

<?php
['1' => 'value1', 'abc' => 'value3', ...]

Another thing of note in this code is that it uses Type Hinting, a mechanism to check if the function arguments belong to the type the function expects. As you can see, it's possible to type hint an argument as callable. This kind of type hinting has been added in version 5.4, so check this before you decide to use it in your application.

I hope you've got the gist of this technique. Don't mind using it in real world applications!!