แนะนำ CI

เป็นบทความเบื้องต้น ที่แนะนำว่า CodeIgniter มีข้อดีอย่างไรทำงานเช่นไร

Sub-Domain or Many File in Page Caching with CodeIgniter

คราวก่อนเขียนเรื่อง Page Caching with CodeIgniter and Cache Clearing code เป็นการเกริ่นถึงวิธีใช้งาน Page Caching ของ Codeigniter รวมไปถึงผมได้แนบคลาสสำหรับการ ลบแคช (Cache Clearing) เข้าไปด้วย เพื่อความสะดวกในการใช้งาน

บทความนี้เลยคล้ายๆ กับบทต่อจากเรื่องข้างต้นนะครับ เป็นกรณีศึกษาที่ผมเจอและจำเป็นต้องใช้ เลยมาขอแชร์ความรู้นิดหนึ่ง เผื่อมีใครมีแนวทางที่ดีกว่าของผมนะครับ

Mini Introduction Page Caching with CodeIgniter

เกริ่นพื้นฐานเล็กน้อยครับ ปกติการทำ Page Caching ใน Codeigniter เราจะเก็บลงโฟลเดอร์หนึ่ง สมมุติว่าชื่อ "system/cache/" นะครับ ส่วนชื่อไฟล์ที่ทำการ Cache ก็จะนำเอา URI(หรือ URL) มาเข้ารหัสด้วย md5 เช่น "http://lab.tosdn.com" จะถูกเข้ารหัสและนำไปตั้งชื่อไฟล์ คือ "53db6ab6193a34a4ebac45ebd7592da6"

ถ้าไม่เข้าใจ ไปอ่านเต็มๆ ที่บทความเก่าครับ - Page Caching with CodeIgniter and Cache Clearing code

Problem of Page Caching with CodeIgniter

คราวนี้ ปัญหาที่ผมเจอมี 2 ข้อครับ

1. หากการทำ Caching มีไฟล์มากมายมหาศาลจะทำอย่างไร? ซึ่งปํญหานี้อาจจะไม่ค่อยสำคัญ หากเว็บเราไม่ได้คิดการใหญ่ และหน้าเพจไม่มากนัก

2. ถ้าเราเปิดให้สมาชิกมี Sub-Domain ได้เอง แปลว่า ในเว็บเราจะเสมือนมีเว็บสมาชิกย่อยลงไปอีก คราวนี้ ปัญหาที่หนีไม่พ้นก็คือ ปัญหาในข้อ 1 และ ปัญหาที่สำคัญตามมาคือ การบริหารจัดการไฟล์ Caching ที่ยากขึ้น เช่น สมาชิกคนนี้เปลี่ยนแปลงชื่อใน profile ตัวเอง ดังนั้น หน้าใน Sub-Domin ต้องมีการเปลี่ยนแปลงด้วย เช่นนั้นแล้วเราต้องมาทำการค้นหาว่า Cacgin Page ของสมาชิกคนนี้ มีไฟล์ไหนบ้าง แค่คิดก็สนุกแล้วครับ T-T

หรือบางคนไม่ได้ใช้เป็น Sub-Domain แต่ใช้เก็บค่าสมาชิกใน Session หรือ Cookie หรือ อื่นๆ แต่ URI ยังใช้คงเดิม เช่น สมาชิก A,B,C ก็เข้าแก้ไขชื่อตนเองใน http://www.web.com/profile เหมือนกัน ดังนั้น Caching ที่เก็บ มันก็จะมีชื่อเหมือนกัน อยู่ที่ว่า Codeigniter ทำการ Generate Page Caching ให้คนไหนก่อน พอคนต่อมาเข้ามาใช้ มันก็จะเจอข้อมูลของคนแรกที่ถู Generate ไว้ มันช่างวุ่นวายได้อีก T-T

Solution of Page Caching with CodeIgniter

เมื่อเจอปัญหาแบบนั้น ผมเลยลองแก้ไขด้วยการจัดระเบียบโฟลเดอร์ของ Page Caching ให้ลึกลงไปอีก 2 ชั้นโดยชั้นแรกเก็บเป็นอักษรหน้า 3 ตัว และชั้นสองเก็บ อักษรเต็มของชื่อ Domain หรือ Sub-Domain ไว้ และไฟล์ข้างในโฟลเดอร์นี้ ก็จะเก็บเฉพาะ หน้านั้นๆของ Domain หรือ Sub-Domain ที่ระบุไว้เท่านั้น

เอาหละครับ เมื่อทราบที่มา ปัญหา และวิธีแก้ไข ก็ลงมือกันเลย :D

How to use Sub-Domain or Many File in Page Caching with CodeIgniter

1. สร้างไฟล์ Library ใน Application มาหนึ่งตัวครับ เช่น ปล. หากในบทความก่อน ใครสร้างไว้แล้วก็ข้ามไปครับ

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

2. ทำการ Extend Output ของ CodeIgniter และใส่โค้ด ดังนี้ครับ ปล. หากในบทความก่อน ใครสร้างไว้แล้วก็ทับได้เลยครับ เพราะผมพ่วง clear_cache() มาในโค้ดนี้แล้ว

 if ( ! defined('BASEPATH')) exit('No direct script access allowed');
