zoukankan      html  css  js  c++  java
  • CodeIgniter框架的缓存原理分解

    用缓存的目的:(手册上叙述如下,已经写得很清楚了)

    Codeigniter 支持缓存技术,以达到最快的速度。

    尽管CI已经相当高效了,但是网页中的动态内容、主机的内存CPU 和数据库读取速度等因素直接影响了网页的加载速度。 依靠网页缓存,你的网页可以达到近乎静态网页的加载速度,因为他们将程序输出的结果保存到硬盘上了。

    如何用:

    启用缓存功能,只需要将下面的代码放入你的任何一个控制器(controller)的方法(function)内:

    $this->output->cache(1);

    其中 n 是你希望缓存更新的 分钟 数。可以使用 m/60 来精确到秒,例如 1/60 ,则是精确到 1秒

    上面的代码可以放到任何一个 function 里面。他的出现顺序对缓存并没有影响,所以将它放在你认为最合乎逻辑的地方。一旦上面的代码放到了控制器的方法中,页面就会被缓存。

    注意:

    由于CI存储缓存文件的方式,只有通过 view 文件的输出才能被缓存,也即是$this->load->view('xxxx', $data); 第三个参数不能为true

    在缓存文件产生之前,请确保 application/cache 文件夹可写。

    如果你不再想使用缓存,仅需将上面的代码从你的controller里面删除即可。注意: 这样做并不能让缓存文件立即消失,它将会自动过期并被删除。如果你想立即删除那些文件,就必须自己动手了。

    原理:

    使用$this->output->cache(1); 开启缓存:

    然后是CodeIgniter.php中做判断:

    1 if ($EXT->_call_hook('cache_override') === FALSE)
    2     {
    3         if ($OUT->_display_cache($CFG, $URI) == TRUE)
    4         {
    5             exit;
    6         }
    7     }

    上面第三行代码,如果读取缓存文件成功,_display_cache方法直接输出缓存内容,然后exit掉不再往下执行

    读缓存操作:(Output Class  _display_cache方法里边)
      读缓存文件,没有返回false 
      有缓存文件 判断缓存是否过期,过期则删除缓存文件返回false
      没有过期,读取缓存内容显示 返回false
     * Update/serve a cached file
         *
         * @access    public
         * @param     object    config class
         * @param     object    uri class
         * @return    void
         */
        function _display_cache(&$CFG, &$URI)
        {
            $cache_path = ($CFG->item('cache_path') == '') ? APPPATH.'cache/' : $CFG->item('cache_path');
    
            // Build the file path.  The file name is an MD5 hash of the full URI
            $uri =    $CFG->item('base_url').
                    $CFG->item('index_page').
                    $URI->uri_string;
    
            $filepath = $cache_path.md5($uri);
    
            if ( ! @file_exists($filepath))
            {
                return FALSE;
            }
    
            if ( ! $fp = @fopen($filepath, FOPEN_READ))
            {
                return FALSE;
            }
    
            flock($fp, LOCK_SH);
    
            $cache = '';
            if (filesize($filepath) > 0)
            {
                $cache = fread($fp, filesize($filepath));
            }
    
            flock($fp, LOCK_UN);
            fclose($fp);
    
            // Strip out the embedded timestamp
            if ( ! preg_match("/(d+TS--->)/", $cache, $match))
            {
                return FALSE;
            }
    
            // Has the file expired? If so we'll delete it.
            if (time() >= trim(str_replace('TS--->', '', $match['1'])))
            {
                if (is_really_writable($cache_path))
                {
                    @unlink($filepath);
                    log_message('debug', "Cache file has expired. File deleted");
                    return FALSE;
                }
            }
    
            // Display the cache
            $this->_display(str_replace($match['0'], '', $cache));
            log_message('debug', "Cache file is current. Sending it to browser.");
            return TRUE;
        }

    写缓存操作:(Output Class _write_cache方法里边)
    缓存文件名称: URI 的md5值;
    缓存内容:过期时间戳加特殊字符'TS--->' 再加变量解析后的模板内容
    缓存路径可自定义
    function _write_cache($output)
        {
            $CI =& get_instance();
            $path = $CI->config->item('cache_path');
    
            $cache_path = ($path == '') ? APPPATH.'cache/' : $path;
    
            if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))
            {
                log_message('error', "Unable to write cache file: ".$cache_path);
                return;
            }
    
            $uri =    $CI->config->item('base_url').
                    $CI->config->item('index_page').
                    $CI->uri->uri_string();
    
            $cache_path .= md5($uri);
    
            if ( ! $fp = @fopen($cache_path, FOPEN_WRITE_CREATE_DESTRUCTIVE))
            {
                log_message('error', "Unable to write cache file: ".$cache_path);
                return;
            }
    
            $expire = time() + ($this->cache_expiration * 60);
    
            if (flock($fp, LOCK_EX))
            {
                fwrite($fp, $expire.'TS--->'.$output);
                flock($fp, LOCK_UN);
            }
            else
            {
                log_message('error', "Unable to secure a file lock for file at: ".$cache_path);
                return;
            }
            fclose($fp);
            @chmod($cache_path, FILE_WRITE_MODE);
    
            log_message('debug', "Cache file written: ".$cache_path);
        }

       

  • 相关阅读:
    《程序员的数学课》模块二 代数与统计
    《程序员的数学课》模块一 无处不在的数学思维03
    Java 接口重试的几种实现
    用过stopwatch(秒表)观察代码运行的时长吗?
    sql 面试必刷系列-case-when
    缓存穿透、缓存击穿和缓存雪崩,了解一下?
    数据库批量插入100W 条数据,你学废了吗?
    缓冲输入流
    Linux系统中内存问题排查思路与解决方法
    Linux系统中负载较高问题排查思路与解决方法
  • 原文地址:https://www.cnblogs.com/jamesbd/p/3832747.html
Copyright © 2011-2022 走看看