Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Codeigniter caching issue when dealing with query string parameters

Greetings,

I'm writing a CI web application which implements the standard file caching functionality as such:

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

I'm using a combination of segments and query string parameters, and appear to be experiencing an issue as a result. What I'm seeing in my use cases and in the Output class code is that the caching is solely segment based. As such, http://www.example.com/segment/?q=foo and http://www.example.com/segment/?q=bar are treated as identical requests.

Does anyone have any insight or recommendations regarding how the url_helper, Output class, or CI base class can be edited such that the above example treats example.com/segment/?q=foo and example.com/segment/?q=bar as separate, unique requests and stores the responses in separate files individually?

like image 459
wannabenerd Avatar asked May 31 '11 23:05

wannabenerd


1 Answers

Due to this is very old answer and the website that was linked to does not exist anymore (new link). I'll copy the code to here for old version of Codeigniter.

This is an answer since Codeigniter 2.

Create MY_Output.php file in application/core and use the code below.

<?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


}

Clear all cache files and folders in application/cache.


Original answer (2011)

this can fix codeigniter cache with querystring codeigniter cache with querystring

it is thai language page but you can just copy that code and put it in application/core/MY_Output.php :)

like image 107
vee Avatar answered Sep 30 '22 09:09

vee