“This article will briefly study the final execution process of the controller and the two advanced attributes used. One is the clever use of the fastcgi_finish_request method, and the other is the trait feature. We have some understanding of the concept of superclass, let’s analyze it together.
Then execute the run method through the App class, and then you will have everything mentioned before.
The picture below is a mind map made by Kaka from the middle waist. The previous one is not there, and all the knowledge points in the back will be written in this mind map.
After executing the run method, it will be executedContainer::get('app')->run()- >send()
Send method, how many people would think that the send method is executed in the App class.
Actually no, think back to the response result returned after executing the controller method before?
If you don’t look at it very roughly, you will remember that it is an object instance of Response.
So the send method will be executed in the response class.
Don’t look at anything else first, let’s look at this line of code first$this->app['hook' ]
, now do you know where it is executed?
This form is to access the properties of the object by accessing the array form, which is the ArrayAccess class parsed before. When the accessed attribute does not exist, offsetGet is executed, and then the magic method __get is executed, and finally the instance is returned through the make method. All these operations are performed in the container.
I will not analyze what this line of code is specifically monitoring.
Then you need to look at the line of code that processes the output data$data = $this->getContent();
What this method does is to pass the The data is assigned to the content attribute of this class.
In fact, in this method of getting the output data, please look at the first place circled. It feels very unnecessary.
It can be seen that there is no processing of the data at all, it is just returned. Therefore, the framework has good and bad points. Only if you read it will you know, otherwise you will be wrong about it. Know nothing about the tools you use regularly.
The next step is Trace debugging injection, which is configured through the configuration file and implemented by calling the debug class, which will not be explained in detail here.
Then there is caching judgment. Caching will be discussed separately in the following article, so it is also passed.
The next step is to set the response header and detect whether the HTTP header has been sent. This is very important, and it is also a knowledge point that is rarely exposed to.
The last step is, it’s coming, it’s coming, it’s coming with echo Now, a method $this->sendData($data);
is executed, giving people the feeling of a daughter-in-law becoming a mother. Finally, when she reaches the terminal, an echo outputs I feel so sad for dozens of days!
In order to reach this echo Kaka, I went through nine or nine or eighty-one difficulties! The battle has not stopped yet, comrades still need to work hard!
Then go here about the framework execution and then go to application initialization, then to route detection, instantiation of the controller, and then return to the response instance, through the entrance The file executes the send method.
Finally output the data to the terminal, which is an echo thing.
Although the battle here is over, there is still a very important knowledge point below, and Kaka will mention it again to explain it.
In the previous section, Container::get( 'app')->run()->send();
The send method is executed in the response class and the data is output.
But after outputting the data, a method fastcgi_finish_request();
is also executed. The comment is to improve the page response. Let’s take a closer look at the mystery.
See this passage on the PHP official website
The script will still occupy a FPM process after fastcgi_finish_request(). So using it excessively for long running tasks may occupy all your FPM threads up to pm.max_children. This will lead to gateway errors on the webserver.
After fastcgi_finish_request(), the script will still occupy the FPM process. So overusing it for long running tasks may tie up all your FPM threads up to pm.max_children. This will cause a gateway error on the web server.
So don’t use this method in your own projects without a thorough understanding of this method.
Next, Kaka will use a case to demonstrate the use of this method. It is just a demonstration. If you need to use it in a project, please read the document carefully and pay attention to the issues.
Case Demonstration
The company has a business that needs to send notifications to users, but because the sending time is too long, it is very time-consuming. It may take dozens of seconds, or more seriously, it will directly cause the browser connection to time out.
One problem is the user experience. The user’s waiting time process is of course not good.
In order to solve the above two problems, the fastcgi_finish_request
discussed today comes in handy.
Understanding
The understanding of this function is actually to send a response to the browser. The user's waiting time is greatly shortened, but the PHP process is still running.
This achieves a purpose, which is similar to the asynchronous execution we often talk about.
Intuitively speaking, it may take 10 seconds to send an email, but the user is not aware of it. After the user clicks to send the email, it will directly return that the sending is successful, the browser response ends, the user does other things, and the background process continues. Perform the task of sending emails.
Case
Specific code
<span style="display: block; background: url(https://files.mdnice.com/point.png); height: 30px; width: 100%; background-size: 40px; background-repeat: no-repeat; background-color: #282c34; margin-bottom: -7px; border-radius: 5px; background-position: 10px 10px;"></span><code class="hljs" style="overflow-x: auto; padding: 16px; color: #abb2bf; display: -webkit-box; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; padding-top: 15px; background: #282c34; border-radius: 5px;"><span class="hljs-meta" style="color: #61aeee; line-height: 26px;"><?php</span><br/><span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br/> * 设置超时时间,变成不限制<br/> *<br/> */</span><br/>set_time_limit(<span class="hljs-number" style="color: #d19a66; line-height: 26px;">0</span>);<br/><br/><span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br/> * 本函数模拟非常耗时的任务,执行完毕需要5秒的时间<br/> */</span><br/><span class="hljs-function" style="line-height: 26px;"><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">function</span> <span class="hljs-title" style="color: #61aeee; line-height: 26px;">writeFile</span><span class="hljs-params" style="line-height: 26px;">()</span><br/></span>{<br/> $path = <span class="hljs-string" style="color: #98c379; line-height: 26px;">'D:/phpstudy_pro/WWW/kaka.txt'</span>;<br/> file_put_contents($path,<span class="hljs-string" style="color: #98c379; line-height: 26px;">'程序运行开始'</span> . PHP_EOL,FILE_APPEND);<br/> <span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">for</span>($i =<span class="hljs-number" style="color: #d19a66; line-height: 26px;">0</span>;$i < <span class="hljs-number" style="color: #d19a66; line-height: 26px;">5</span>;$i++) {<br/> file_put_contents($path,time() . PHP_EOL,FILE_APPEND);<br/> sleep(<span class="hljs-number" style="color: #d19a66; line-height: 26px;">1</span>);<br/> }<br/><br/> file_put_contents($path,<span class="hljs-string" style="color: #98c379; line-height: 26px;">'程序运行结束'</span> . PHP_EOL,FILE_APPEND);<br/><br/>}<br/><br/><span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br/> * 输出文字标记,任务开始<br/> */</span><br/><span class="hljs-keyword" style="color: #c678dd; line-height: 26px;">echo</span>(<span class="hljs-string" style="color: #98c379; line-height: 26px;">'任务开始'</span>);<br/><br/><span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br/> * 后台执行非常耗时的任务<br/> */</span><br/>register_shutdown_function(writeFile);<br/><br/><span class="hljs-comment" style="color: #5c6370; font-style: italic; line-height: 26px;">/**<br/> * 立即发送请求<br/> */</span><br/>fastcgi_finish_request();<br/><br/><br/><br/></code>
The above tests are all conducted using the Linux system, otherwise you will not see the intuitive effect.
After the above demonstration, the response is very fast. After the browser responds, the background program still executes a timestamp every second.
The above is a brief introduction to the fastcgi_finish_request
method. If you are also interested, you can give it a simple try, which will help you better understand the little secrets.
Kaka should have analyzed this feature two years ago,trait
is what is often called a super class.
This feature was only added in PHP5.4. This feature is not a frequently used interface nor a class.
This feature is to solve a major weakness of PHP, which is that it can only have single inheritance. However, it cannot be called multiple inheritance. To be more rigorous, it is just a function similar to multiple inheritance.
Next I will show you a case.
Create test file 1 and return the corresponding class name.
Create the test1 file and return the corresponding class name
creates a controller file to output information.
Then introduce the corresponding super class file in the controller. What needs to be noted here is the first circled box, this The frame is to directly introduce the super class test file.
Then you can access it directly and see what will be returned.
Accessing the results through the above picture, you can see that the method that returns the Test super class file is also based on the Controller controller. , which is why the super class mentioned at the beginning of the article just implements a function of multiple inheritance.
But there will be a problem here, please see the error message below.
The error message in the above picture is caused by the use of two superclasses in the controller, which is how the following picture is used. .
So how to solve this error message! Next, follow the rhythm of this click.
Resolving error messages
Before solving the previous problem, you must first understand what caused this problem.
The reason for this error is that the two traits referenced have hello functions with the same name, and there is a conflict.
But this situation can be avoided in daily development, because it is still very convenient to change the method name manually, but here Kaka teaches you how to solve this problem.
The first is to use the hello method in one trait to overwrite the method of the same name in another trait. Because the contents of the two methods are consistent, I directly choose insteadof to cover here;
The second is to They use as aliases so there won't be conflicts. The as keyword has another use, which is to modify the access control of a method.
After the changes in the above picture, visit again and take a look at the returned results.
Then some partners will have questions at this time, that is, the case printing result is always the method of the Test class, and the method of the Test1 class is always No printing is performed.
How to access it! Let’s take a look.
From the above figure, you can see that the access method has been changed to an alias to control access, and then let’s take a look at the access results.
As you can see from the above figure, the return result is the return result of the super class Test1 class.
So regarding the use of as, you need to search for how to use it. Sometimes you can learn a lot of knowledge by paying attention to the details.
This is it for the source code analysis of the controller. Kaka will give it to you through the source code. Analyze how the controller is instantiated.
The calling relationship between ArrayAccess and magic methods is also discussed again. You must have your own thinking to think about the problem.
This is how to respond to data after accessing the controller, etc.
I also learned about the clever use of fastcgi_finish_request method in the source code, but when using this function, you must pay attention to the two points mentioned about Kaka.
Finally, there is a simple case description of the super class.
“Persistence in learning, persistence in blogging, and persistence in sharing are the beliefs that Kaka has always adhered to since his career. I hope that Kaka’s articles in the huge Internet can bring you a little Silk help. I’m Kaka, see you next time.
The above is the detailed content of Features fastcgi_finish_request and trait used by ThinkPHP framework. For more information, please follow other related articles on the PHP Chinese website!