Page Caching with CodeIgniter and Cache Clearing code

Introduction Page Caching with CodeIgniter

ใน CodeIgniter จะมีคำสั่งทำ Page Caching ไว้ให้อยู่แล้ว ซึ่งมันเอาไว้ทำการ Caching หน้าเว็บไซต์ที่ได้รับการประมวลผลแล้ว มห้กลายเป็น หน้า Statics ตามระยะเวลาที่เรากำหนดไว้ ดังนั้น เมื่อโหลดหน้านั้นขึ้นมาใหม่ภายในระยะเวลานั้น จะไม่ทำการประมวลผลอีก ซึ่งจะส่งผลให้เว็บโหลดเร็วขึ้นมากๆ (เช่น โหลดจาก 0.2 วินาที เหลือเพียง 0.0020 วินาที) รวมไปถึงประหยัดทรัพยากรณ์เซอเวอร์ได้อีกมากโข

ซึ่งวิธีการใช้ ก็ง่ายมากครับ แค่ใส่คำสั่ง $this->output->cache(5); ไว้ก่อนคำสั่งเรียก View จะหมายถึงการทำ Caching สำหรับหน้า (View) นั้นๆ เป็นเวลา 5 นาที เช่น

$this->output->cache(60); //1 Hour $this->load->view('profile.php');

ดังนั้น คำสั่งทั้งหมดในหน้า profile.php จะไม่ถูก ประมวลผลซ้ำภายใน 5 นาที หลังจากมีคนเข้าครั้งแรก เพราะระบบจะไปเรียกหน้า Cache มาแสดงแทน ซึ่ง เป็นหน้านิ่งๆ (Static page) เหมือน html ธรรมดาๆ

พอเข้าใจหลักการ Page Caching ของ CodeIgniter แล้วนะครับ คราวนี้ มาพูดถึงข้อจำกัดของมันบ้าง

Restriction of Page Caching with CodeIgniter

ข้อจำกัดของ Page Caching ด้วย CodeIgniter เท่าที่คนส่วนใหญ่ รวมถึงผมพบก็คือ มันง่ายเกินไป! เพราะมันทำงานอัตโนมัตินั่นเอง :D

เพราะ วิธีการทำงานของ Page Caching ใน CodeIgniter มันจะทำการ เก็บ output ของคำสั่งประมวลผลทั้งหมด ไปเก็บไว้ในชื่อไฟล์ ที่เข้ารหัสด้วย MD5 และชื่อไฟล์นั้น มันเอามาจาก URL หรือ URI ที่เรียกมันครับ เช่น

http://lab.tosdn.com

จะถูกเข้ารหัสและนำไปตั้งชื่อไฟล์ คือ

53db6ab6193a34a4ebac45ebd7592da6

ดังนั้น เมื่อมีการเข้าหน้านี้ซ้ำอีกครั้ง มันจะดึงค่า URL หรือ URI ที่ได้ มาเข้ารหัส MD5 และตรวจสอบว่า Cache หมดอายุ (Cache Expire) หรือยัง ถ้าหมดแล้ว จะทำการลบไฟล์เดิม > ประมวลผลข้อมูลใหม่ > แล้วก็เก็บค่าข้อมูลใหม่ ในชื่อไฟล์เดิม อีกครั้ง วนอย่างนี้ไปเรื่อยๆ

Problem of Page Caching with CodeIgniter

อันนี้เป็นปัญหาที่ผมเจอ รวมถึงใครหลายๆ คนที่ใช้ CodeIgniter นั่นก็คือ ต้องการลบหน้าที่ Cache ออก โดยไม่ต้องรอให้หมดเวลา แต่เราสามารถสั่งการได้เอง

การทำ Page Caching หรือ Database Caching ของผม ปกติจะทำการเก็บใหม่ ทุกครั้งที่มีการเปลี่ยนแปลงข้อมูล แต่ถ้าไม่มีการเปลี่ยนแปลงข้อมูล ก็ให้อยู่นิ่งๆ แบบนั้นไปเรื่อยๆ หรือจนกว่าจะหมดเวลาของมันไปเอง

ดังนั้น ในระบบจัดการข้อมูลของผม จำต้องมีการลบ Cache (Clear Cache) ทุกครั้งที่มีการแก้ไข

แต่ CodeIgniter ทำไม่ได้ครับ :D

Solution of Page Caching with CodeIgniter

วิธีแก้ไขปัญหาข้างต้น หลายคนไปใช้ Smarty ซึ่งเป็นระบบการจัดการ Template (Template Engine) ที่ดีมากตัวหนึ่ง หรือไปใช้ตัวอื่นๆ นำมา Integrate รวมกับ Codeigniter แทนการใช้งานระบบ Template เดิมของมัน (ที่ผมเขียนมาทั้งหมดคือระบบ Template เดิมที่มันมีมาให้อยู่แล้วนะครับ อย่าเพิ่งสับสนๆ)

แต่ที่ผมลองใช้งาน มันจัดการ Template ได้ดีสมน้ำสมเนื้อมันเอง แต่ผมรู้สึกว่ามันใหญ่เทอะทะ เพราะระบบมันฉลาดเกินไป! กล่าวคือ ผมต้องการ Page Caching ทั้งหน้าแค่นั้น ไม่ได้ต้องการแบ่งส่วนการ Caching เช่น ส่วน Header ของเว็บทำการ Cache ไว้ แต่ Body ไม่ต้องทำ อะไรทำนองนั้น

เขียนมาถึงตรงนี้ ใครเคลิ้มตาม เจอปัญหาแบบผม และต้องการใช้งานแบบผม มาลุยแก้ปัญหากันดีกว่าครับ :D

How to Cache Clearing with CodeIgniter?

1. สร้างไฟล์ Library ใน Application มาหนึ่งตัวครับ เช่น

/system/application/libraries/My_Output.php (ใครตั้ง Suffix ว่าอะไรก็ใส่แทน My ไปเลยครับ)

2. ทำการ Extend Output ของ CodeIgniter และใส่โค้ด ดังนี้ครับ

<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

/** * Clear Cache * * Responsible for sending final output to browser * * @package        CodeIgniter * @subpackage    Libraries * @added-by    Chitpong Wuttanan */ class My_Output extends CI_Output {

function clear_cache($set_uri = NULL){ $CFG =& load_class('Config'); $filepath = ($CFG->item('cache_path') == '') ? BASEPATH.'cache/' :       $CFG->item('cache_path').md5($set_uri);

if(file_exists($filepath)) { @unlink($filepath); log_message('debug', "Cache deleted for: ".$set_uri); } else { return FALSE; } } }

?>

3. วิธีการนำไปใช้ (Usage)

3.1 ใช้แบบเดิม โดยไม่ระบุ URI ซึ่งการทำงานจะเหมือนเดิมทุกอย่าง

$this->output->cache(60); //1 Hour $this->load->view('profile.php');

4. วิธีการลบ Cache (Clear Cache)

$this->output->clear_cache('http://www.web.com/profile');

มา อธิบายโค้ดกันนิดหนึ่งครับ

โค้ดตัวนี้ผมได้ทำการ extend ไว้กับคลาส Output เดิม เพื่อสะดวกต้อการเรียกใช้ครับ โดยทำการสร้าง Function ชื่อ  clear_cache() เข้าไป

ในฟังก์ชั่นนี้ จะ เรียก URI ที่เราระบุ ทำการเข้ารหัสด้วย md5 และ ลบออก ง่ายไหมครับ ไม่ต้องไป Integrate ระบบ Template Engine ให้ยุ่งยากเลย

Reference Page Caching with CodeIgniter and Cache Clearing code

Comments

ผมเข้าใจแล้วทำไมต้องมีการลบ

ผมเข้าใจแล้วทำไมต้องมีการลบ Cache แบบนี้ แง่ๆทำ Twistori เวลา edit คำต้องการให้มัน clear cache นี้เองหือๆ T_T