Implementation analysis of ThinkPHP6.0 pipeline mode and middleware
Description
ThinkPHP 6.0 RC5 began to use the pipeline mode to implement middleware, which is more concise and orderly than the implementation of previous versions. This article analyzes its implementation details.
First we start from the entry file public/index.php, $http = (new App())->http;
Get an instance of the http class and call its run method :$response = $http->run();, and then its run method calls the runWithRequest method:
1 2 3 4 5 6 7 8 9 10 11 |
|
The execution of middleware is in the final return statement.
pipeline, through, send method
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
through method code:
1 2 3 4 5 |
|
The previous call through is the incoming array_map (...) encapsulates the middleware into closures, and through saves these closures in the $pipes attribute of the Pipeline class.
PHP’s array_map method signature:
1 |
|
$callback iterates over each element of $array and returns a new value. Therefore, the final formal characteristics of each closure in $pipes are as follows (pseudocode):
1 2 3 4 |
|
This closure receives two parameters, one is the request instance, and the other is the callback function, handle method After processing, the response is obtained and returned.
through returns an instance of the Pipeline class, and then calls the send method:
1 2 3 4 5 |
|
This method is very simple. It just saves the incoming request instance in the $passable member variable, and finally returns the Pipeline class. instance, so that other methods of the Pipeline class can be called in a chain.
then, carry method
After the send method, then call the then method:
1 2 3 4 5 |
|
The then here receives a closure as a parameter. This closure The package actually contains the execution code for the controller operations.
then method code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
carry code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
In order to make it easier to analyze the principle, we put the carry method inside Connect it to then and remove the error capture code to get:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
The key here is to understand the execution process of array_reduce and $pipeline($this->passable). These two processes can be compared to " The process of "wrapping onions" and "peeling onions".
array_reduce first iteration, the initial value of $stack is:
(A)
1 2 3 |
|
The return value of the callback function is:
(B)
1 2 3 |
|
Substitute A into B to get the value of $stack after the first iteration:
(C)
1 2 3 4 5 6 7 |
|
For the second iteration, in the same way, substitute C into B to get:
(D)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
And so on, we have Substitute as many middlewares as you want, and the last time you get $stack, return it to $pipeline. Since the middleware closures were reversed in the previous order, the closures in the front are wrapped in the inner layer, so the closures after the reverse order are later on the outside, and from the perspective of the forward order, they become the earlier ones. Middleware is the outermost layer.
After wrapping the closures layer by layer, we get a "super" closure D similar to an onion structure. The structure of this closure is as shown in the code comments above. Finally, pass the $request object to this closure and execute it: $pipeline($this->passable);, thus starting a process similar to peeling an onion. Next, let’s see how the onion is peeled.
Analysis of peeling onion process
array_map(...) Process each middleware class into a closure similar to this structure:
1 2 3 4 |
|
The handle is the entrance in the middleware, and its structural characteristics are as follows:
1 2 3 4 5 6 |
|
Our "onion" above has only two layers in total, that is, there are two layers of closures of the middleware, assuming M1- 1 and M1-2 are respectively the prefix and postvalue operation points of the first middleware handle method. The same applies to the second middleware, which is M2-1 and M2-2. Now, let the program execute $pipeline($this->passable), expand it, that is, execute:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
At this time, the program requires the return value from:
1 2 3 4 5 6 7 8 9 |
|
, that is To execute the first middleware closure, $passable corresponds to the $request parameter of the handle method, and the next-level closure
1 2 3 4 5 6 7 |
|
corresponds to the $next parameter of the handle method.
To execute the first closure, that is, to execute the handle method of the first closure, the process is: first execute the code at point M1-1, that is, the pre-operation, and then execute $response = $next($request);, then the program enters to execute the next closure, $next($request) is expanded, that is:
1 2 3 4 5 6 7 |
|
and so on, execute the closure, that is, execute the second The handle method of the middleware, at this time, first executes the M2-1 point, and then executes $response = $next($request). The $next closure at this time is:
1 2 3 |
|
Belongs to the core of the onion— — The innermost layer, which is the closure containing the controller operations, expand it:
1 2 3 |
|
最终,我们从 return $destination($passable) 中返回一个 Response 类的实例,也就是,第二层的 $response = $next($request) 语句成功得到了结果,接着执行下面的语句,也就是 M2-2 点位,最后第二层闭包返回结果,也就是第一层闭包的 $response = $next($request) 语句成功得到了结果,然后执行这一层闭包该语句后面的语句,即 M1-2 点位,该点位之后,第一层闭包也成功返回结果,于是,then 方法最终得到了返回结果。
整个过程过来,程序经过的点位顺序是这样的:M1-1→M2-1→控制器操作→M2-2→M1-2→返回结果。
总结
整个过程看起来虽然复杂,但不管中间件有多少层,只要理解了前后两层中间件的这种递推关系,洋葱是怎么一层层剥开又一层层返回的,来多少层都不在话下。
The above is the detailed content of Implementation analysis of ThinkPHP6.0 pipeline mode and middleware. For more information, please follow other related articles on the PHP Chinese website!

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

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

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

Hot Topics



To run the ThinkPHP project, you need to: install Composer; use Composer to create the project; enter the project directory and execute php bin/console serve; visit http://localhost:8000 to view the welcome page.

ThinkPHP has multiple versions designed for different PHP versions. Major versions include 3.2, 5.0, 5.1, and 6.0, while minor versions are used to fix bugs and provide new features. The latest stable version is ThinkPHP 6.0.16. When choosing a version, consider the PHP version, feature requirements, and community support. It is recommended to use the latest stable version for best performance and support.

Steps to run ThinkPHP Framework locally: Download and unzip ThinkPHP Framework to a local directory. Create a virtual host (optional) pointing to the ThinkPHP root directory. Configure database connection parameters. Start the web server. Initialize the ThinkPHP application. Access the ThinkPHP application URL and run it.

"Development Suggestions: How to Use the ThinkPHP Framework to Implement Asynchronous Tasks" With the rapid development of Internet technology, Web applications have increasingly higher requirements for handling a large number of concurrent requests and complex business logic. In order to improve system performance and user experience, developers often consider using asynchronous tasks to perform some time-consuming operations, such as sending emails, processing file uploads, generating reports, etc. In the field of PHP, the ThinkPHP framework, as a popular development framework, provides some convenient ways to implement asynchronous tasks.

Performance comparison of Laravel and ThinkPHP frameworks: ThinkPHP generally performs better than Laravel, focusing on optimization and caching. Laravel performs well, but for complex applications, ThinkPHP may be a better fit.

ThinkPHP installation steps: Prepare PHP, Composer, and MySQL environments. Create projects using Composer. Install the ThinkPHP framework and dependencies. Configure database connection. Generate application code. Launch the application and visit http://localhost:8000.

ThinkPHP is a high-performance PHP framework with advantages such as caching mechanism, code optimization, parallel processing and database optimization. Official performance tests show that it can handle more than 10,000 requests per second and is widely used in large-scale websites and enterprise systems such as JD.com and Ctrip in actual applications.

Development suggestions: How to use the ThinkPHP framework for API development. With the continuous development of the Internet, the importance of API (Application Programming Interface) has become increasingly prominent. API is a bridge for communication between different applications. It can realize data sharing, function calling and other operations, and provides developers with a relatively simple and fast development method. As an excellent PHP development framework, the ThinkPHP framework is efficient, scalable and easy to use.
