Categories
PHP

The Closure Class

A closure is an anonymous function, but an anonymous function is not a closure.

An anonymous function declares without any named identifier to refer to it. A closure is an anonymous function that closes over the environment in which it was defined. This means a closure can use of variables from outside its scope (parent scope).

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

<?php
 //Anonymous function
 $anony = function () {
  return 'lambda';
 };
 echo get_class($anony); # Prints: Closure
 echo gettype($anony);   # Prints: object

 //Arrow function
 $arrow = fn() => 'im an arrow func';
 echo get_class($arrow); # Prints: Closure
 echo gettype($arrow);   # Prints: object

Use keyword

Variables are not accessible inside functions unless they are declared as global:

<?php
 # Anonymous function
 $hello = 'Hello ';
 $anony= function ($name){
  return $hello.$name;
 };
 echo $anony('World');
 # Warning: Undefined variable $hello ... on line 5

In much the same way, variables from the child scope are not accessible from within the closure unless explicitly stated using the use keyword:

<?php
 # Closure example
 $hello = 'Hello ';
 $closure = function ($name) use ($hello){
  return $hello.$name;
 };
 echo $closure('World');
 # Prints: Hello World

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.

Example: Passing multiple parameters and use multiple outer scope variables in a closure:

<?php
 #Closure example
 $v1 = 'V1 ';
 $v2 = 'V2 ';
 $c = function ($v3, $v4) use ($v1, $v2) {
       echo $v1,$v2,$v3,$v4;
      };
 $c('V3 ','V4'); # V1 V2 V3 V4

Closure class

PHP introduced the Closure class in the 5.3 version. The closure class is used to represent anonymous 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:

<?php
 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
<?php
 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:

<?php
 class A {
  private $hi = 'Hello ';
 }
 $closure = function () {
             return $this->hi;
            };
 $getHi = $closure->call(new A);
 echo $getHi; // Hello

Note: you can replace the anonymous function with the arrow function, following is the modified example:

<?php
 class A {
  private $hi = 'Hello ';
 }

 $closure = fn() => $this->hi;
 $getHi = $closure->call(new A);
 echo $getHi; // Hello 

For more information visit: http://php.net/manual/class.closure.php


PHP OOP Tutorials: