Monday, 11 November 2019

A simple closure of PHP

A simple closure

We’ll start by creating a very simple closure using an anonymous function:
// A simple example of a closure

function getGreetingFunction() {

  $timeOfDay = "morning";

  return ( function( $name ) use ( &$timeOfDay ) {
    $timeOfDay = ucfirst( $timeOfDay ); 
    return ( "Good $timeOfDay, $name!" );
  } );
};

$greetingFunction = getGreetingFunction();
echo $greetingFunction( "Fred" ); // Displays "Good Morning, Fred!"
Let’s walk through this code:
  1. getGreetingFunction()
    getGreetingFunction() initialises a local variable, $timeOfDay, on line 5, and on lines 7-10 it also defines and returns an anonymous function (described below).
  2. The anonymous function
    On line 8, the anonymous function manipulates getGreetingFunction()‘s local $timeOfDay variable by converting its first letter to uppercase, and on line 9 it returns a greeting string that contains $timeOfDay‘s value.
      • The use keyword
        Normally, the anonymous function wouldn’t have access to the $timeOfDay variable, since that variable is local to getGreetingFunction()‘s scope only. However, the use keyword on line 7 tells PHP to let the anonymous function access $timeOfDay. This lets us create the closure.
      • The ampersand
        The ampersand (&) before $timeOfDay tells PHP to pass a reference to the $timeOfDay variable into the anonymous function, rather than just copying the variable’s value. This allows the anonymous function to manipulate $timeOfDay directly. Strictly speaking, a closure’s function should always access variables in its enclosing scope by reference. That said, if you know that you won’t need to change the value of a variable then you can omit the ampersand to pass the variable by value instead.
  3. Calling getGreetingFunction()
    On line 13, we call getGreetingFunction() and get back the returned anonymous function, which we store in a $greetingFunction variable.
    Note that, by this point, getGreetingFunction() has finished running. In normal circumstances, its local variable, $timeOfDay, would have fallen out of scope and disappeared. However, because we’ve created a closure using the anonymous function (now stored in $greetingFunction), the anonymous function can still access this $timeOfDay variable.
  4. Calling the anonymous function
    On line 14, we call our anonymous function. It manipulates the value of the $timeofDay variable inside the closure by converting its first letter to uppercase, then it returns a greeting containing $timeOfDay‘s new value, which is "Morning".
That, in a nutshell, is how you create a closure in PHP. It’s a trivial example, but the important point to note is that the returned anonymous function can still access its enclosing function’s $timeOfDay local variable, even after the enclosing function has finished running.

No comments:

Post a Comment