Home  >  Article  >  PHP Framework  >  ThinkPHP about the difference between ArrayAccess and direct magic access return instance

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

咔咔
咔咔Original
2020-12-29 11:31:491591browse
"

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

"

Preface

#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');

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

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.

1. Instantiation Controller

#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.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

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.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

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

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

Next, take a look at the code of this method. Middleware is used here. 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.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

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).

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

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.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

Explain the abstract class

  • Abstract classes cannot be instantiated
  • A class with an abstract method must be an abstract class; the class must be decorated with abstract
  • Abstract method There cannot be a function body; that is, abstract function fun();
  • Non-abstract methods in abstract classes can be called by subclasses
  • Non-abstract The subclass inherits the abstract class, and the subclass must implement all the abstract methods of the parent class
  • Abstract subclasses inherit the abstract class, and there is no need to inherit the abstract methods of the parent class

According to the principle of the above figure, you can see that DispatchThis 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.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

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.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

Come tothinkphp/library/think/route/dispatch/Module.phpViewexecmethod.

Then the next task is to conduct an in-depth interpretation of this method.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

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.phpThis class. In the constructor of this class, you can see that the attribute for app is An App instance is assigned.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

Then when you come to the App class, you can see that it is inherited from the Container class.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

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.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

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!

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

Then the listen method of the hook will be executed to monitor the behavior of the tag.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

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.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

Then the code will be executed until$results[$key] = $this ->execTag($name, $tag, $params);Here.

Parameter description

  • $name = string(22) "behavior\LoadBehavior"
  • $tag = module_init

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.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

2. Regarding the difference between ArrayAccess and direct execution of magic access to return instances

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.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

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.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

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.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

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.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

Let’s first take a look at the value of this app and print it out as think\App Object object.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

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.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

Then the __get method will be executed, and the make method will be executed to return the corresponding instance.

ThinkPHP about the difference between ArrayAccess and direct magic access return 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.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

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.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

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.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

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.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

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.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

Then execute the make method to create an instance of the class.

ThinkPHP about the difference between ArrayAccess and direct magic access return instance

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

  • #__get is for the attributes of the class. When the attributes of the class do not exist, it will be executed.
  • ArrayAccess is used to access the instantiated class in the form of an array. When, if it does not exist, the offsetGet method will be executed.
    Recommended tutorial: "thinkphp"

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!

Statement:
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