(4)php框架開發---模板靜態化處理

   在這次的技術討論是,如何使用php原生來做模板語言,拋棄笨重的smarty等框架。因爲php本身就是很好的模板語言來的,所以基本上可以直接使用原生php代碼來做,這樣子可以省略了正則表達式置換的問題出現。

   在做php靜態化的時候,基本就是有兩種方法:

  1. file_get_contents(http://文件地址)
  2. ob函數
   在這裏我偏向於使用ob函數,ob函數常用方法如下:
ob_start();            //打開一個輸出緩衝區,所有的輸出信息不再直接發送到瀏覽器,而是保存在輸出緩衝區裏面。
ob_clean();            //刪除內部緩衝區的內容,不關閉緩衝區(不輸出)。
ob_end_clean();        //刪除內部緩衝區的內容,關閉緩衝區(不輸出)。
ob_get_clean();        //返回內部緩衝區的內容,關閉緩衝區。相當於執行 ob_get_contents() and ob_end_clean()
ob_flush();            //發送內部緩衝區的內容到瀏覽器,刪除緩衝區的內容,不關閉緩衝區。
ob_end_flush();        //發送內部緩衝區的內容到瀏覽器,刪除緩衝區的內容,關閉緩衝區。
ob_get_flush();        //返回內部緩衝區的內容,並關閉緩衝區,再釋放緩衝區的內容。相當於ob_end_flush()並返回緩衝區內容。
flush();               //將ob_flush釋放出來的內容,以及不在PHP緩衝區中的內容,全部輸出至瀏覽器;刷新內部緩衝區的內容,並輸出。
ob_get_contents();     //返回緩衝區的內容,不輸出。
ob_get_length();       //返回內部緩衝區的長度,如果緩衝區未被激活,該函數返回FALSE。
ob_get_level();        //Return the nesting level of the output buffering mechanism.
ob_get_status();       //Get status of output buffers.
ob_implicit_flush();   //打開或關閉絕對刷新,默認爲關閉,打開後ob_implicit_flush(true),所謂絕對刷新,即當有輸出語句(e.g: echo)被執行時,便把輸出直接發送到瀏覽器,而不再需要調用flush()或等到腳本結束時才輸出。
ob_gzhandler               //ob_start回調函數,用gzip壓縮緩衝區的內容。
ob_list_handlers           //List all output handlers in use
output_add_rewrite_var     //Add URL rewriter values
output_reset_rewrite_vars  //Reset URL rewriter values
這些函數的行爲受php_ini設置的影響:
output_buffering       //該值爲ON時,將在所有腳本中使用輸出控制;若該值爲一個數字,則代表緩衝區的最大字節限制,當緩存內容達到該上限時將會自動向瀏覽器輸出當前的緩衝區裏的內容。
output_handler         //該選項可將腳本所有的輸出,重定向到一個函數。例如,將 output_handler 設置爲 mb_output_handler() 時,字符的編碼將被修改爲指定的編碼。設置的任何處理函數,將自動的處理輸出緩衝。
implicit_flush         //作用同ob_implicit_flush,默認爲Off。

根據上面的ob函數,我們可以知道,使用ob_start,ob_get_contents,ob_clean這三個函數就可以實現基本的靜態化了。
具體的文件佈局如圖:

這裏面我首先定義一個cache類,這個類也在core文件目錄下,這個類是用來編譯cache文件,然後就是調用靜態模板。在調用模板的時候,這裏面會判斷cache文件是否修改過,如果修改過了,那麼我就重新編譯cache文件,否則直接調用靜態模板。
namespace core;


class cache
{
    /*
     * 顯示模板
     */
    public function display($filename,$page=null){

        $tpl_file = ROOT_PATH.'/'.MODULE_NAME.'/tpl/'.$filename.'.php';
        $cache_file = ROOT_PATH.'/caches/'.MODULE_NAME.'/'.$filename.'.htm';

//        判斷文件是否被修改,未修改不用重新編譯
        if(!$this->cache($tpl_file,$cache_file)){
            $this->compile($filename,$tpl_file,$cache_file,$page=null);
        }
        require_once($cache_file);
    }

    //判斷模板是否緩存,如模板文件有更改則重新編譯
    function cache($tpl_file,$cache_file) {
        if(!file_exists($cache_file) || filemtime($tpl_file)>filemtime($cache_file)){
            return false;
        }

        return true;
    }
    /*
     * 編譯靜態文件
     */
    public function compile($name,$tpl_file,$cache_file,$page=null){

        ob_start(); //開啓緩存區
        require_once($tpl_file);
        file_put_contents($cache_file,ob_get_contents());
        if(!$page){

            file_put_contents(ROOT_PATH.'/caches/'.MODULE_NAME.'/'.$name.'.htm',ob_get_contents());
        }else{

            file_put_contents(ROOT_PATH.'/caches/'.MODULE_NAME.'/'.$name.'_'.$page.'.htm',ob_get_contents());
        }
        ob_clean();//清空緩衝區


    }

}

基本的模板類做好後,就是整合到整個框架裏面去了。這裏,我會將cache類放到dphp.php這個文件裏面。做成一個接口的形式來獲取每個對象。直接根據(命名空間\類名)的形式傳參進去就能獲取到當前的類對象了。


然後就是在控制器類裏面封裝一個cache類來使用,在控制類裏面我們可以將display這些函數封裝起來,這樣子的話就可以讓我們和cache對象隔離了。


然後再模塊控制器裏面就可以直接使用display函數了,並且不用知道他是如何實現的。這裏面要在display函數傳一個cache文件名,在上面的項目圖裏面我們可以看到tpl/admin.php,所以這個參數就是這個文件的名字。


   然後你會發現,這樣的做法明顯無法顯示數據變化的情況重新編譯文件。所以爲了讓其實現這個效果,我們必須要藉助ajax來實現。這裏面我們將數據以接口的形式來表示,然後使用ajax獲取到數據後,在客戶端是用js或jq動態添加html代碼,這樣就實現了數據的動態變化了。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章