Study background

When looking at the Laravel source code, there are many anonymous functions. For small white, so see my headache. However, after watching several times, slowly also understand, in order to deepen the impression, I want to learn more about anonymous functions.

Refer to the article

Link: www.cnblogs.com/echojson/p/…

PHP Closure class details

Closure

Closure is for function reuse, PHP closure function is designed to reuse functions and language features, if the closure function in the specified domain variable access, use the use keyword to achieve. PHP, with its function-oriented programming features, is also an object-oriented programming language. PHP automatically converts Closure functions into instances of the built-in Closure class, which in turn add more power to the Closure function. Closures cannot be instantiated (private constructors) and cannot be inherited. You can use reflection to determine whether a closure instance can be instantiated and inherited!

$say = function () {
    echo "Say";
};

var_dump($say);
// Here is the print result
//PHP automatically converts the Closure function into an object instance of the built-in Closure class
object(Closure)# 1 (0) {

}
Copy the code

Anonymous functions

$say = function() {
    echo "Say";
}

// 1: anonymous function call
$say(a); test(Closore$callback) {
    return $callback(a); }// 2: the second call
test($say);
Copy the code

To achieve closure

An anonymous function passed in as an argument in a normal function can also be returned in a function. The keyword that connects a closure to an external variable: USE

$helloWorld = function () { $hello = "Hello"; // The variable referenced by use is just a CLONE of the variable (not a full reference to the variable itself), so any changes to the variable must be preceded by an ampersand (&). $worlds = function () use(&$hello) { $hello .= " World"; }; $worlds(); echo $hello; }; $helloWorld(); var_dump($helloWorld);Copy the code

An anonymous function in a class

class A { public static function testA() { return function ($i) { return $i+100; }; } } function B(Closure $callback) { return $callback(200); $a = B(a ::testA()); $a = B(a ::testA()); print_r($a);Copy the code

Binding of anonymous functions

Anonymous function access is no longer anonymous function scope, but a class access scope, so we bind an anonymous function to a class.

Closure {
    __construct ( void )
    public static Closure bind (Closure $closure , object $newthis [, mixed $newscope = 'static' ])
    public Closure bindTo (object $newthis [, mixed $newscope = 'static' ])
}
Copy the code

Parameters that

Closure: anonymous function to bind newThis: object to bind to anonymous function, or NULL to create unbound closure NewScope: class scope to bind to closure, or the ‘static’ identifier does not change. If an object is passed in, the class name of the object is used. Class scope to determine the private, protected method visibility of the $this object in the closure. You can pass either the class name or an instance of the class. The default value is’ static ‘, which means no change. Return value: Returns a new Closure object, or false on failure.

Closure:: Static versions of bind and Closure::bindTo

The bind parameter allows access to public, protect, and private attributes of the class. Public: public type, which can be subclassed by self:: Var calls a public method or property,parent::method calls a parent method, which in an instance might suffice. Parent ::method calls a parent method, Parent ::method calls parent methods. Obj ->var may be sufficient to call methods or properties of public type. In a subclass you can use self:: Parent ::method calls the protect method or property. Parent ::method calls the protect method or property. Parent ::method calls the parent class. Methods and properties of protect type cannot be called by obj->var in an instance. Private: Properties or methods of a private type can be used only in that class. Private properties and methods can be called in instances of that class, subclasses, and instances in subclasses.

You can’t use this to access a static variable, you can’t use this to access a static variable in a static method, or you can’t use this in a static method. Reason: Static properties belong to the class itself and not to any instance of the class. Static properties can be thought of as global variables stored in a class that can be accessed from anywhere through the class. You cannot access private static variables outside the class with the class name ::. You can only access private static variables inside the class with self or static.

First argument: the anonymous function to bind. 12. The second argument to close bind can be object or NULL, depending on whether the first argument closure contains the object context. The binding’s preference for that determines the context of this· in the function. The binding pair likes the context in which this⋅ determines the function. If $this is used in a closure, the second argument cannot be null, but must be an object instance. If the closure is used for static access (: :), the second argument can be null or object. The third parameter: scope, which controls the scope of the closure. If the closure accesses the private property, the third parameter is required to improve the access of the closure. If the closure accesses the public property, the third parameter is not required. This is required only if you don’t want to change access permissions, either by passing an object or a class name.

<? PHP class A {private $name = 'private '; protected $age = 30; private static $weight = '70kg'; Public $address = '$address '; public static $height = '180cm'; } $obj = new A(); $obj->name; $obj->name; $obj->age; $obj->age; //A::$weight; $obj->address; A::$height; $this->name; $this->name; $this->name; $this->name; }; Fatal error: Uncaught error: Using $this when not in object context //echo $fun(); $fun = function () { return A::$height; }; //echo $fun(); $fun = function () { return $this->name; }; $this = $fun; $this = $fun; $this = $fun; Fatal error: Uncaught error: Using $this when not in object context Fatal error: Uncaught error: Using $this when not in object context // The name attribute of class A is private and cannot be accessed. // Uncaught Error: Cannot access private property A::$name // $name = Closure::bind($fun,new A(),new A())); //echo $name(); $fun = function () { return self::$weight; }; $wight = Closure::bind($fun,null,A::class); echo $wight(); Sometimes the second argument is null, and sometimes the third argument is not. This depends on how the code in your anonymous function is accessed. $this->name = $this->name; $this->name = $this->name; If it is private, protected, you need to use the third parameter to make it public. If it is already public, you can omit it or not. When you use bind, you can write either null as the second argument, or you can write a specific object instance, usually null. The third parameter depends on whether the static property you access is private or public. If it's private or protected, you have to write the third parameter to make it public. 3. If you want to raise the scope of the property, you need to pass the third parameter, either the object name or the class name.Copy the code