<br> /********<br> / TOSDN - URI from CI URI Library<br> / Update 12/12/2551 2:26<br> ********/</p> <p>/**<br> * Page Caching management class (extends from CI_Output)<br> *<br> *<br> * @package        CodeIgniter<br> * @subpackage    Libraries<br> * @hacked-by    Chitpong Wuttanan<br> */<br> class My_Output extends CI_Output {
    var $cache_name;
    <br> var $cache_expiration;
    /**<br> * Set Cache<br> *<br> * @access    public<br> * @param    integer<br> * @return    void<br> *//**<br> * Update/serve a cached file<br> *<br> * @access    public<br> * @return    void<br> */<br> function _display_cache(&$CFG, &$URI)<br> {
        <br> $cache_path = ($CFG->
        item('cache_path') == '') ? BASEPATH.'cache/' : $CFG->
        item('cache_path');
        if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))<br> {
            <br> return FALSE;
            <br>
        }
        $cache_topdomain_uri = md5($CFG->
        item('base_url'));
        <br> $cache_path_folder_uri = $cache_path."/".substr($cache_topdomain_uri, 0, 3)."/".$cache_topdomain_uri."/";
        // Build the file path.  The file name is an MD5 hash of the full URI<br> $uri =    $CFG->
        item('base_url').<br> $CFG->
        item('index_page').<br> $URI->
        uri_string;
        $filepath = $cache_path_folder_uri.md5($uri);
        if ( ! @file_exists($filepath))<br> {
            <br> return FALSE;
            <br>
        }
        if ( ! $fp = @fopen($filepath, FOPEN_READ))<br> {
            <br> return FALSE;
            <br>
        }
        flock($fp, LOCK_SH);
        $cache = '';
        <br> if (filesize($filepath) >
        0)<br> {
            <br> $cache = fread($fp, filesize($filepath));
            <br>
        }
        flock($fp, LOCK_UN);
        <br> fclose($fp);
        // Strip out the embedded timestamp<br> if ( ! preg_match("/(\d+TS--->
        )/", $cache, $match))<br> {
            <br> return FALSE;
            <br>
        }
        // Has the file expired? If so we'll delete it.<br> if (time() >
        = trim(str_replace('TS--->
        ', '', $match['1'])))<br> {
            <br> @unlink($filepath);
            <br> log_message('debug', "Cache file has expired. File deleted");
            <br> return FALSE;
            <br>
        }
        // Display the cache<br> $this->
        _display(str_replace($match['0'], '', $cache));
        <br> log_message('debug', "Cache file is current. Sending it to browser.");
        <br> return TRUE;
        <br>
    }
    /**<br> * Write a Cache File<br> *<br> * @access    public<br> * @return    void<br> */<br> function _write_cache($output)<br> {
        <br> $CI =& get_instance();
        <br> $path = $CI->
        config->
        item('cache_path');
        $cache_path = ($path == '') ? BASEPATH.'cache/' : $path;
        if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))<br> {
            <br> return;
            <br>
        }
        $cache_topdomain_uri = md5($CI->
        config->
        item('base_url'));
        <br> $cache_path_folder = $cache_path."/".substr($cache_topdomain_uri, 0, 3);
        <br> $cache_path_folder_uri = $cache_path_folder."/".$cache_topdomain_uri."/";
        if ( ! is_dir($cache_path_folder) OR ! is_really_writable($cache_path_folder))<br> {
            <br> @mkdir($cache_path_folder, 0755);
            <br> @mkdir($cache_path_folder_uri, 0755);
            <br>
        }
        if(empty($this->
        cache_name)) {
            <br> $uri = $CI->
            config->
            item('base_url').<br> $CI->
            config->
            item('index_page').<br> $CI->
            uri->
            uri_string();
            <br> $cache_path_folder_uri .= md5($uri);
            <br>
        }
        else {
            <br> $cache_path_folder_uri .= md5($this->
            cache_name);
            <br>
        }
        if ( ! $fp = @fopen($cache_path_folder_uri, FOPEN_WRITE_CREATE_DESTRUCTIVE))<br> {
            <br> log_message('error', "Unable to write cache file: ".$cache_path_folder_uri);
            <br> return;
            <br>
        }
        $expire = time() + ($this->
        cache_expiration * 60);
        if (flock($fp, LOCK_EX))<br> {
            <br> fwrite($fp, $expire.'TS--->
            '.$output);
            <br> flock($fp, LOCK_UN);
            <br>
        }
        <br> else<br> {
            <br> log_message('error', "Unable to secure a file lock for file at: ".$cache_path_folder_uri);
            <br> return;
            <br>
        }
        <br> fclose($fp);
        <br> @chmod($cache_path_folder_uri, DIR_WRITE_MODE);
        log_message('debug', "Cache file written: ".$cache_path_folder_uri);
        <br>
    }
    function clear_cache($set_uri = NULL, $all=FALSE){
        <br> $CFG =& load_class('Config');
        <br> $cache_topdomain_uri = md5($CFG->
        item('base_url'));
        <br> $cache_path_folder_uri = $CFG->
        item('cache_path')."/".substr($cache_topdomain_uri, 0, 3)."/".$cache_topdomain_uri;
        if($all == FALSE) {
            <br> $filepath = ($CFG->
            item('cache_path') == '') ? BASEPATH.'cache/' : $cache_path_folder_uri."/".md5($set_uri);
            <br> if(file_exists($filepath))<br> {
                <br> @unlink($filepath);
                <br> log_message('debug', "Cache deleted for: ".md5($set_uri)." (".$set_uri.")");
                <br>
            }
            else {
                <br> return FALSE;
                <br>
            }
            <br>
        }
        else {
            <br> $filepath = ($CFG->
            item('cache_path') == '') ? BASEPATH.'cache/' : $cache_path_folder_uri;
            <br> if ($handle = opendir($filepath)) {
                <br> while (($file = readdir($handle))  !== false) {
                    <br> if ($file != "." && $file != "..") {
                        <br> @unlink($filepath."/".$file);
                        <br>
                    }
                    <br>
                }
                <br> closedir($handle);
                <br> log_message('debug', "Cache deleted for: ".md5($set_uri)." (".$set_uri.")");
                <br>
            }
            else {
                <br> return FALSE;
                <br>
            }
            <br>
        }
        <br>
    }
    <br>
}

3. วิธีการนำไปใช้ (Usage) ใช้เหมือนเดิมทุกประการครับ :D

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

ปิดท้ายด้วยการอธิบายโค้ดนิดหนึ่งนะครับ

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

