Detailed introduction to php caching technology and implementation code of php caching

高洛峰
Release: 2016-11-29 10:18:47
Original
973 people have browsed it

Some information, such as information that is often constant but can still change, is placed in the cache to speed up the display. This is very valuable. The so-called cache is generally understood to be some shared information stored on the server side. It is The server is the same as life and death. When saving the cache, we can specify the time of the next update. For example, it should be updated every 5 minutes. Data cache: The data cache mentioned here refers to the database query PHP cache mechanism. Each visit When entering a page, it will first detect whether the corresponding cached data exists. If it does not exist, it will connect to the database, obtain the data, and serialize the query results and save them to the file. In the future, the same query results will be directly obtained from the cache table or file. get.

The most widely used example is the search function of Discuz, which caches the result ID into a table and searches the cache table first when searching for the same keyword next time.

As a common method, when multiple tables are associated, generate an array and save the contents in the attached table to a field in the main table. When necessary, decompose the array. This has the advantage of only reading one table, but has two disadvantages. There will be many more steps to synchronize the data. The database is always the bottleneck. Trading the hard disk for speed is the key point.

Page caching:

Every time you visit a page, it will first detect whether the corresponding cached page file exists. If it does not exist, connect to the database, get the data, display the page and generate a cached page file at the same time, so that the next time you visit That's when the page file comes into play. (Template engines and some common PHP caching mechanism classes on the Internet usually have this function)

Time-triggered caching:

Check whether the file exists and the timestamp is less than the set expiration time, if the timestamp of the file modification is less than the current timestamp If the expiration timestamp is large, then use the cache, otherwise update the cache.

Content-triggered caching:

Force the PHP cache mechanism to be updated when data is inserted or updated.

Static caching:

The static caching mentioned here refers to static caching, which directly generates text files such as HTML or XML, and regenerates them when there are updates. It is suitable for pages that do not change much, so I won’t talk about it here.

The above content is a code-level solution. I directly CP other frameworks and am too lazy to change. The contents are similar, it is easy to do, and can be used in several ways, but the following content is a server-side caching solution. Non-code level, it requires the cooperation of multiple parties to achieve it

Memory cache:

Memcached is a high-performance, distributed memory object PHP caching mechanism system, used to reduce database load and improve access speed in dynamic applications.

PHP buffer:

There are eaccelerator, apc, phpa, xcache, I won’t talk about these. Search a bunch of them and see for yourself. If you know this thing, it’s OK

MYSQL cache:

This is also considered non-code level. Classic databases use this method. Look at the running time below, 0.09xxx and the like

I will post the modified part of my.ini based on the blue guy, 2G MYISAM table It can be around 0.05S. It is said that he has changed it for almost a year


Web cache based on reverse proxy:

such as Nginx, SQUID, mod_proxy (apache2 and above are divided into mod_proxy and mod_cache)

Example of NGINX


Usage Google found some PHP caching technology methods

Send me a PHP caching implementation, which implements apc and file caching. By inheriting Cache_Abstract, you can call third-party caching tools.


Refer to shindig’s cache class and apc.

<?php   
class CacheException extends Exception {}   
/**  
 * <a href="http://www.php.cn/category/79.html">缓存</a>抽象类  
 */  
abstract class Cache_Abstract {   
    /**  
     * 读<a href="http://www.php1.cn/category/79.html">缓存</a>变量  
     *  
     * @param string $key <a href="http://www.php.cn/category/79.html">缓存</a>下标  
     * @return mixed  
     */  
    abstract public function fetch($key);   
        
    /**  
     * <a href="http://www.php.cn/category/79.html">缓存</a>变量  
     *  
     * @param string $key <a href="http://www.php.cn/category/79.html">缓存</a>变量下标  
     * @param string $value <a href="http://www.php.cn/category/79.html">缓存</a>变量的值  
     * @return bool  
     */  
    abstract public function store($key, $value);   
        
    /**  
     * 删除<a href="http://www.php.cn/category/79.html">缓存</a>变量  
     *  
     * @param string $key <a href="http://www.php.cn/category/79.html">缓存</a>下标  
     * @return Cache_Abstract  
     */  
    abstract public function delete($key);   
        
    /**  
     * 清(删)除所有<a href="http://www.php.cn/category/79.html">缓存</a>  
     *  
     * @return Cache_Abstract  
     */  
    abstract public function clear();   
        
    /**  
     * 锁定<a href="http://www.php.cn/category/79.html">缓存</a>变量  
     *  
     * @param string $key <a href="http://www.php.cn/category/79.html">缓存</a>下标  
     * @return Cache_Abstract  
     */  
    abstract public function lock($key);   
    
    /**  
     * <a href="http://www.php.cn/category/79.html">缓存</a>变量解锁  
     *  
     * @param string $key <a href="http://www.php.cn/category/79.html">缓存</a>下标  
     * @return Cache_Abstract  
     */  
    abstract public function unlock($key);   
    
    /**  
     * 取得<a href="http://www.php.cn/category/79.html">缓存</a>变量是否被锁定  
     *  
     * @param string $key <a href="http://www.php.cn/category/79.html">缓存</a>下标  
     * @return bool  
     */  
    abstract public function isLocked($key);   
    
    /**  
     * 确保不是锁定状态  
     * 最多做$tries次睡眠等待解锁,超时则跳过并解锁  
     *  
     * @param string $key <a href="http://www.php.cn/category/79.html">缓存</a>下标  
     */  
    public function checkLock($key) {   
        if (!$this->isLocked($key)) {   
            return $this;   
        }   
            
        $tries = 10;   
        $count = 0;   
        do {   
            usleep(200);   
            $count ++;   
        } while ($count <= $tries && $this->isLocked($key));  // 最多做十次睡眠等待解锁,超时则跳过并解锁   
    
        $this->isLocked($key) && $this->unlock($key);   
            
        return $this;   
    }   
}   
    
    
/**  
 * APC扩展<a href="http://www.php.cn/category/79.html">缓存</a>实现  
 *   
 *   
 * @category   Mjie  
 * @package    Cache  
 * @author     流水孟春  
 * @copyright  Copyright (c) 2008- <cmpan(at)qq.com>  
 * @license    New BSD License  
 * @version    $Id: Cache/Apc.php 版本号 2010-04-18 23:02 cmpan $  
 */  
class Cache_Apc extends Cache_Abstract {   
        
    protected $_prefix = &#39;cache.mjie.net&#39;;   
        
