【问题标题】:How do frameworks like codeigniter do their page caching?像 codeigniter 这样的框架是如何进行页面缓存的?
【发布时间】:2011-01-22 02:10:33
【问题描述】:

我知道 codeigniter 似乎将视图输出保存了指定的分钟数,如果 s 用户在这么多分钟内再次请求该页面,它将提供已保存的页面版本,而不是再次处理请求。它似乎将视图的所有输出保存在一个文件中,但它是如何做到的呢?那么,它怎么知道这些缓存文件的过期时间是多少呢?

最重要的是,如何为使用这种缓存模型的页面创建登录安全性?

任何见解将不胜感激。谢谢!

【问题讨论】:

  • 代替模板系统,它可能会使用ob_start 和朋友来捕获和保存输出。使缓存工作的首选方法是遵守条件 HTTP 标头 If:If-Modified-Since:。虽然我不知道 CodeIgniter 是真的这样做还是仅仅依赖于预配置的超时。

标签: php model-view-controller codeigniter outputcache


【解决方案1】:

在 core/ 中 CodeIgniter.php 的第 177 行:

if ($EXT->_call_hook('cache_override') === FALSE)
    {
        if ($OUT->_display_cache($CFG, $URI) == TRUE)
        {
            exit;
        }
    }

它检查缓存文件并显示它而不是处理控制器/操作代码。

您还可以阅读缓存文件在显示之前如何由 Output 类检查是否过期。

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;
}

【讨论】:

  • 很有趣,但是如果页面应该在登录后面怎么办。如果它没有进入控制器,开发人员如何添加会话权限检查?
  • 另外,每次都必须 preg_match 和 preg_replace 整个文件内容似乎太可惜了,必须有更好的方法来计算过期时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-08
  • 2011-06-03
  • 2015-12-23
  • 1970-01-01
  • 2010-11-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多