PHP

Anonymous / Lambda functions and Closures

A lambda function (also commonly referred to as an anonymous function) is a function that was declared without any named identifier to refer to it . Lambda functions allow the quick definition of throw-away functions that are not used elsewhere. A closure is a lambda which closes over the environment in which it was defined. This means that a closure can use of variables from outside its scope (parent scope). A closure is a lambda (anonymous) function, but a lambda function is not a closure unless you specify the use keyword.

Anonymous function

PHP 5.3 introduced anonymous functions. An anonymous function is a function without a name (nameless function). Anonymous functions can be assigned to variables and passed around just like any other PHP object. But it’s still a function, so you can invoke it and pass it arguments.

<?php
$anony = function ($a , $b)
 {
  return $a < $b;
 };

var_dump (
 $anony ( 1 ,2 ) //true
);

Anonymous class

PHP 7 introduced anonymous classes. We can now instantiate objects through nameless classes, which brings us closer to object literal syntax found in other languages. Let’s take a look at the following simple example:

$anony = new class {
 public function hello($name) {
  return "Hello $name";
 }
};

echo $anony->hello('World');
//Hello world

When to use anonymous (lambda) function

Anything that requires a temporary function that you probably will only use once. I would use them for callbacks, for functions such as usort function:

$someArray = ['100',3,7,1];
usort ($someArray, function ($x , $y) {
 return $x > $y;
});

print_r($someArray);

The preg_replace_callback example:

$text = "<p>some text...\n\n\n</p>...";
$text = preg_replace_callback(
      '|<p>\s*\w|',
      function ($matches) {
       return strtoupper($matches[0]);
      },
      $text
 );

echo $text; //<p>Some text

Closure

PHP closures and anonymous (lambda) functions use the same syntax as a function, but if you inspect a PHP closure or anonymous function, you’ll find they are instances of the Closure class:

<?php
$anony = function () {
 return 'lambda';
};

//Closure
echo get_class($anony);

//object
echo gettype($anony);

We can see that anonymous functions are implemented as objects instantiated from the Closure class.

A closure in PHP is an anonymous (lambda) function that encapsulates its surrounding state at the time it is created. The encapsulated state exists inside the closure even when the closure lives after its original environment ceases to exist. In practical syntax we define a closure like this:

<?php
$hello = 'Hello ';

$closure = function ($name) use ($hello){
 return $hello.$name;
};

//Closure
echo get_class($closure);

//object
echo gettype($closure);

//Hello World
echo $closure('World');

Use keyword

Variables are not accessible inside functions unless they are declared as global. In much the same way, variables from the child scope are not accessible from within the closure unless explicitly stated using the use keyword.

Closure class

PHP introduced the Closure class in the 5.3 version. Closure class is used to represent anonymous (lambda) functions. Anonymous functions, implemented in PHP 5.3, yield objects of this type. Since PHP 5.4, the Closure class got several methods that allow further control of the anonymous function after it has been created.

bindTo() method

The bind() and bindTo() methods basically duplicate the Closure with a specific bound object and class scope.

Closures have the ability to capture a context from outside of the function’s scope (using use keyword). In addition to variables, this context can also be an object’s scope. This creates a closure object that has access to the properties of the object.

The bindTo method has two parameters:

  • the object to which the closure is bound
  • the class scope that it is associated with it

To access private and protected, the name of the class must be specified as the second argument:

class A {
 private $hi = 'Hello ';
}

$closure = function () { return $this->hi; };
$getHi = $closure->bindTo(new A , 'A');

echo $getHi(); // Hello

bind() method

The bind() method has three parameters:

  • The anonymous functions to bind
  • The object to which the given anonymous function should be bound
  • The class scope that it is associated with
class A {
 private $hi = 'Hello ';
}

$closure = function () { return $this->hi; };
$getHi = Closure::bind($closure,new A, 'A');

echo $getHi(); // Hello

Call() method

PHP 7 introduced the call method on a Closure class. The call method does not duplicate the closure, it temporarily binds the closure to the object, and calls it with any given parameters. It then returns the return value of the closure:

class A {
 private $hi = 'Hello ';
}

$closure = function () { return $this->hi; };
$getHi = $closure->call(new A);

echo $getHi; // Hello

For more information visit:

Advertisement:
Advertisement: