"This article will instantiate the controller as a primer and then analyze the difference between ArrayAccess and directly executing magic access to return the instance
"
#In the above section, routing is explained in detail, starting from application initialization to route scheduling. Return to the routing detection link.
The value obtained by route detection is as shown below, which is the value finally returned by route scheduling.
The routing rule used is Route::get('hello/:name', 'index/index/:name');
As can be seen from the above figure, important data are stored in dispatchc, then The controller will be explained in detail below.
The first thing to explain is the instantiation controller operation performed after the routing detection is completed.
Let’s first take a look at how to execute the instantiation controller!
There is no doubt that the code must be executed first from the entry file. Here, the container is used to return an instance of App, and then the run method in the App class is called.
When you come down, you will come to the execution application. In this method, it is also the route just parsed above.
So after the detection route is executed, the instantiated controller will be executed.
After the route detection is executed, the class think\route\dispatch\Module Object
is returned. And this class is assigned to the variable $dispatch
Then let’s take a look at the code of this method. Here we use What is middleware is that closures are still used in this quick code. If you are not clear about the concept of closures, you need to go back to the basics.
The place circled in the picture above is the code $dispatch->run()
. Next, we need to analyze this piece of code.
After detecting the final return value of the route, we can know that this method is actually in the think\route\dispatch\Module
class.
Then you need to analyze the run method in this class, which is to perform routing scheduling.
In this method, neither obtaining routing parameters nor detecting routing, nor automatic data verification will be executed (this is based on the routing address given above by Kaka as an example).
So according to the above code, the code will be executed to$data = $this->exec();
here.
Tracing this method will lead to the existence of an abstract class in the picture below. What you need to know here is the abstract class.
Explain the abstract class
According to the principle of the above figure, you can see that Dispatch
This class is an abstract class.
So there will be two situations. One is that the abstract class inherits the abstract class without inheriting the abstract method of the parent class.
The other is that non-abstract subclasses inherit abstract classes, and the subclass must implement all abstract methods of the parent class.
How to find who has inherited Dispatch
Do you have a question at this time? How to find the subclass of Dispatch.
You can see this type of Dispatch in this picture, but there is also a dispatch directory.
According to the data returned by route detection, you can easily know that it is the class thinkphp/library/think/route/dispatch/Module.php
.
Come tothinkphp/library/think/route/dispatch/Module.php
Viewexec
method.
Then the next task is to conduct an in-depth interpretation of this method.
Look at the first line of code first$this->app['hook']->listen( 'module_init');
, here the container ArrayAccess is used to access the object in the form of an array, and then execute the magic method __get. When accessing a non-existent attribute, the make method will be executed.
Use the editor to track this app and you will go to thinkphp/library/think/route/Dispatch.php
This class. In the constructor of this class, you can see that the attribute for app is An App instance is assigned.
Then when you come to the App class, you can see that it is inherited from the Container class.
I have talked about this knowledge point more than once in the context of containers. To access non-existent properties, go back and execute the __get magic method of the container. .
So the parameters of this block will be passed into the hook, and the instance of the hook will be returned. About this How the instance is returned is explained in detail in the container section, you can check it out!
Then the listen method of the hook will be executed to monitor the behavior of the tag.
At this time, you can come to the application behavior extension definition file. You can see that this parameter is initialized for the module, but because this value is empty.
So it will not be executed in the above picture, so put the application initialization value into this parameter for a simple test.
This class is the execution hook, the optimization operation of the facade class.
Then the code will be executed to$results[$key] = $this->execTag($name, $ tag, $params);
Here.
Parameter description
Then the passed parameters are processed through regular expressions, and finally moduleInit is returned
Then pass $obj = Container::get($class);
Return the instance of behavior\LoadBehavior
Finally, verify through the function is_callable
to detect whether the method in the class can be called, the method array format, this method will be written in a separate article later To parse it as an object, you only need to know that false will be returned.
Then the $portal
value of this class will be assigned to $method
, and this value is run.
Finally pass$result = $this->app->invoke($call, [$params]);
This line of code, the bottom execution of this line of code is through reflection implemented by the mechanism.
The last code will return NULL.
Instance Controller
The next step is to instantiate the controller. The calling method is $this->app->controller()
What needs to be noted here is the list function, this An array will be returned at the end of the function, and the two variables in the list will be indexes 0 and 1 respectively.
The judgment will also execute the first one, and it will also execute the make method of the container class. This method will directly return the instance of app\index\controller\Index
.
Some friends have learned the use of ArrayAccess and the magic method __get.
It is estimated that some of them are in ambiguous areas in these two places. Kaka will put these two together and analyze them once.
Let’s talk about the use of ArrayAccess first
This case has been demonstrated to you before, mainly to implement the ArrayAccess class.
Then when you come to the controller for use, instantiate it first. The previously implemented case is as follows.
But the case that needs to be implemented this time is not what is implemented in the figure below.
Next, use the method shown in the figure below to access the object properties directly using the array.
In the picture above, you can see that an attribute title is set to kaka. In this case, it can be obtained directly in the form of an array.
See that the return result is kaka, which means that the properties of the object are directly accessed in array form.
Summary
In the implementation process of the first case, one step was ignored, which is to use the object to directly access the properties of the object in the form of an array.
What you can see can be obtained directly, so let’s put this idea into the framework and take a look.
Framework practical case
The following code exists in the routing parsed in the previous article. Let’s briefly analyze it.
Let’s first take a look at the value of this app. The printed value is the think\App Object
object.
When think\App Object
this object accesses request
, because The app attribute does not have this request
, and because the app class inherits the container class, it will go to the container class to execute the method below.
Then the __get method will be executed, and the make method will be executed to return the corresponding instance.
If you still have questions at this time, why does it just say it will be executed and it will be executed!
Next, Kaka will take everyone to do a simple test and you will know.
Print a random value in this position.
Then go to the offsetGet method of ArrayAccess of the container class and print the passed value.
Looking at the print results, it is very clear.
That’s it for the use of ArrayAccess That’s it. This is also a detailed explanation based on the previous one. Next, we will explain the __get method in the container in detail to see under what circumstances the __get method will be executed.
____get method usage detailed explanation
For this case, please see the $this->hook
in the picture below.
For the same reason, let’s first debug the value of $this
.
There is no need to print this value, because it is in this class.
The attributes in the class should be accessible, just use $this->
directly.
So when the system accesses $this->hook
, since the App class does not have the hook attribute, it will execute the magic method of the container class.
Then execute the make method to create an instance of the class.
Summary
So we use ArrayAccess and __get magic methods, and ultimately the executed make method returns an instance of the class.
When encountering this->config is the __get method of the container that is executed.
When encountering app['request'], ArrayAccess is executed and then offsetGet is executed.
offsetGet
method will be executed. The above is the detailed content of ThinkPHP about the difference between ArrayAccess and direct magic access return instance. For more information, please follow other related articles on the PHP Chinese website!