PHP Clourse (closure class) Brief analysis
0x00 Preface
A closure refers to a function that encapsulates the surrounding state when it is created. Even if the environment in which the closure is located no longer exists, the state encapsulated in the closure still exists.
All closures in PHP are objects instantiated by the Clourse class, which means closures are no different from other PHP objects. An object must have its methods and properties. This article will summarize the basic usage of closures in PHP and the role of the Clourse class method. [Recommended: PHP video tutorial]
0x01 Basic usage of closures
Let’s take a look at the most basic usage of closures:
<?php $hello = function ($word) { return 'hello ' . $word; }; echo $hello('world'); // 输出 hello world
Hey, the most intuitive feeling of this code is to assign a function to the $hello variable and then call it directly through $hello. But this closure does not inherit variables from the parent scope (that is, it encapsulates the surrounding state). We can inherit variables from the closure's parent scope through the use keyword. Examples are as follows:
<?php $name = 'panda'; $hello = function () use ($name) { return 'hello ' . $name; }; echo $hello(); // 输出 hello panda
Starting from PHP 7.1, use cannot pass in such variables: superglobals, $this or have the same name as a parameter.
In addition, when using the use keyword, the variables of the parent scope are passed into the closure by value. That is to say, once the closure is created, even if the external variables are modified, it will not affect the value passed into the closure (that is, even if the environment where the closure is located no longer exists, the state encapsulated in the closure still exists). An example is as follows:
<?php $name = 'panda'; $hello = function () use ($name) { return 'hello ' . $name; }; $name = 'cat'; echo $hello(); // 输出 hello panda
Passing a reference to a variable allows the closure to modify the value of an external variable. An example is as follows:
<?php $name = 'panda'; $changeName = function () use (&$name) { $name = 'cat'; }; $changeName(); echo $name; // 输出 cat
Note: When passing an object in PHP, the default is to pass it by reference, so in the closure Special attention needs to be paid when operating objects passed by use within the package. The example is as follows:
<?php class Dog { public $name = 'Wang Cai'; } $dog = new Dog(); $changeName = function () use ($dog) { $dog->name = 'Lai Fu'; }; $changeName(); echo $dog->name; // 输出 Lai Fu
0x02 Closure class
Prove that the closure is just the Closure class object
<?php $clourse = function () { echo 'hello clourse'; }; if (is_object($clourse)) { echo get_class($clourse); } // 输出 Closure
The above code will output Closure, proving that the closure is just An ordinary Closure class object.
Clourse class summary
We can see the relevant information of the closure class from the PHP official manual. The following is a summary of the Clourse class that I viewed in the local documentation of PhpStorm.
/** * Class used to represent anonymous functions. * <p>Anonymous functions, implemented in PHP 5.3, yield objects of this type. * This fact used to be considered an implementation detail, but it can now be relied upon. * Starting with PHP 5.4, this class has methods that allow further control of the anonymous function after it has been created. * <p>Besides the methods listed here, this class also has an __invoke method. * This is for consistency with other classes that implement calling magic, as this method is not used for calling the function. * @link http://www.php.net/manual/en/class.closure.php */ final class Closure { /** * This method exists only to disallow instantiation of the Closure class. * Objects of this class are created in the fashion described on the anonymous functions page. * @link http://www.php.net/manual/en/closure.construct.php */ private function __construct() { } /** * This is for consistency with other classes that implement calling magic, * as this method is not used for calling the function. * @param mixed $_ [optional] * @return mixed * @link http://www.php.net/manual/en/class.closure.php */ public function __invoke(...$_) { } /** * Duplicates the closure with a new bound object and class scope * @link http://www.php.net/manual/en/closure.bindto.php * @param object $newthis The object to which the given anonymous function should be bound, or NULL for the closure to be unbound. * @param mixed $newscope The class scope to which associate the closure is to be associated, or 'static' to keep the current one. * If an object is given, the type of the object will be used instead. * This determines the visibility of protected and private methods of the bound object. * @return Closure Returns the newly created Closure object or FALSE on failure */ function bindTo($newthis, $newscope = 'static') { } /** * This method is a static version of Closure::bindTo(). * See the documentation of that method for more information. * @static * @link http://www.php.net/manual/en/closure.bind.php * @param Closure $closure The anonymous functions to bind. * @param object $newthis The object to which the given anonymous function should be bound, or NULL for the closure to be unbound. * @param mixed $newscope The class scope to which associate the closure is to be associated, or 'static' to keep the current one. * If an object is given, the type of the object will be used instead. * This determines the visibility of protected and private methods of the bound object. * @return Closure Returns the newly created Closure object or FALSE on failure */ static function bind(Closure $closure, $newthis, $newscope = 'static') { } /** * Temporarily binds the closure to newthis, and calls it with any given parameters. * @link http://php.net/manual/en/closure.call.php * @param object $newThis The object to bind the closure to for the duration of the call. * @param mixed $parameters [optional] Zero or more parameters, which will be given as parameters to the closure. * @return mixed * @since 7.0 */ function call ($newThis, ...$parameters) {} /** * @param callable $callable * @return Closure * @since 7.1 */ public static function fromCallable (callable $callable) {} }
First of all, the Clourse class is a final class, which means that it cannot be inherited. Secondly, its constructor __construct is set to private, which means that the closure object cannot be instantiated through the new keyword. These two guarantees Closures can only be instantiated through the syntax function (...) use(...) {...}.
Why can closures be executed as functions?
From the above class summary, we can see that the Clourse class implements the __invoke method. This method is explained in the PHP official manual as follows:
When trying to call a function When an object is called, the __invoke() method is automatically called.
This is why closures can be executed as functions.
Bind the specified $this object and class scope
In frameworks that allow the use of closure routing (such as: Slim), we can see the following writing:
$app->get('/test', function () { echo $this->request->getMethod(); });
Can I use $this in a closure? Which object does this $this point to?
The function of binding $this and class scope can be achieved through the bindTo and bind methods. The example is as follows:
<?php class Pandas { public $num = 1; } $pandas = new Pandas(); $add = function () { echo ++$this->num . PHP_EOL; }; $newAdd1 = $add->bindTo($pandas); $newAdd1(); // 输出 2 $newAdd2 = Closure::bind($add, $pandas); $newAdd2(); // 输出 3
The above example binds the specified object as a closure $ this, but we didn't specify class scope. So if you rewrite the $num property of the Pandas class to protected or private, a fatal error will be thrown!
Fatal error: Uncaught Error: Cannot access protected property Pandas::$num
When we need to access non-public properties or methods of the bound object, we need to specify the class scope. The example is as follows:
<?php class Pandas { protected $num = 1; } $pandas = new Pandas(); $add = function () { echo ++$this->num . PHP_EOL; }; $newAdd1 = $add->bindTo($pandas, $pandas); $newAdd1(); // 输出 2 $newAdd2 = Closure::bind($add, $pandas, 'Pandas'); $newAdd2(); // 输出 3
Here we see that both the bindTo and bind methods specify $newscope. Parameters, the $newscope parameter defaults to static, which means it does not change the class scope. The $newscope parameter accepts a class name or object and changes the class scope of the closure to the specified class scope. At this time, the $num property of the Pandas class can be accessed by the closure.
Bind $this object and class scope once and execute (PHP7)
The bindTo and bind methods are executed each time a new object and class scope are specified. To copy the original closure and then return the new closure, it becomes cumbersome when the bound object needs to be modified multiple times, so PHP7 provides a new method call, which can temporarily bind the closure to an object. (the class scope is also modified to the class to which the object belongs) and executed. An example is as follows:
<?php class Pandas { protected $num = 1; } $pandas = new Pandas(); $add = function ($num) { $this->num += $num; echo $this->num . PHP_EOL; }; $add->call($pandas, 5); // 输出 6
Callable to Closure (PHP7.1)
In PHP7.1, the Closure class has a fromCallable method that can convert callable type values into Closure, the example is as follows:
<?php class Foo { protected $num = 1; public static function hello(string $bar) { echo 'hello ' . $bar; } } $hello = Closure::fromCallable(['Foo', 'hello']); $hello('world');
This way of writing is quite cool. After all, calling through closure is much more fun than calling with call_user_func function^_^.
0x03 Summary
For more related information, please see the Closure class and anonymous functions. Because the Chinese version of the Closure class in the PHP official manual has not been updated, there are no call and fromCallable methods. For the content, I recommend everyone to read the English version (ㄒoㄒ).
The above is the detailed content of Analyze the functions of PHP closures and Clourse class methods. For more information, please follow other related articles on the PHP Chinese website!

