"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
"
#Routing is explained in detail above, starting from application initialization and parsing until route scheduling is returned to route detection.
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, and the controller will be explained in detail next.
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.
What is returned after the route detection is executed isthink\route\dispatch\Module Object
This class, and this class is assigned to the variable$dispatch
The place circled in the picture above is the code $dispatch->run()
, and the next step is It’s time 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 (the routing address given above is used 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 out who has inherited Dispatch
Is there one at this time? One question is 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 will be returned The hook instance, how this instance is returned is explained in detail in the container section, you can take a look!
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, and you can see that this parameter is the module initialization , 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 until$results[$key] = $this ->execTag($name, $tag, $params);
Here.
Parameter description
Then the passed parameters are processed through regular expressions, and finally moduleInit is returned
And then through $obj = Container::get($class);
Return an instance of behavior\LoadBehavior
Finally passed the is_callable
function to verify whether the method in the class can be called, the method array format, this method will be used to write a separate article as an object to parse, here you only need to know It will return false.
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.
Instancing the 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 function will return an array, and then 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 I come to the controller to use it, I instantiate it first and implement the case before 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, a step was ignored, which is to use objects to directly use arrays Form directly accesses the object's properties.
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 and print it out as think\App Object
object.
When think\App Object
this object accesses request
, because the app attribute does not have thisrequest
, 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 that it will be executed? It will be implemented!
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.
The use of ArrayAccess ends here. This is also explained in detail based on the previous one. Next, the __get method in the container will be explained in detail to see under what circumstances __get will be executed. method.
__Detailed explanation of how to use get method
For this case, please see $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.
You should be able to access attributes in the class, just use $this->
That’s it.
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 use ArrayAccess and The __get magic method is ultimately executed and the 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'], execute ArrayAccess and then execute offsetGet
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!