DIY – Basic Cache System

Dynamic Page
Dynamic Page

หลักการทำงานทั่วๆไปของ website ปัจจุบัน จะมีลำดับการทำงานแบบนี้ครับ
1. user เข้าหน้า website (user ส่ง request ไปที่ web server)
2. server ประมวลผล
3. server ดึงข้อมูลมาจาก database
4. server ได้รับข้อมูลจาก database แล้วนำมาประมวลผลอีกรอบ
5. server ประมวลผลเสร็จส่งไฟล์กลับไปให้

ซึ่งขั้นตอนทั้ง ก็จะให้ memory ในการทำงาน

Cached File example
Cached File example

แต่เมื่อเราทำระบบ cache file, server ก็จะใช้ memory ในการทำงานน้อยลงมาก
เช่น การ cache HTML ไฟล์จะช่วยลดได้ดังนี้
ข้อ “2” ก็ไม่ต้องแล้ว หา cache file ก็พอ
ข้อ “3” ไม่ต้องไปดึงข้อมูลมาจาก database แล้ว อยู่ใน cache file แล้ว
ข้อ “4” ไม่ต้องแล้ว
ที่เหลือก็ไปดึง cache file ที่ต้องการมาแล้วก็ส่งให้ user

สรุปการทำงานก็จะเป็น
1. user เข้าหน้า website (user ส่ง request ไปที่ web server)
2. server ประมวลผลไปเรียก cache file ที่ต้องการมา
3. server ประมวลผลเสร็จส่งไฟล์กลับไปให้

Cache file ก็คือ ไฟล์ชั่วคราวซึ่งอาจจะอยู่ในรูปแบบใดก็ได้ เช่น html, css, js, etc.

PHP – Basic Cache System

PHP basic cache system
PHP basic cache system

หลักการทำงานของระบบ cache ในบทความนี้จะเป็นแบบนี้
1. user ส่ง request มา
2. server ตรวจสอบดูว่ามี cache file หรือเปล่า
ถ้ามี cache file ก็จะส่ง cache file นั้นให้เลย ถ้าไม่มีก็
– ดึงข้อมูลที่ต้องการ
– ประมวลผล
– ทำเป็น HTML file
– สร้าง cache file
– เก็บไว้ใน cache folder
– ส่งข้อมูลจาก Output buffer นั้นออกไปให้ user

ตัวอย่าง PHP Code

ตัวอย่างนี้จะเป็น PHP Code – basic cache system โดยวิธีใช้ Output buffer และ filesystem

// Example code
$cache_ext  = '.html'; //file extension
$cache_time  = 3600;  //Cache file expires afere these seconds (1 hour = 3600 sec)
$cache_folder = 'cache/'; //folder to store Cache files
$ignore_pages = array('', '');

$dynamic_url = 'http://'.$_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . $_SERVER['QUERY_STRING']; // requested dynamic page (full url)
$cache_file = $cache_folder.md5($dynamic_url).$cache_ext; // construct a cache file
$ignore = (in_array($dynamic_url,$ignore_pages))?true:false; //check if url is in ignore list

if (!$ignore && file_exists($cache_file) && time() - $cache_time < filemtime($cache_file)) { //check Cache exist and it's not expired.
  ob_start('ob_gzhandler'); //Turn on output buffering, "ob_gzhandler" for the compressed page with gzip.
  readfile($cache_file); //read Cache file
  echo '<!-- cached page - '.date('l jS \of F Y h:i:s A', filemtime($cache_file)).', Page : '.$dynamic_url.' -->';
  ob_end_flush(); //Flush and turn off output buffering
  exit(); //no need to proceed further, exit the flow.
}
//Turn on output buffering with gzip compression.
ob_start('ob_gzhandler'); 

######## Your Website Content Starts Below #########

// your content file

######## Your Website Content Ends here #########

if (!is_dir($cache_folder)) { //create a new folder if we need to
  mkdir($cache_folder);
}
if(!$ignore){
  $fp = fopen($cache_file, 'w');  //open file for writing
  fwrite($fp, ob_get_contents()); //write contents of the output buffer in Cache file
  fclose($fp); //Close file pointer
}
ob_end_flush(); //Flush and turn off output buffering

นอกจากตัวอย่าง code นี้, ผู้เขียนแนะนำ cache ไฟล์แยกเป็นส่วนๆเช่น header, content, footer แทนที่จะเป็นการ cache ทั้งหมดเลยดังตัวอย่างด้านบน