
The term functional programming is a recurring term in all programming languages, especially in recent years. What is functional programming and how can it be applied in PHP.
Functional programming is a way of building software by combining pure functions. You treat computation as the evaluation of mathematical functions. It avoids changing state and mutable data. This approach is becoming important in PHP for several reasons. Modern web applications are becoming more complex. Functional programming offers tools to manage this complexity.
Â
Immutability
Immutability means that once a variable is set, it cannot be changed. This helps prevent unexpected behavior in your code. In traditional PHP, variables are often changed throughout a script. This can make it really hard to know exactly when and where a change happened. Immutability solves this.
Here’s a simple example:
$name = "Alice"; $newName = strtoupper($name); echo $name; // Outputs "Alice" echo $newName; // Outputs "ALICE"
In this example, strtoupper
 doesn’t change the original $name
 variable. It returns a new, uppercase string, leaving $name
 unchanged. Functional code prefers this approach.
Pure Functions
Pure functions are key to functional programming. A pure function always returns the same result for the same input and has no side effects. Side effects might include changing a global variable, writing to a database, or calling an outside API.
Here are two examples:
Pure Function:
function add(int $a, int $b): int { return $a + $b; } echo add(2, 3); // Always outputs 5
Impure Function:
$factor = 2; function multiply(int $a): int { global $factor; return $a * $factor; } echo multiply(5); // Output depends on $factor; not pure
The add
 function is pure because it only depends on its input. The multiply
 function is impure since its output depends on $factor
, which is outside its scope.
First-Class and Higher-Order Functions
In PHP, functions are first-class citizens. That means you can assign them to variables, pass them as arguments to other functions, and return them from functions. Higher-order functions take advantage of this. They are functions that accept other functions as arguments or return them.
function applyOperation(int $a, int $b, callable $operation): int { return $operation($a, $b); } function add(int $a, int $b): int { return $a + $b; } echo applyOperation(5, 3, 'add'); // Outputs 8
In this case, applyOperation
 is a higher-order function. It takes the add
 function as an argument. This ability to treat functions like any other variable is central to functional programming in PHP.
Let’s add the subtract operation:
function subtract(int $a, int $b): int { return $a - $b; } echo applyOperation(5, 3, 'subtract'); // Outputs 2
You can also pass the callable as an anonymous function (closure):
echo applyOperation(5, 3, function(int $a, int $b) { return $a * $b; });
This example can be simplified with the usage of Arrow-Functions:
echo applyOperation(5, 3, fn($a, $b) => $a * $b );
Anonymous Functions (Closures)
Anonymous functions, also known as closures, are functions without a name. You can assign them to variables and use them as callbacks. PHP’s array_map
, array_filter
, and array_reduce
, call_user_func()
, functions work well with anonymous functions.
$numbers = [1, 2, 3, 4, 5]; $squared = array_map(function($number) { return $number * $number; }, $numbers); print_r($squared); // Outputs: Array ( [0] => 1 [1] => 4 [2] => 9 [3] => 16 [4] => 25 )
Here, the anonymous function calculates the square of each number in the array. array_map
 then applies this function to every element.
Currying and Partial Application
Currying changes a function that takes multiple arguments into a sequence of functions that each take a single argument. Partial application involves pre-filling some arguments of a function. PHP doesn’t directly support currying, but you can simulate it using closures.
function add(int $a): callable { return function (int $b) use ($a): int { return $a + $b; }; } $add5 = add(5); echo $add5(3); // Outputs 8
In this example, add
 returns a new function that already has the first argument $a
 set to 5
.
Â
Recursion
Recursion means a function calls itself. This can be useful for solving problems that can be broken down into smaller, similar subproblems. Make sure your recursive functions have a base case to prevent infinite loops.
function factorial(int $n): int { if ($n <= 1) { return 1; } else { return $n * factorial($n - 1); } } echo factorial(5); // Outputs 120
This factorial
 function calls itself with a smaller value of $n
 until it reaches the base case ($n <= 1
).