_display_cache() - จะทำหน้าที่เรียกการแสดงผล โดยตรวจสอบว่ามีการทำ Caching ไว้ไหม ถ้ามี และยังไม่หมดอายุ ตามเวลาที่กำหนด ก็จะเรียก Cache โดยตรวจสอบก่อนว่ามาจาก URI ไหน ให้เข้ารหัสด้วย md5และตัด 3 ตัวแรกออกมา เพื่อเข้าโฟลเดอร์ชั้นแรก จากนั้นเข้าโฟลเดอร์ชั้นสอง ด้วยรหัส md5 ตัวเต็ม จากนั้นจึงจะเจอไฟล์ที่มันจะตรวจสอบ แต่ถ้าไม่เจอ มันจะไปเรียก _write_cache() เพื่อสร้างไฟล์ใหม่ทันที รวมไปถึงสร้างโฟลเดอร์ให้อัตโนมัติด้วยนะครับ

_write_cache() - อันนี้ทำหน้าที่สร้างไฟล์ครับ โดยมีขั้นตอนเหมือน _display_cache() ครับ แต่ทำหน้าที่สร้างไฟล์ในโฟลเดอร์ที่เรากำหนดไว้

clear_cache() - เอาไว้ Clear Cache ครับ ตามที่เคยเขียนไว้ใน Page Caching with CodeIgniter and Cache Clearing code

ยังไงก็ลองเล่นดูนะครับ หากมีวิธีที่ดีกว่านี้ ก็เสนอได้ครับ :D

 

อ้างอิง : Sub-Domain or Many File in Page Caching with CodeIgniter

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

อธิบายนิยามโฟลเดอร์ต่างๆของ CodeIgniter

คนส่วนใหญ่เวลาเริ่มต้นทำ CodeIgniter สิ่งหนึ่งที่ภายใน "คู่มือการใช้งาน" ได้บอกไว้อาจจะยาวและต้องใช้ประสบการณ์ในการทำความเข้าใจซักเล็กน้อยซึ่งผมจะอธิบายเป็นอันๆไปเลยนะครับ โดยปกติแล้ว CI จะมี

โดย CodeIgniter นั้นสามารถใช้ได้หลาย Application ในอันเดียว (ซึ่งผมไม่ค่อยนิยมทำแบบนั้น) ดังนั้นภายในโฟลเดอร์ system ซึ่งสามารถเปลี่ยนชื่อได้ นั้นจะประกอบด้วยพวก libraries , helpers , language , plugins ซึ่งเหมือนกับตัวที่อยู่ในโฟลเดอร์ application มีความแตกต่างเพียงเรื่องเดียวก็คือ ถ้าอยู่ในโฟลเดอร์ system จะสามารถใช้ได้มากกว่า 1 applications แต่ถ้าอยู่ใน application นั้นๆก็จะใช้ได้เฉพาะ application แล้วความหมายของแต่ละอันละคืออะไร

  • libraries ถ้าพูดง่ายๆคือแหล่งรวมคลาส (Class) ต่างๆที่จะนำมาใช้ซึ่งมักจะใช้ใน Controller และ Model เป็นส่วนใหญ่
  • helpers มีลักษณะเหมือน libraries แต่จะเจาะจงไปยังเรื่องที่เกี่ยวข้องกับด้าน View เป็นหลักแต่ไม่ได้ถูกจำกัด ดังนั้นเราก็ยังใช้มันได้ใน Controller และ Model อยู่ดี
  • plugins คือฟังก์ชัน (functions) โดยไม่จำเป็นต้องเป็นคลาสซึ่งเมื่อโหลดขึ้นมาแล้วก็สามารถใช้งานได้ทันที
  • language คือภาษาซึ่งเราสามารถทำให้ app เราเป็น i18n ซึ่งรองรับหลายภาษาได้ด้วยเจ้าตัวนี้และ Language Helper

