The PHP closure of Closure USES elaboration

  • 2020-06-01 09:16:13
  • OfStack

Unconsciously, I found that PHP had reached version 5.5, and I was using PHP5.2 all the time, which made me look like a young man from a remote mountain. After getting used to using closures in javascript, I suddenly became interested in PHP's closures.

As a result, an WAMP integrated development environment has been installed on the web, which is version PHP 5.3 (PHP 5.3 has introduced the feature of closures). It must be said that WAMP is really easy to install and use. Simple configuration 1, get started.

Anonymous functions
When you think of closures, you have to think of anonymous functions, also known as closure functions (closures), which seem to be the main implementation of PHP closures. The declaration of an anonymous function is as follows:


$func = function() {

}; // With a terminator 

As you can see, the anonymous function has no name, so if you want to use it, you need to return it to a variable. Anonymous functions, like normal function 1, can declare arguments and call the same methods:

$func = function( $param ) {
    echo $param;
};
$func( 'some string' );
// Output: 
//some string

By the way, PHP also had a function that created anonymous functions before the introduction of closures: create function, but the code logic could only be written as strings, which seemed arcane and unmaintainable, so it was rarely used.

To achieve closure
Anonymous functions are passed in as arguments in normal functions and can also be returned. This implements a simple closure.

Here are three examples


// case 1
// It's defined in the function 1 An anonymous function and call it 
function printStr() {
    $func = function( $str ) {
        echo $str;
    };
    $func( 'some string' );
}
printStr();
 
// case 2
// Return the anonymous function in the function and call it 
function getPrintStrFunc() {
    $func = function( $str ) {
        echo $str;
    };
    return $func;
}
$printStrFunc = getPrintStrFunc();
$printStrFunc( 'some string' );
 

// case 3
// Pass the anonymous function as an argument and call it 
function callFunc( $func ) {
    $func( 'some string' );
}
$printStrFunc = function( $str ) {
    echo $str;
};
callFunc( $printStrFunc );
// You can also pass anonymous functions directly. If you know js This might be a familiar way to write it 
callFunc( function( $str ) {
    echo $str;
} );

The keyword that connects closures to external variables: USE
Closures can hold variables and values in the context of the code block they are in. PHP by default, anonymous functions cannot call the context variables of the code block they are in, but only by using the use keyword.

Let's do another example:


function getMoney() {
    $rmb = 1;
    $dollar = 6;
    $func = function() use ( $rmb ) {
        echo $rmb;
        echo $dollar;
    };
    $func();
}
getMoney();
// Output: 
//1
// Report an error. Can't find it dorllar variable 

As you can see, dollar is not declared in the use keyword and is not available in this anonymous function, so be aware of this in your development.

One might wonder if it is possible to change context variables in anonymous functions, but I find that it is not possible:


function getMoney() {
    $rmb = 1;
    $func = function() use ( $rmb ) {
        echo $rmb;
        // the $rmb The value of the add 1
        $rmb++;
    };
    $func();
    echo $rmb;
}
getMoney();
// Output: 
//1
//1

Ah, it turns out that use is only referring to one copy of the variable. But I want to reference the variable completely, not copy it.

To do that, you actually add 1 to the variable & Symbols will do:


function getMoney() {
    $rmb = 1;
    $func = function() use ( &$rmb ) {
        echo $rmb;
        // the $rmb The value of the add 1
        $rmb++;
    };
    $func();
    echo $rmb;
}
getMoney();
// Output: 
//1
//2

Ok, so anonymous functions can refer to context variables. If you return an anonymous function to the outside world, the anonymous function will hold the variables referenced by use, but the outside world will not have access to them, which might make the concept of 'closures' a little clearer.

Change 1 according to the above example:


function getMoneyFunc() {
    $rmb = 1;
    $func = function() use ( &$rmb ) {
        echo $rmb;
        // the $rmb The value of the add 1
        $rmb++;
    };
    return $func;
}
$getMoney = getMoneyFunc();
$getMoney();
$getMoney();
$getMoney();
// Output: 
//1
//2
//3

conclusion
The features of PHP closures are not so surprising. In fact, CLASS can achieve similar or even much more powerful functions, not to mention the same as js's closures. We can only hope that PHP will improve its support for closures in the future. Anonymous functions are useful, though, because you don't have to declare callbacks externally when you're using functions like preg_replace_callback and so on.


Related articles: