处理查询字符串参数时出现Codeigner缓存问题


Codeigniter caching issue when dealing with query string parameters

问候语,

我正在编写一个实现标准文件缓存功能的CI web应用程序,例如:

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

我使用的是段和查询字符串参数的组合,结果似乎遇到了问题。我在用例和Output类代码中看到的是,缓存完全是基于段的。像这样的http://www.example.com/segment/?q=foo和http://www.example.com/segment/?q=bar被视为相同的请求。

是否有人对如何编辑url_helper、Output类或CI基类有任何见解或建议,以便上面的示例处理example.com/segment/?q=fooexample.com/segment/?q=bar作为单独的、唯一的请求,并将响应单独存储在单独的文件中?

由于这是一个非常古老的答案,链接到的网站已经不存在了(新链接)。我将把旧版本的Codeigniter的代码复制到这里。

这是一个答案,因为代码点火器2。

application/core中创建MY_Output.php文件,并使用下面的代码。

<?php
/**
 * @author vee
 */
class MY_Output extends CI_Output
{

    public function __construct()
    {
        parent::__construct();
    }// __construct

    /**
     * Update/serve a cached file
     *
     * @access    public
     * @return    void
     */
    public 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;
        // buld query strings
        $querystrings = $_SERVER['QUERY_STRING'];
        if ( $querystrings != null ) {$querystrings = "?".$querystrings;}
        $uri = $uri.$querystrings;
        $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;
    }// _display_cache

    /**
     * Write a Cache File
     *
     * @access    public
     * @return    void
     */
    public 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();
        // buld query strings
        $querystrings = $_SERVER['QUERY_STRING'];
        if ( $querystrings != null ) {$querystrings = "?".$querystrings;}
        $uri = $uri.$querystrings;
        $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);
    }// _write_cache

}

清除应用程序/缓存中的所有缓存文件和文件夹。


原始答案(2011)

这可以使用querystring修复代码点火器缓存带查询字符串的代码点火器缓存

这是一个泰语页面,但您可以复制该代码并将其放入application/core/MY_Output.php:)

进入config/config.php

您应该像这个一样启用cache_query_string

$config['cache_query_string'] = TRUE;

将所有查询参数都考虑在内。请注意,这可能会导致为同一页面反复生成大量缓存文件。

这里有一些代码可以覆盖Codeigniter的Output类,这似乎对我有效

创建文件application/core/MY_Output.php,从Output.php复制_write_cache()和_display_cache

class MY_Output extends CI_Output {
    function __construct() {
        parent::__construct();
    }
    function _write_cache($output) {
        ....
        $uri = $CI->config->item('base_url').
               $CI->config->item('index_page').
               $CI->uri->uri_string();
        // append querystring
        $qs = (empty($_SERVER['QUERY_STRING'])) ? '' : '?'.$_SERVER['QUERY_STRING'];
        $uri .= $qs;
        // append querystring  
        ....
    }
    function _display_cache(&$CFG, &$URI)
        ....
        $uri = $CI->config->item('base_url').
               $CI->config->item('index_page').
               $URI->uri_string;
        // append querystring
        $qs = (empty($_SERVER['QUERY_STRING'])) ? '' : '?'.$_SERVER['QUERY_STRING'];
        $uri .= $qs;
        // append querystring
        ....
    }

如果_GET的值为空,则应该缓存

if(!$_GET)
    $this->output->cache(0);