    public function __construct() {   
        if (!function_exists(&#39;apc_cache_info&#39;)) {   
            throw new CacheException(&#39;apc extension didn&#39;t installed&#39;);   
        }   
    }   
        
    /**  
     * 保存<a href="http://www.php.cn/category/79.html">缓存</a>变量  
     *  
     * @param string $key  
     * @param mixed $value  
     * @return bool  
     */  
    public function store($key, $value) {   
        return apc_store($this->_storageKey($key), $value);   
    }   
        
    /**  
     * 读取<a href="http://www.php.cn/category/79.html">缓存</a>  
     *  
     * @param string $key  
     * @return mixed  
     */  
    public function fetch($key) {   
        return apc_fetch($this->_storageKey($key));   
    }   
        
    /**  
     * 清除<a href="http://www.php.cn/category/79.html">缓存</a>  
     *  
     * @return Cache_Apc  
     */  
    public function clear() {   
        apc_clear_cache();   
        return $this;   
    }   
        
    /**  
     * 删除<a href="http://www.php.cn/category/79.html">缓存</a>单元  
     *  
     * @return Cache_Apc  
     */  
    public function delete($key) {   
        apc_delete($this->_storageKey($key));   
        return $this;   
    }   
        
    /**  
     * <a href="http://www.php.cn/category/79.html">缓存</a>单元是否被锁定  
     *  
     * @param string $key  
     * @return bool  
     */  
    public function isLocked($key) {   
        if ((apc_fetch($this->_storageKey($key) . &#39;.lock&#39;)) === false) {   
            return false;   
        }   
            
        return true;   
    }   
        
    /**  
     * 锁定<a href="http://www.php.cn/category/79.html">缓存</a>单元  
     *  
     * @param string $key  
     * @return Cache_Apc  
     */  
    public function lock($key) {   
        apc_store($this->_storageKey($key) . &#39;.lock&#39;, &#39;&#39;, 5);   
        return $this;   
    }   
        
    /**  
     * <a href="http://www.php.cn/category/79.html">缓存</a>单元解锁  
     *  
     * @param string $key  
     * @return Cache_Apc  
     */  
    public function unlock($key) {   
        apc_delete($this->_storageKey($key) . &#39;.lock&#39;);   
        return $this;   
    }   
        
    /**  
     * 完整<a href="http://www.php.cn/category/79.html">缓存</a>名  
     *  
     * @param string $key  
     * @return string  
     */  
    private function _storageKey($key) {   
        return $this->_prefix . &#39;_&#39; . $key;   
    }   
}   
    
/**  
 * 文件<a href="http://www.php.cn/category/79.html">缓存</a>实现  
 *   
 *   
 * @category   Mjie  
 * @package    Cache  
 * @author     流水孟春  
 * @copyright  Copyright (c) 2008- <cmpan(at)qq.com>  
 * @license    New BSD License  
 * @version    $Id: Cache/File.php 版本号 2010-04-18 16:46 cmpan $  
 */  
class Cache_File extends Cache_Abstract {   
    public $useSubdir     = false;   
        
    protected $_cachesDir = &#39;cache&#39;;   
        
    public function __construct() {   
        if (defined(&#39;DATA_DIR&#39;)) {   
            $this->_setCacheDir(DATA_DIR . &#39;/cache&#39;);   
        }   
    }   
        
    /**  
     * 获取<a href="http://www.php.cn/category/79.html">缓存</a>文件  
     *  
     * @param string $key  
     * @return string  
     */  
    protected function _getCacheFile($key) {   
        $subdir = $this->useSubdir ? substr($key, 0, 2) . &#39;/&#39; : &#39;&#39;;   
        return $this->_cachesDir . &#39;/&#39; . $subdir . $key . &#39;.php&#39;;   
    }   
    
    /**  
     * 读取<a href="http://www.php.cn/category/79.html">缓存</a>变量  
     * 为防止信息泄露,<a href="http://www.php.cn/category/79.html">缓存</a>文件格式为php文件,并以"<?php exit;?>"开头  
     *   
     * @param string $key <a href="http://www.php.cn/category/79.html">缓存</a>下标  
     * @return mixed  
     */  
    public function fetch($key) {   
        $cacheFile = self::_getCacheFile($key);   
        if (file_exists($cacheFile) && is_readable($cacheFile)) {   
            // include 方式   
            //return include $cacheFile;   
            // 系列化方式   
    
            return unserialize(@file_get_contents($cacheFile, false, NULL, 13));   
        }   
    
        return false;   
    }   
    
    /**  
     * <a href="http://www.php.cn/category/79.html">缓存</a>变量  
     * 为防止信息泄露,<a href="http://www.php.cn/category/79.html">缓存</a>文件格式为php文件,并以"<?php exit;?>"开头  
     *  
     * @param string $key <a href="http://www.php.cn/category/79.html">缓存</a>变量下标  
     * @param string $value <a href="http://www.php.cn/category/79.html">缓存</a>变量的值  
     * @return bool  
     */  
    public function store($key, $value) {   
        $cacheFile = self::_getCacheFile($key);   
        $cacheDir  = dirname($cacheFile);   
    
        if(!is_dir($cacheDir)) {   
            if(!@mkdir($cacheDir, 0755, true)) {   
                throw new CacheException("Could not make cache directory");   
            }   
        }   
    // 用include方式   
        //return @file_put_contents($cacheFile, &#39;<?php return &#39; . var_export($value, true). &#39;;&#39;);   
    
        return @file_put_contents($cacheFile, &#39;<?php exit;?>&#39; . serialize($value));   
    }   
    
    /**  
     * 删除<a href="http://www.php.cn/category/79.html">缓存</a>变量  
     *  
     * @param string $key <a href="http://www.php.cn/category/79.html">缓存</a>下标  
     * @return Cache_File  
     */  
    public function delete($key) {   
        if(emptyempty($key)) {   
            throw new CacheException("Missing argument 1 for Cache_File::delete()");   
        }   
            
        $cacheFile = self::_getCacheFile($key);   
        if(!@unlink($cacheFile)) {   
            throw new CacheException("Cache file could not be deleted");   
        }   
    
        return $this;   
    }   
    
    /**  
     * <a href="http://www.php.cn/category/79.html">缓存</a>单元是否已经锁定  
     *  
     * @param string $key  
     * @return bool  
     */  
    public function isLocked($key) {   
        $cacheFile = self::_getCacheFile($key);   
        clearstatcache();   
        return file_exists($cacheFile . &#39;.lock&#39;);   
    }   
    
    /**  
     * 锁定  
     *  
     * @param string $key  
     * @return Cache_File  
     */  
    public function lock($key) {   
        $cacheFile = self::_getCacheFile($key);   
        $cacheDir  = dirname($cacheFile);   
        if(!is_dir($cacheDir)) {   
            if(!@mkdir($cacheDir, 0755, true)) {   
                if(!is_dir($cacheDir)) {   
                    throw new CacheException("Could not make cache directory");   
                }   
            }   
        }   
    
        // 设定<a href="http://www.php.cn/category/79.html">缓存</a>锁文件的访问和修改时间   
        @touch($cacheFile . &#39;.lock&#39;);   
        return $this;   
    }   
      
    /**  
     * 解锁  
     *  
     * @param string $key  
     * @return Cache_File  
     */  
    public function unlock($key) {   
        $cacheFile = self::_getCacheFile($key);   
        @unlink($cacheFile . &#39;.lock&#39;);   
        return
Copy after login

Related labels:
php
source:php.cn
Statement of this Website
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
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template