Home Backend Development PHP Tutorial What are anonymous functions and closures in PHP? How to create?

What are anonymous functions and closures in PHP? How to create?

Jul 29, 2016 am 08:33 AM
php anonymous function Closure


The content of this article is to introduce to you what anonymous functions and closures are in PHP? How to create anonymous functions and closures? It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

Overview

Closures and anonymous functions were introduced in PHP 5.3.0. These two features are very useful and every PHP developer should master them.

Anonymous functions are actually functions without names. Anonymous functions can be assigned to variables and passed like any other PHP function object. However, anonymous functions are still functions, so they can be called and parameters can be passed in, making them suitable as callbacks for functions or methods.

A closure refers to a function that encapsulates the surrounding state when it is created. Even if the environment where the closure is located no longer exists, the state encapsulated in the closure still exists.

Creating anonymous functions

Creating anonymous functions is very simple:

//将匿名函数赋给一个变量,通过变量名+()的形式来调用
$greet = function () {
    return "Hello World";
};

echo $greet();
Copy after login

Result printing:

Hello World
Copy after login

Anonymous functions are very similar to ordinary PHP functions: the commonly used syntax is the same, they also accept parameters, and can return values. However, closures do not have function names.

Note: The reason why we can call the $greet variable is because the value of this variable is a closure, and the closure object implements the __invoke() magic method. As long as there is () after the variable name, PHP will find and call the __invoke method.
$greet变量,是因为这个变量的值是一个闭包,而且闭包对象实现了__invoke()魔术方法,只要变量名后有(),PHP就会查找并调用__invoke方法。

我们通常把匿名函数当做函数或方法的回调使用,事实上,很多PHP函数都会用到匿名函数,比如array_mappreg_replace_callback,这是使用PHP匿名函数的绝佳时机。记住,闭包和其他值一样,可以作为参数传入其他PHP函数:

$numberPlusOne = array_map(function ($number) {
    return $number += 1;
}, [1, 2, 3]);

print_r($numberPlusOne);
Copy after login

在匿名函数出现之前,要实现这样的功能,PHP开发者只能单独创建具名函数,然后使用名称引用这个函数:

function incrementNumber ($number) {
    return $number += 1;
}

$numberPlusOne = array_map(‘incrementNumber’,  [1, 2, 3]);
print_r($numberPlusOne);
Copy after login

这样做把回调的实现和使用场所隔离开了,而且使用闭包实现代码更加简洁。

创建闭包

包含自由变量的函数与为所有这些自由变量提供了变量绑定的环境一起,被称为闭包。
function makeHelloWorld($name) { 
    $i = 0;
    return function()use($name, &$i){
        echo $name.$i. ' <br>';
        $i++;
    };

}
$hello1 = makeHelloWorld("itbsl");
$hello2 = makeHelloWorld("kevin");
$hello1();
$hello1();
$hello1();
$hello2();
Copy after login

打印结果:

itbsl0 
itbsl1 
itbsl2 
kevin0
Copy after login

从父作用域继承变量

在PHP中必须手动调用闭包对象的bindTo方法或使用use关键字把父作用域的变量及状态附加到PHP闭包中。而实际应用中,又以使用use关键字实现居多。

use关键字

实际上,Laravel框架中也大量使用了闭包,最常见的比如路由定义:

Route::group(['domain' => '{account}.myapp.com'], function () {
    Route::get('user/{id}', function ($account, $id) {
        //
    });
});
Copy after login

这里面的两个function都是匿名函数。而从父作用域继承变量的使用场景在Laravel底层源码中也是俯拾即是,比如Model.php(IlluminateDatabaseEloquent)的saveOrFail方法:

What are anonymous functions and closures in PHP? How to create?

该方法的作用是使用事务将模型数据保存到数据库,这里面我们使用匿名函数返回保存状态,同时使用use关键字将父作用域的$options传递给该闭包以便其能够访问这个数据。

此外,还支持传递多个父作用域变量到匿名函数,比如还是在Model类中的forceFill方法:

What are anonymous functions and closures in PHP? How to create?

多个变量以逗号分隔即可。

bindTo方法

