2010年8月28日 星期六

php純view樣版載入器

各位版友大家晚安。
小弟呢!長久以來一直接到很多學生的專題疑難。
他們常常都丟程式碼給我看。
但我每次看到都很吐血。
因為......html和php混在一起實在是太難分難解了。
在眾多的技術都討論了MVC的架構理論。
小弟現在也算是codeigniter的重度患者。
但問題在於,很多時候,又不能馬上叫那些學生立刻去學smarty樣版引擎。
或是立刻上手像是zend framework、cakephp、symfony、codeigniter這些東西。
然後大家就陷入了會寫物件的用framework很高興,不會寫的就純寫肉肉長的php
逐步的虐待自己又無法很順利的切割view和程式。
昨天又是一個專題發問過來,我看了一個不大的50行的程式。
其中echo就佔了快要一半。
然而半年以前,曾經寫過一個樣版載入架構,但是他有幾個大缺點。
載入變數定義方式不佳、採用變數置換內容、無法掛入php程式碼……這些問題。
自從用了ci之後,我就不斷的一直思考關於view的問題。
有沒有什麼是可以做純view載入樣板的方法?
ci的動作方式一直讓我擁入想法,卻一直沒有機會實現他。
但是今天卻讓我有機會去實現這麼一個東西。
當然可能有很多高手有寫出類似或根本就是的東西。
不管怎麼說,這樣一個樣板載入器總是能解決很多想把程式和view做最基礎切割的
設計人員,一個不錯的載入器程式。
底下將會公開這個程式的源碼,當然因為是第一版本的東西。
所以自然而然有我不知道可能的bug也不一定。
或者各位覺得這樣的東西應該要加上怎麼樣的功能或是怎麼樣的限制也可以提出討論。
能讓他的功能更加完整也是相當不錯的。
如果有人會覺得你這就是有參考ci的一些方法,這我不否認的確是有。
但無論如何,總是把他輕巧的參考出來並使用。
所以並非全然是超抄使用。各位如果有看過ci和我這隻程式就明白了。

檔名:template_engine.php
<?php
class template_engine{

    function view($source_page,$variable = '',$return = FALSE){
        $variable = $this->_check_array($variable);
        foreach($variable as $key => $value){
            $$key = $value;
        }
        ob_start();
            eval("?>".file_get_contents($source_page.".php")."<?");
            $buffer_tmp = ob_get_contents();
        ob_end_clean();
        if($return)
            return $buffer_tmp;
        echo $buffer_tmp;
    }

    function _check_array($variable){
        if($variable == null)
            return array();
        if(!is_array($variable)){
            echo 'This variable is not array';
            exit();
        }
        return $variable;
    }

}
?>
使用方法:(會用ci或是一般template engine的朋友就一定會用的啦。)
<?php
require('template_engine.php');
$load = new template_engine;
$frame['topbanner'] = $load->view('topbanner','',TRUE);
$frame['leftmenu'] = $load->view('leftmenu','',TRUE);
$frame['body'] = $load->view('body','',TRUE);
$load->view('mypages',$frame);
?>
有用過template engine應該覺得相當眼熟。是的,他該當就是如此的用法了。
$load->view()中有三個參數
第一個參數是載入的樣版檔名,副檔名強制為php,而這邊只需要輸入主檔名。
第二個參數是陣列,你傳入的陣列鍵名在樣版中會被解成變數。
舉例來說:
$data['name'] = 'sam';
$load->view('body',$data);
則在你的body.php中,你要使用$data['name'],他會變成$name。
所以你的body.php中就是直接寫
<?=$name?>
他就會顯示$data['name']的內容。
第三個參數是決定顯示還是傳回內容。
如果輸入TRUE的話是不顯示,將內容傳回至變數。
如果輸入FALSE或是不輸入的話,則會變成將內容顯示出來。
再來要說明的就是,在你載入的樣版中,所以PHP的程式碼都是可執行的。
但無論如何我們還是遵從template engine的一些不成文的規範如下:
1.使用<?=$name?>而不要使用<?php echo $name?>
2.條件式、迴圈、判斷式中的HTML輸出請讓他成為純HTML而不使用echo也不用大刮號
來列示範圍如下:

使用<?php if(條件):?>及<?php else:?>及<?php endif?>
而不使用<?php if(條件){.....}else{}?>

使用<?php while(條件):?>及<?php endwhile?>
而不使用<?php while(條件){.....}?>

使用<?php for(迴圈):?>及<?php endfor?>
而不使用<?php for(迴圈){.....}?>

使用<?php foreach(陣列方法):?>及<?php endforeach?>
而不使用<?php foreach(陣列方法){......}?>

其他一些遵從framework使用的架構規範都是比較好的做法。

目前這個載入器還沒有很深入的去寫比較多的php程式碼在內。
畢竟是純把他當樣版來使用(他也應當必須是當樣版載入來使用)。
若然有bug或是問題還煩請大家回報。
這樣我可以讓這個程式更加的完善。
有什麼需要追加的功能或不錯的意見也請大家能多多提供給我。

總之我是覺得這對很多初探php和html分開作頁的學習者。
這個程式提供了不錯而且有效的解決方案。

總之,我也是盡力在解決這樣的問題上。
幫助需要的人,也透過這樣的模式,讓大家能早一點上手真正的framework。

這是一個輕巧的程式,卻也是我花了很長的時間一直在思考view這件事之後。
所生產出的第一個我覺得真正有幫助到人的東西。

除了鼓勵為動力,也尚祈批評,以供改進。
如要整個程式含範例檔,請來信:
tkdmaf@gmail.com