ปรับแต่ง codeigniter cache ให้รับ querystring

ปกติแล้วระบบ cache ของ codeigniter จะทำงานโดยเอา url มาทำการ hash เป็นชื่อไฟล์แล้วเก็บเป็น cache และมันไม่รองรับ querystring ใดๆเลย

วิธีนี้จะแก้ไขให้มันทำงานกับ url+querystring ได้ด้วย

สร้างไฟล์ MY_Output.php ขึ้นมาใน application/core/
copy โค้ดต่อไปนี้ใส่ในไฟล์ หรือถ้ามีไฟล์นี้อยู่ก่อนหน้าแล้วก็คัดลอกเฉพาะ method ต่อไปนี้ไปวางเสริมข้างใน


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

เสร็จสิ้นขั้นตอนการปรับแต่ง

การใช้งาน cache โดยก๊อปโค้ดต่อไปนี้ วางไว้ในส่วนใดก็ได้ภายในแต่ละ controller, controller/method ที่ต้องการให้ cache


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


โดยเลข 10 คือจำนวนนาที

ทดสอบ.
เข้าไปใน folder application/cache แล้วลบไฟล์ทั้งหมด ยกเว้น .htaccess, index.html
เรียกดูเว็บไซต์ที่ทำ ถ้าไม่พบ error ใดๆ ถือว่าใช้ได้แล้ว
ตรวจสอบ folder application/cache อีกครั้ง ควรจะพบไฟล์เพิ่มขึ้น เพราะมีการใช้งาน cache แล้ว
เสร็จสิ้นขั้นตอน

ใส่ความเห็น

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *

คุณอาจใช้แท็กHTMLและแอททริบิวต์เหล่านี้: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>