The State of Functional Programming in PHP 5.3.x

A few weeks ago, I started looking into the possibility of functional programming in PHP. I stumbled across the capability of defining anonymous functions — starting with PHP 5.3.0. These can be used to define closures with bound variables and also for partial application or currying. Higher order functions can also be defined.

All anonymous functions are implemented through the internal Closure class — which is strange since anonymous functions can be used to implement closures, but anonymous functions are not closures. It takes advantage of the __invoke() magic in PHP 5.3.x. This means that alternate implementations or libraries taking further advantage of anonymous functions could be created rather easily.

Anonymous Functions

It is very easy to define an anonymous function:

$variable = function ($arg) {
  return $arg+1;

This is very close to what JavaScript programmers typically call a closure, for reasons we’ll see shortly.

Note: In PHP 5.4.x (currently in alpha — development preview), an anonymous function defined inside of a class can use the $this variable to access class properties and methods.

Closures and Bound Variables

A closure is an anonymous function that encloses part of the external scope surrounding it. Here’s an example:

// Assign value to variable to be bound
$variable = 3;
// Create a closure using a variable outside of the scope of the anonymous function.
$closure = function ($arg) use($variable) {
  return $arg + $variable;

One must explicitly bind variables in the outside scope by using the keyword use. Binding variables in PHP is, by default, through early binding. This means that the values seen by the anonymous function are the values that were bound at the time the function was defined. One can implement late binding by passing in the variables to be bound by reference in the use parameters. For example:

// Define the greeting
$greeting = "Hello!\n";
// Define a function and bind a variable by reference (late binding)
$f = function() use(&$greeting) {
  echo $greeting;
// Run the closure
// Change the greeting
$greeting = "Hi!\n";
// Run the closure

This would output:


JavaScript uses late binding, where the value seen is whatever the bound variable’s value is at the time of the anonymous function’s execution. Variable scope overlaps one level of nesting — closures can access variables in the scope directly containing it. In PHP, I have nonesuch luck. This is why anonymous functions are commonly called closures in JavaScript, it is so common to use its implicit binding that most programmers don’t notice that they might not even be creating a real closure. (Since the variables in the containing scope are always available to the anonymous function (unless there are optimizations in the interpreter or compiler), it might technically still be a closure.)

Partial Application of Functions

If there is a general function that accepts many variables and one wants to create a function that fixes most of the variables, one can partially apply a function. This takes a function with a certain number of parameters and returns a function that accepts fewer parameters. For instance, I can take a saddle function (a 3-d function that looks like a saddle) and turn it into a 2-d parabola (which is actually the curve at y = 5):

$general_function = function($x, $y) {
  return $x*$x - $y*$y;
$partial_function = function($x) use($general_function) {
  return $general_function($x, 5);

Higher Order Functions

Higher order functions are functions that accept functions as their parameters. A common higher order function is the compose function. It accepts two functions and returns a function. All of the inputted functions must accept the same number of parameters and resulting function will accept the same number of parameters.

function compose(&$f, &$g) {
  // Return the composed function
  return function() use($f,$g) {
    // Get the arguments passed into the new function
    $x = func_get_args();
    // Call the function to be composed with the arguments
    // and pass the result into the first function.
    return $f(call_user_func_array($g, $x));

Other common functions are map, filter, & fold (reduce in some cases).

The function map takes an array and a function, applies the function to each element in the array, returning the resulting array:

// Convenience wrapper for mapping
function map(&$data, &$f) {
  return array_map($f, $data);

The filter function takes an array and a function (boolean). It applies the function to each element in the array and appends it to the array if the function returns true.

// Convenience wrapper for filtering arrays
function filter(&$data, &$f) {
  return array_filter($data, $f);

The fold function aids in taking an array and turning it into a scalar (single) value:

// Convenience wrapper for reducing arrays
function fold(&$data, &$f) {
  return array_reduce($data, $f);

// sum over an array using the fold function
$sum = function ($values) {
  return fold($values, function($u, $v) {
    return $u += $v;

Functions as Objects

Unfortunately, the class which is implemented internally for anonymous functions does not support instantiation. This has the side effect of not allowing the Closure class to be extended. This is not a huge deal, since the __invoke() magic could be used to create a class that can be used the same way as the internal class. For instance:

class Lambda {
private $anonymous;
  public function __construct($f) {
    $this->anonymous = $f;
  public function __invoke() {
    $x = func_get_args();
    return call_user_func_array($this->anonymous, $x);

$a = new Lambda(function($x) {
  return $x*$x;

$y = $a(5);
echo "$y\n";

If one implemented the ArrayAccess interface, one could create objects that as extensible as JavaScript objects.

Example Code

There are more examples for one to peruse over at my github account. Here are the links to the gists:

  1. Composing Functions in PHP
  2. Sketch of Making a Functional Style Controller (Please, don’t emulate this! This is terrible, I have a better way of doing it in the works.)
  3. Functional Programming in PHP