Home >PHP Framework >ThinkPHP >In-depth analysis of ThinkPHP cache source code

In-depth analysis of ThinkPHP cache source code

咔咔
咔咔Original
2021-01-18 22:46:261887browse
"

Cache is a function that will be used after the project has been running for a period of time. This article will do an in-depth analysis of the cache in the framework

"

Preface

Caching is an essential function in the project, when the user volume When it is large, it must be cached. If you check the database directly, it will be too bad for the user experience.

So under what circumstances should cache be used?

  • Hot events, such as Weibo hot searches
  • Infrequently updated data, such as configuration items
  • Blogging platform’s ranking list
  • Social platform’s watch list, fan list, etc.

The application scenarios mentioned above are not It is said that the cache of the framework is generally not used at the cache level.

Commonly used are redis, memcache and other NoSQL.

But today’s main discussion is caching in the framework, so don’t think that the caching of the framework is omnipotent, it still depends on the actual situation of the project.

1. Execution process of cache cache setting and source code analysis

First, you need to implement the following cases and introduce cache class

In-depth analysis of ThinkPHP cache source code
Demo case

How does cache run?

Just the codeCache::setDo you know how this works now? If you don’t know Kaka, I’ll take you to learn it in depth.

We all know that the entry file of the framework is index.php, and a file named base.php is introduced in the entry file.

In-depth analysis of ThinkPHP cache source code
Entry file

Go to the base.php file and you can see about the registered class library alias. As for how to register, this is executed in the framework There is an in-depth explanation in the section on the process, you can go back and learn more.

In-depth analysis of ThinkPHP cache source code
Register class library alias

So the code will be executed in the facade class at the core of the framework. There is a method __callStatic in this class. This method is executed when a non-existent static method is called.

In-depth analysis of ThinkPHP cache source code
The core class of the facade

So how to do this verification! You can’t just say this, that’s how it is, right?

Then the code will then come to the method of creating a Facade instance. The test we do is to print out the value of this class.

In-depth analysis of ThinkPHP cache source code
Create Facade instance

Regardless of how many times this cache has been executed, you can clearly see that this value exists in the print result, so from another The clumsy aspects verified Kaka's rhetoric.

In-depth analysis of ThinkPHP cache source code
Printed test value

There is a very small detail here that I think everyone should know about, that is about the use of static

Tips about static

First of all, you can see that the cache class inherits the Facade facade class

In-depth analysis of ThinkPHP cache source code
.
##Then static is used in the facade class, then the final returned class is the class that inherits the facade class, which is the cache class

Facade class demonstrationIn-depth analysis of ThinkPHP cache source code
It can be summarized in one sentence as

static If it is inherited, the subclass will be called by default, otherwise it will call itself

So let’s continue below The

static::getFacadeClass()

here is also the method in the subclass that is executed. <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">Okay, we have entered a small interlude, and then we will get to the main topic. </p> <p data-tool="mdnice编辑器" style="padding-top: 8px; padding-bottom: 8px; line-height: 1.75; margin-top: 0.8em; margin-bottom: 0.8em;">So the code will be executed to the file <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27,31,35,.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgb(271, 93, 108);">thinkphp/library/think/Cache.php, which is the location of the core class library.

You cannot find the set method in this method, so the code will be executed to the __call method, which will be triggered when a non-existent method is called.

In-depth analysis of ThinkPHP cache source code
Cache class

Automatic initialization of cache

According to the execution process we will see the init method Automatically initialize the cache (it should be noted here that the first time is not executed here, but the make method. When the make method is executed, the value will be stored in the handler attribute. The second time it comes in through the call method, it will return directly. , instead of executing it once, you must pay attention here)

In-depth analysis of ThinkPHP cache source code
Automatically initialize the cache

Here we print once$options The value of this.

In-depth analysis of ThinkPHP cache source code
Print results

Discuss why the $options parameter has a value

This is about the container knowledge, come to Kaka to show you.

In-depth analysis of ThinkPHP cache source code
make method

When creating a Cache, create a Facade instance. During this process, pay attention to the area circled in the picture below, and execute a This is the make method.

In-depth analysis of ThinkPHP cache source code
Create Facade instance

When you come to the make method, just look at the circled area

In-depth analysis of ThinkPHP cache source code第二次执行的位置
The location where the make method is executed for the second time

Then enter the invokeClass method. This method calls the instantiation of the reflection execution class to support dependency injection.

In this method, the make method in Cache is executed through reflection.

调用反射执行类的实例化 支持依赖注入
Call the instantiation of the reflection execution class to support dependency injection

So the make method in the Cache class will be executed, and this method will instantiate this class and execute the constructor, let’s take a look next.

缓存类的In-depth analysis of ThinkPHP cache source code
The make method of the cache class

When you come to the constructor, you will see that the configuration items of the cache configuration file obtained from the make method are passed into the init method. That is the part that automatically initializes the cache.

In-depth analysis of ThinkPHP cache source code
Constructor

So from here you can see that the init method automatically initializes the cache. The first execution is executed when the container is instantiated, so $options will have a value.

Next, we will follow this process to perform connection caching, which is the content of the code $this->handler = $this->connect($options);.

This method is very simple. It uses the factory mode that has been explained before to load different types of cache.

Then the returned object will be stored in the cache instance attribute $instance with $optionsmd5 as the subscript.

In-depth analysis of ThinkPHP cache source code
Connection cache

The final code will be returned to the __call method in cache, the class is object(think\cache\driver\File) The method is set

In-depth analysis of ThinkPHP cache source code
When a method that does not exist is called, it will be executed

Then the execution process will come to the location shown below and write Cache

In-depth analysis of ThinkPHP cache source code
Write cache

Get the file name

The main thing you need to understand in this method The thing is how to get the specific file name in the cache and then store the data.

This name value is the value we need to set, wechat.

In-depth analysis of ThinkPHP cache source code
Get the storage file name of the variable

Then go to getCacheKey to get the storage file name of the variable.

The first step in this method is to encrypt the type and cache value through hashing. These options are declared in this class and must be made clear here.

Because the options variable is used extensively in the framework, do not confuse it.

What you need to understand in this method is how the file name is determined.

In-depth analysis of ThinkPHP cache source code
Get the file name

You still have to go to the beginning of this class to check the value of this options. In this class you can see the picture above The encryption type used is hash_type which is md5

In-depth analysis of ThinkPHP cache source code
About the value cached to the file

Then come to the constructor and you can see the settings for the path

In-depth analysis of ThinkPHP cache source code
Get the path of the cache file

You can see the line of code Container::get('app') in the above picture, This line of code uses the container to execute the make method. The make method plays a very important role in the container, so it needs to be understood carefully.

Then there is a small detail that I don’t know if you have seen, that is, there is an init method below. Let’s go and see what this method does.

After coming to this method, you will find that the file is created directly according to the path of the obtained cache file.

In-depth analysis of ThinkPHP cache source code
Initialization check

At this time, you can check the created file and you can see that the file has been created.

In-depth analysis of ThinkPHP cache source code
The path of the cache file

Finally, use the file_put_contents function to store the data to the cache file storage location just obtained

In-depth analysis of ThinkPHP cache source code
Write data in the cache file

The database storage form is as shown below

In-depth analysis of ThinkPHP cache source code
Data storage form

Until This is the end of the framework cache settings. In fact, the process is not difficult. In this case, the file format used by Kaka is the same as for redis or others.

2. Execution process of cache cache acquisition and source code analysis

Now that we have learned the source code analysis of cache settings, Then we should also briefly understand the source code analysis obtained by cache.

The same demonstration case is the same as before, just replace set with get

In-depth analysis of ThinkPHP cache source code
Demonstration case

The process is the same as setting up the cache. First, you will go to the facade class to create the corresponding instance of the cache

In-depth analysis of ThinkPHP cache source code
The facade class creates a cache instance

When the facade class creates the cache class, it will come to the cache class filethinkphp/library/think/Cache.php

You can see in this file that the __call method is still used. This method is to call a method that does not exist and it will be executed.

In-depth analysis of ThinkPHP cache source code
Cached files

Then you will come to the init method. This method has been explained in depth when setting the cache value.

According to the execution process, we will see that the init method automatically initializes the cache (it should be noted here that the first time it is executed is not here, but the make method. When the make method is executed, the value will be Stored in the attribute of handler, it will return directly after entering through the call method for the second time, and will not be executed again. You must pay attention here)

Why is the cache's make method executed first? This is because When creating a cache class instance in a container, it will be judged in the make method whether there is a make method in the class. If it exists, it will be executed first.

In-depth analysis of ThinkPHP cache source code
Automatically initialize the cache

So in the cache classreturn call_user_func_array([$this->init(), $method], $args );This code will executethinkphp/library/think/cache/driver/File.phpget method of this class

In-depth analysis of ThinkPHP cache source code
read cache

In this class you can see a method that took a long time to parse when setting the cache value getCacheKey

In this method, it is mainly used sbustr is used to encrypt the stanza of values, the first two values ​​are the directory, and the remaining characters are the file name.

Then return the file name.

In-depth analysis of ThinkPHP cache source code
Get the storage file name of the variable

Then use file_get_contents to get the contents of the file

In-depth analysis of ThinkPHP cache source code
Read the file content

Then you can continue to look down. There is an expired deleted cache file here.

The expiration policy in the framework is that when you set the expiration time, the cache will not be deleted directly after it expires, but will be deleted after you access it again.

This strategy is lazy deletion in redis. When we use lazy deletion, the data will not be automatically deleted when it expires. Then its deletion method is that the next time the key value is obtained, it will Make a judgment to determine whether the key has expired. If it has expired, delete it.

In-depth analysis of ThinkPHP cache source code
Expired fir tree cache files

Up to this point, the execution process of cache acquisition has been completed by source code analysis. In fact, most of the content is obtained when It has been analyzed.

Then why do we still need to talk about getting cached data? That’s because we need to explain something to you here.

3. Data compression

When setting up the cache, there was a problem when writing the cached value to the file. Functiongzcompress

However, when getting the cache value and reading the data from the file, I encountered a functiongzuncompress

In fact, from the settings It can be seen from the two functions of cache and cache acquisition that the compressed data is set and the decompressed data is obtained.

There are two other compression functions in PHP: gzdeflate and gzencode. The same decompression function also corresponds to gzinflate gzdecode

. Although the functions are all compression functions, the underlying implementations are different.

gzcompress uses the ZLIB format;

gzdeflate uses the pure DEFLATE format;

gzencode uses the GZIP format;

The above is about Just understand some knowledge about data compression and decompression.

4. Summary

In this section, Kaka takes you through the framework’s processing results of caching .

In fact, Kaka has previously tested that the cache response time that comes with the framework should be shortened by one-third. Of course, this also varies based on the amount of data.

So far, the source code interpretation of the PHP framework ThinkPHP ends here. If there is time later, I will interpret some of the content that has not been mentioned.

Finally, reading the source code is really tiring.

Persistence in learning, persistence in blogging, and persistence in sharing are the beliefs that Kaka has always upheld since his career. I hope that Kaka’s articles in Nuoda Internet can bring you Any help. I’m Kaka, see you next time.

The above is the detailed content of In-depth analysis of ThinkPHP cache source code. 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