在這次的技術討論是,如何使用php原生來做模板語言,拋棄笨重的smarty等框架。因爲php本身就是很好的模板語言來的,所以基本上可以直接使用原生php代碼來做,這樣子可以省略了正則表達式置換的問題出現。
在做php靜態化的時候,基本就是有兩種方法:
- file_get_contents(http://文件地址)
- 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這三個函數就可以實現基本的靜態化了。
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這個文件裏面。做成一個接口的形式來獲取每個對象。直接根據(命名空間\類名)的形式傳參進去就能獲取到當前的類對象了。