"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
"
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?
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.
First, you need to implement the following cases and introduce cache class
How does cache run?
Just the codeCache::set
Do 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.
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.
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.
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.
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.
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
static If it is inherited, the subclass will be called by default, otherwise it will call itselfSo 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.
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)
Here we print once$options
The value of this.
Discuss why the $options parameter has a value
This is about the container knowledge, come to Kaka to show you.
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.
When you come to the make method, just look at the circled area
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.
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.
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.
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 $options
md5 as the subscript.
The final code will be returned to the __call method in cache, the class is object(think\cache\driver\File)
The method is set
Then the execution process will come to the location shown below and 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.
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.
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
Then come to the constructor and you can see the settings for the path
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.
At this time, you can check the created file and you can see that the file has been created.
Finally, use the file_put_contents function to store the data to the cache file storage location just obtained
The database storage form is as shown below
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.
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
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
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.
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.
So in the cache classreturn call_user_func_array([$this->init(), $method], $args );
This code will executethinkphp/library/think/cache/driver/File.php
get method of this class
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.
Then use file_get_contents to get the contents of the file
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.
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.
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.
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!