我们在前面已经提到,闭包是一个对象,所以我们可以在闭包中使用$this关键字获取闭包的内部状态,闭包对象的默认状态没什么用,需要注意的是其中的__invoke魔术方法和bindTo方法。

__invoke的作用前面已经说过,当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。

接下来我们来看看bindTo方法,通过该方法,我们可以把闭包的内部状态绑定到其他对象上。这里bindTo方法的第二个参数显得尤为重要,其作用是指定绑定闭包的那个对象所属的PHP类,这样,闭包就可以在其他地方访问邦定闭包的对象中受保护和私有的成员变量。

你会发现,PHP框架经常使用bindTo方法把路由URL映射到匿名回调函数上,框架会把匿名回调函数绑定到应用对象上,这样在匿名函数中就可以使用$thisWe usually use anonymous functions as callbacks of functions or methods. In fact, many PHP functions use anonymous functions, such as array_map and preg_replace_callback. is an excellent time to use PHP anonymous functions. Remember, closures, like other values, can be passed as parameters to other PHP functions:

class App {
    protected $routes = [];
    protected $responseStatus = '200 OK';
    protected $responseContentType = 'text/html';
    protected $responseBody = 'Laravel学院';

    public function addRoute($routePath, $routeCallback) {
        $this->routes[$routePath] = $routeCallback->bindTo($this, __CLASS__);
    }