โฟลเดอร์ถัดมาที่ผมจะอธิบายก็คือ cache , fonts , logs ซึ่งรายละเอียดคือ

  • cache เป็นที่เก็บไฟล์ cache เมื่อเราใช้ cache ในส่วนต่างๆของ CodeIgniter
  • fonts เป็นที่เก็บ font ซึ่งเราอาจจะนำไปใช้กับ Image Class หรือคลาสอื่นๆถ้าคุณะจใช้
  • logs เป็นที่เก็บ logs เมื่อเกิด error ซึ่งคุณสามารถอ่านเพิ่มเติมได้ที่ บทความนี้

ส่วน codeigniter เป็นโฟลเดอร์ในส่วนของ core ของ codeigniter ซึ่งไม่ควรไปแตะ ถ้าไม่ได้อยากรู้วิธีเขียนกลไก แล้วต่อมาคือ scaffolding ซึ่งในส่วนนี้เป็น theme และสิ่งที่เกี่ยวข้องกับ function scaffold ซึ่งใน CodeIgniter ตรงส่วนนี้ ไม่ดีพอที่จะใช้ หมดแล้วในส่วนของ system คราวนี้เหลือในส่วน application ซึ่งผมจะเริ่มจากพื้นฐานก่อนเลยคือ

  • models เป็นโฟลเดอร์เก็บ model ซึ่งจะใช้กับ controller
  • views เป็นโฟลเดอร์เก็บ view ซึ่งแสดงส่วนของ user interface ซึ่งจะต่อกับ controller
  • controllers เป็นที่เก็บ controller ซึ่งผสานระหว่าง view และ model แต่ CI ไม่จำเป็นต้องมี model ดังนั้นเราสามารถทำ view กับ controller เฉยๆเลยก็ได้

ซึ่งหลักการ Model-View-Controller (MVC) นั้นมีคำอธิบายอยู่ลองศึกษาเพิ่มเติมจาก บทความนี้ครับ เสร็จแล้วเราจะยังเหลือโฟลเดอร์เหลือดังนี้ errors , configs , hooks ซึ่งผมจะอธิบายทีละอันดังนี้ครับ

  • errors นั้นเป็นโฟลเดอร์ที่จัดการกับ error ที่เกิดขึ้น ซึ่งเราสามารถดัดแปลงหน้า error ได้จากที่นี้ เช่น จะดัดแปลงเวลาไม่เจอหน้า page ที่ต้องการเราก็ไปแก้ได้ที่ error_404.php
  • configs ที่แห่งนี้เป็นแหล่งเก็บ config ต่างๆเกี่ยวกับ CodeIgniter ซึ่งสามารถศึกษาได้จาก คู่มือการใช้งาน CodeIgniter
  • hooks เอาไว้เก็บไฟล์ที่เรา hook จาก CodeIgniter ซึ่ง hook คือสิ่งที่ CodeIgniter เปิดให้เราสามารถแก้ไข Core ของ CodeIgniter ได้โดยไม่ต้องไปดัดแปลงตรงๆ ข้อดีก็คือเราจะสามารถเสริม CodeIgniter ให้เจ๋งขึ้นได้ โดยอนาคตเมื่อ CodeIgniter มีเวอร์ชั่นใหม่ก็จะสามารถลงได้เลยทันที ไม่ต้องมานั่งเขียนโค้ดใหม่ซึ่งได้ทั้งความสามารถของ CodeIgniter แล้วสิ่งที่ทำเรายังอยู่ ศึกษา hook เพิ่มเติมได้ที่นี้ครับ

หมดแล้วครับทุกโฟลเดอร์ วันหลังจะมาเขียนเรื่อง CodeIgniter เพิ่มขึ้นเรื่อยๆนะครับ

Why use CodeIgniter - ทำไมผมจึงใช้ Codeigniter