PHP is widely used in e-commerce, content management systems and API development. 1) E-commerce: used for shopping cart function and payment processing. 2) Content management system: used for dynamic content generation and user management. 3) API development: used for RESTful API development and API security. Through performance optimization and best practices, the efficiency and maintainability of PHP applications are improved.

PHP makes it easy to create interactive web content. 1) Dynamically generate content by embedding HTML and display it in real time based on user input or database data. 2) Process form submission and generate dynamic output to ensure that htmlspecialchars is used to prevent XSS. 3) Use MySQL to create a user registration system, and use password_hash and preprocessing statements to enhance security. Mastering these techniques will improve the efficiency of web development.

PHP and Python each have their own advantages, and choose according to project requirements. 1.PHP is suitable for web development, especially for rapid development and maintenance of websites. 2. Python is suitable for data science, machine learning and artificial intelligence, with concise syntax and suitable for beginners.

PHP is still dynamic and still occupies an important position in the field of modern programming. 1) PHP's simplicity and powerful community support make it widely used in web development; 2) Its flexibility and stability make it outstanding in handling web forms, database operations and file processing; 3) PHP is constantly evolving and optimizing, suitable for beginners and experienced developers.

PHP remains important in modern web development, especially in content management and e-commerce platforms. 1) PHP has a rich ecosystem and strong framework support, such as Laravel and Symfony. 2) Performance optimization can be achieved through OPcache and Nginx. 3) PHP8.0 introduces JIT compiler to improve performance. 4) Cloud-native applications are deployed through Docker and Kubernetes to improve flexibility and scalability.

