Functional Programming in PHP: Advanced Level

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Functional Programming in PHP: Advanced Level

\n\n

Functional programming (FP) is a paradigm in which computation is treated as the evaluation of mathematical functions, avoiding changing state and mutable data. Although PHP was not originally designed as a purely functional language, starting from version 7.4 and especially in PHP 8.x, it has gained powerful tools for writing code in a functional style. In this article, we will explore advanced FP concepts in PHP: from higher-order functions to monads, with practical examples and recommendations.

\n\n

1. Higher-Order Functions and Closures

\n\n

Higher-order functions are functions that take other functions as arguments or return them. In PHP, this is implemented through anonymous functions (closures) and built-in functions like array_map, array_filter, array_reduce.

\n\n

Example: callback function for filtering

\n\n
<?php\n$numbers = [1, 2, 3, 4, 5, 6];\n\n// Higher-order function\n$filterEven = function(array $items, callable $callback): array {\n    $result = [];\n    foreach ($items as $item) {\n        if ($callback($item)) {\n            $result[] = $item;\n        }\n    }\n    return $result;\n};\n\n// Anonymous predicate function\n$isEven = fn($n) => $n % 2 === 0;\n\n$evenNumbers = $filterEven($numbers, $isEven);\n// Result: [2, 4, 6]\nprint_r($evenNumbers);\n?>\n
\n\n

Example: function factory (closure with state)

\n\n
<?php\nfunction createMultiplier(float $factor): callable {\n    // Closure "remembers" $factor\n    return fn($number) => $number * $factor;\n}\n\n$double = createMultiplier(2);\n$triple = createMultiplier(3);\n\necho $double(5); // 10\necho $triple(5); // 15\n?>\n
\n\n

Closures in PHP allow capturing variables from the outer scope via use (in PHP 7.4+ you can use arrow functions fn). This is the foundation for building currying and partial application.

\n\n

2. Currying and Partial Application

\n\n

Currying is the transformation of a function with multiple arguments into a sequence of functions with a single argument. Partial application is fixing a portion of a function's arguments. PHP has no built-in support, but it is easy to implement.

\n\n

Example: manual currying

\n\n
<?php\n// Regular function\nfunction add(int $a, int $b): int {\n    return $a + $b;\n}\n\n// Curried version\n$curriedAdd = function(int $a): callable {\n    return function(int $b) use ($a): int {\n        return $a + $b;\n    };\n};\n\n$addFive = $curriedAdd(5);\necho $addFive(3); // 8\n?>\n
\n\n

Example: universal currying function

\n\n
<?php\nfunction curry(callable $fn, int $arity = null): callable {\n    $reflection = new ReflectionFunction($fn);\n    $arity = $arity ?? $reflection->getNumberOfRequiredParameters();\n\n    $curry = function(...$args) use ($fn, $arity, &$curry) {\n        if (count($args) >= $arity) {\n            return $fn(...$args);\n        }\n        return function(...$nextArgs) use ($fn, $args, $arity, $curry) {\n            return $curry(...array_merge($args, $nextArgs));\n        };\n    };\n\n    return $curry;\n}\n\n$add = function(int $a, int $b, int $c): int {\n    return $a + $b + $c;\n};\n\n$curriedAdd = curry($add);\n$result = $curriedAdd(1)(2)(3); // 6\necho $result;\n?>\n
\n\n

Currying is especially useful for function composition and creating specialized versions of general functions.

\n\n

3. Function Composition and Functional Patterns

\n\n

Function composition is creating a new function by sequentially applying multiple functions. The result of one function is passed as input to the next.

\n\n

Example: left-to-right composition (pipe)

Blogs

Book Recommendations