ส่วนตัวผมเพิ่งใช้งาน Framework เป็นครั้งแรก ที่ผ่านมาก็จะทำการเขียนโค้ดแบบเพียวๆ หรือที่เรียกกันว่า Hard Code นั่นเอง
ดังนั้นเมื่อผมเริ่มรู้จัก PHP Framework ทำให้ผมเลือกที่จะเล่น CI ด้วยเหตุผล

  • เร็วมากกกกกก!
  • เล็กมากกกกก!
  • แรงมากกกกก!
  • สามารถแก้ไขปรับปรุง Framework ตามที่เราต้องการได้ง่าย เพราะโค้ดเขียนมาแบบง่ายๆ
  • รู้ PHP + OOP อีกเล็กน้อย ก็ใช้ CI ได้สบายๆ
  • ถ้าไม่รู้โครงสร้างการเขียนแบบ MVC ก็สามารถเขียนถึกๆ แค่ C กับ V ก็ได้ ไม่ fix
  • ถ้าขี้เกียจอ่าน Manual มันว่ามี Library ให้ใช้บ้าง ก็ยัดโค้ด PHP + Function ปกติไปได้เลย
  • มันมี Active Record ให้ใช้ ทำให้การทำงานกับฐานข้อมูลเป็นเรื่องสะดวก, เร็ว, ปลอดภัยขึ้นอีก (จริงๆ เรื่องของ ORM มันมีหลายยี่ห้อที่ทำมา Support แต่ผมยังไม่ได้ลอง แต่เจ้า Active Record มีติดมาให้ในตัวต้นฉบับเลยครับ)
  • มี Library พื้นฐานครบตามต้องการ จะมีนอกเหนือจากนั้น ก็สามารถไปหา Library Third Party มาผสมได้ไม่ยาก ถ้าหาไม่ได้ก็ไปโหลด Class มา include แบบถึกๆ ก็สามารถใช้ได้
  • ทำ URL Friendly ได้ง่ายดี
  • ทำ Caching Page แบบง่ายๆ ได้ (ถ้าจะให้ดีคงต้องไปผสมกับ Smarty ซึ่งมี Library รองรับอยู่เช่นกัน)
  • ทำ Caching Database แบบง่ายๆ ได้ด้วย
  • ถึงแม้จะไม่มี AJAX ผสมมาด้วย แต่เราก็สามารถนำมาผสมใช้ที่หลังได้ เช่น jQuery, XAJAX
จะว่าไปแล้ว ถ้าใครไม่ต้องการความเลิศหรูอลังการ และต้องการ PHP Framework แบบพอเพียง ผมว่า CI เป็นตัวเลือกที่ดีมาก
แต่ตรงจุดนี้เอง ผมไม่สามารถฟันธงได้ว่า สามารถรองรับเว็บไซต์ขนาดใหญ่ได้แค่ไหน แต่เท่าที่ตามอ่านข้อมูลในเว็บไซต์ พบว่ามันรองรับการทำงานระบบใหญ่ๆ ได้
แต่ในความส่วนตัวผมมองว่า ด้วยความที่ตัวมันเล็ก จึงทำงานได้เร็ว บางทีผมก็คิดไม่ออกว่าจะต้อง Optimize ที่ไหน เพราะมันเขียนมาง่ายมากๆ ไม่ซับซ้อน ดังนั้น ด้วยความที่เป็นอย่างที่ผมกล่าว การจะเขียนให้รองรับเว็บไซต์ขนาดใหญ่ ตัว Framework เองจึงไม่น่ามีปัญหาใดๆ แต่จะขึ้นอยู่กับผู้เขียนมากกว่าว่าจะเขียนให้มันทำงานได้ดีได้เร็วแค่ไหน
สรุปแล้ว ถ้าใครจะใช้ Codeigniter ไว้เพื่อจัดระเบียบโค้ดให้มันแยกเป็นส่วนๆ ของการทำงานตามแบบ MVC ไว้ช่วยเหลือเรื่อง URL Friendly และช่วยเหลือเรื่องการ Optimize Code ในภายหลัง (เข้าไปเปลี่ยนโค้ดใน CORE ตามแบบฉบับของเรา) ผมว่า มันเหมาะมากเลยหละครับ
Syndicate content