PHP is suitable for web development, especially in rapid development and processing dynamic content, but is not good at data science and enterprise-level applications. Compared with Python, PHP has more advantages in web development, but is not as good as Python in the field of data science; compared with Java, PHP performs worse in enterprise-level applications, but is more flexible in web development; compared with JavaScript, PHP is more concise in back-end development, but is not as good as JavaScript in front-end development.

PHP and Python each have their own advantages and are suitable for different scenarios. 1.PHP is suitable for web development and provides built-in web servers and rich function libraries. 2. Python is suitable for data science and machine learning, with concise syntax and a powerful standard library. When choosing, it should be decided based on project requirements.

PHP is a scripting language widely used on the server side, especially suitable for web development. 1.PHP can embed HTML, process HTTP requests and responses, and supports a variety of databases. 2.PHP is used to generate dynamic web content, process form data, access databases, etc., with strong community support and open source resources. 3. PHP is an interpreted language, and the execution process includes lexical analysis, grammatical analysis, compilation and execution. 4.PHP can be combined with MySQL for advanced applications such as user registration systems. 5. When debugging PHP, you can use functions such as error_reporting() and var_dump(). 6. Optimize PHP code to use caching mechanisms, optimize database queries and use built-in functions. 7


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

SublimeText3 Linux new version
SublimeText3 Linux latest version

Atom editor mac version download
The most popular open source editor

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

SublimeText3 Mac version
God-level code editing software (SublimeText3)