    public function dispatch($currentPath) {
        foreach ($this->routes as $routePath => $callback) {
            if( $routePath === $currentPath) {
                $callback();
            }
        }
        header('HTTP/1.1 ' . $this->responseStatus);
        header('Content-Type: ' . $this->responseContentType);
        header('Content-Length: ' . mb_strlen($this->responseBody));
        echo $this->responseBody;
    }

}
Copy after login
Copy after login
🎜 Before the advent of anonymous functions, to implement such functionality, PHP developers could only create a separate named function and then reference this function by name :🎜
$app = new App();
$app->addRoute(‘user/nonfu’, function(){
    $this->responseContentType = ‘application/json;charset=utf8’;
    $this->responseBody = ‘{“name”:”LaravelAcademy"}';
});
$app->dispatch(‘user/nonfu');
Copy after login
Copy after login
🎜This isolates the implementation of callbacks from the places of use, and the use of closures to implement code is more concise. 🎜🎜🎜🎜Creating Closures 🎜🎜🎜🎜A function containing free variables, together with an environment that provides variable bindings for all these free variables, is called a closure. rrreee🎜Print results:🎜rrreee🎜🎜Inherit variables from the parent scope🎜🎜🎜In PHP, you must manually call the bindTo method of the closure object or use useKeyword attaches the variables and state of the parent scope to the PHP closure. In actual applications, most of them are implemented using the use keyword. 🎜🎜🎜use keyword 🎜🎜🎜🎜In fact, closures are also widely used in the Laravel framework. The most common ones are routing definitions: 🎜rrreee🎜Here are two Each function is an anonymous function. The usage scenarios of inheriting variables from the parent scope are also common in Laravel's underlying source code, such as the saveOrFail method of Model.php (IlluminateDatabaseEloquent): 🎜🎜What are anonymous functions and closures in PHP? How to create?🎜🎜The function of this method is to use transactions to transfer model data Save to the database, here we use an anonymous function to return the saved status, and use the use keyword to pass the $options of the parent scope to the closure so that it can access the data. 🎜🎜In addition, it also supports passing multiple parent scope variables to anonymous functions, such as the forceFill method in the Model class: 🎜

What are anonymous functions and closures in PHP? How to create?🎜🎜 Multiple variables can be separated by commas. 🎜🎜🎜bindTo method 🎜🎜🎜🎜We have mentioned before that the closure is an object, so we can use the $this keyword in the closure to get the closure The internal state of the closure object is useless. What needs to be noted is the __invoke magic method and the bindTo method. 🎜🎜The role of __invoke has been mentioned before. When trying to call an object by calling a function, the __invoke() method will be automatically called. 🎜🎜Next let’s take a look at the bindTo method. Through this method, we can bind the internal state of the closure to other objects. The second parameter of the bindTo method here is particularly important. Its function is to specify the PHP class to which the object of the bound closure belongs. In this way, the closure can access the bound closure in other places. Protected and private member variables in an object. 🎜🎜You will find that the PHP framework often uses the bindTo method to map routing URLs to anonymous callback functions. The framework will bind the anonymous callback function to the application object, so that it can be used in the anonymous function. The $this keyword refers to important application objects: 🎜

class App {
    protected $routes = [];
    protected $responseStatus = '200 OK';
    protected $responseContentType = 'text/html';
    protected $responseBody = 'Laravel学院';

    public function addRoute($routePath, $routeCallback) {
        $this->routes[$routePath] = $routeCallback->bindTo($this, __CLASS__);
    }

    public function dispatch($currentPath) {
        foreach ($this->routes as $routePath => $callback) {
            if( $routePath === $currentPath) {
                $callback();
            }
        }
        header('HTTP/1.1 ' . $this->responseStatus);
        header('Content-Type: ' . $this->responseContentType);
        header('Content-Length: ' . mb_strlen($this->responseBody));
        echo $this->responseBody;
    }

}
Copy after login
Copy after login

这里我们需要重点关注addRoute方法,这个方法的参数分别是一个路由路径和一个路由回调,dispatch方法的参数是当前HTTP请求的路径,它会调用匹配的路由回调。第9行是重点所在,我们将路由回调绑定到了当前的App实例上。这么做能够在回调函数中处理App实例的状态:

$app = new App();
$app->addRoute(‘user/nonfu’, function(){
    $this->responseContentType = ‘application/json;charset=utf8’;
    $this->responseBody = ‘{“name”:”LaravelAcademy"}';
});
$app->dispatch(‘user/nonfu');
Copy after login
Copy after login

在Larval底层也有用到bindTo方法,详见Illuminate\Support\Traits\Macroable__call方法:闭包和匿名函数(https://laravelacademy.org/post/4341.html)

总结:以上就是本篇文章的全部内容,希望能对大家的学习有所帮助。


Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Roblox: Bubble Gum Simulator Infinity - How To Get And Use Royal Keys
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Fusion System, Explained
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Mandragora: Whispers Of The Witch Tree - How To Unlock The Grappling Hook
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1670
14
PHP Tutorial
1274
29
C# Tutorial
1256
24
PHP: A Key Language for Web Development PHP: A Key Language for Web Development Apr 13, 2025 am 12:08 AM

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

PHP vs. Python: Understanding the Differences PHP vs. Python: Understanding the Differences Apr 11, 2025 am 12:15 AM

PHP and Python each have their own advantages, and the choice should be based on project requirements. 1.PHP is suitable for web development, with simple syntax and high execution efficiency. 2. Python is suitable for data science and machine learning, with concise syntax and rich libraries.

PHP and Python: Comparing Two Popular Programming Languages PHP and Python: Comparing Two Popular Programming Languages Apr 14, 2025 am 12:13 AM

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 in Action: Real-World Examples and Applications PHP in Action: Real-World Examples and Applications Apr 14, 2025 am 12:19 AM

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.

The Enduring Relevance of PHP: Is It Still Alive? The Enduring Relevance of PHP: Is It Still Alive? Apr 14, 2025 am 12:12 AM

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 and Python: Different Paradigms Explained PHP and Python: Different Paradigms Explained Apr 18, 2025 am 12:26 AM

PHP is mainly procedural programming, but also supports object-oriented programming (OOP); Python supports a variety of paradigms, including OOP, functional and procedural programming. PHP is suitable for web development, and Python is suitable for a variety of applications such as data analysis and machine learning.

PHP vs. Other Languages: A Comparison PHP vs. Other Languages: A Comparison Apr 13, 2025 am 12:19 AM

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: Code Examples and Comparison PHP and Python: Code Examples and Comparison Apr 15, 2025 am 12:07 AM

PHP and Python have their own advantages and disadvantages, and the choice depends on project needs and personal preferences. 1.PHP is suitable for rapid development and maintenance of large-scale web applications. 2. Python dominates the field of data science and machine learning.

See all articles