[PHP]简单易用的样板引擎

MVC是现在很流行的程式架构,因为按照功能分开后,更容易扩充和维护,其中的View会写成接收外来的变数来呈现资料,不处理资料取得和商业逻辑,因此便有了各种的样板引擎来让这件事情更容易达成

今天要介绍的是一款PHP的样板引擎,它没有名称,也不有名,来自这一篇文章Template Engine,简体翻译,但笔者却非常推崇,原因无他,就是非常的简单易用,通常样板引擎需要另外安装,有着专用的语法,用来呈现、过滤资料,并且可以用好几个小样板,组合出画面,每一个小样板都可以重複使用,避免重複开发

而这款却不需安装,仅用一个class便实现样板引擎的功能,甚至还有快取功能,不需要学新的语法,因为直接使用php语言,这有好有坏,设计师需要学习php语言,但虽然如此,用到的php其实不会太複杂,跟学习smarty相比,应该差不多难度,另外一个疑虑是,如果你的网站允许使用者上传样板修改版面,使用php语言变成自由度太大了,无法防止被上传包含恶意程式码的样板,不过这篇文章是在2003年写的,如今都是使用修改css的方式让使用者修改版面,所以这个疑虑也不存在了

事不宜迟,来看看这个class到底长的怎样

class Template {    var $vars; /// Holds all the template variables    /**     * Constructor     *     * @param $file string the file name you want to load     */    function Template($file = null) {        $this->file = $file;    }    /**     * Set a template variable.     */    function set($name, $value) {        $this->vars[$name] = is_object($value) ? $value->fetch() : $value;    }    /**     * Open, parse, and return the template file.     *     * @param $file string the template file name     */    function fetch($file = null) {        if(!$file) $file = $this->file;        extract($this->vars);          // Extract the vars to local namespace        ob_start();                    // Start output buffering        include($file);                // Include the file        $contents = ob_get_contents(); // Get the contents of the buffer        ob_end_clean();                // End buffering and discard        return $contents;              // Return the contents    }}/** * An extension to Template that provides automatic caching of * template contents. */class CachedTemplate extends Template {    var $cache_id;    var $expire;    var $cached;    /**     * Constructor.     *     * @param $cache_id string unique cache identifier     * @param $expire int number of seconds the cache will live     */    function CachedTemplate($cache_id = null, $expire = 900) {        $this->Template();        $this->cache_id = $cache_id ? 'cache/' . md5($cache_id) : $cache_id;        $this->expire   = $expire;    }    /**     * Test to see whether the currently loaded cache_id has a valid     * corrosponding cache file.     */    function is_cached() {        if($this->cached) return true;        // Passed a cache_id?        if(!$this->cache_id) return false;        // Cache file exists?        if(!file_exists($this->cache_id)) return false;        // Can get the time of the file?        if(!($mtime = filemtime($this->cache_id))) return false;        // Cache expired?        if(($mtime + $this->expire) < time()) {            @unlink($this->cache_id);            return false;        }        else {            /**             * Cache the results of this is_cached() call.  Why?  So             * we don't have to double the overhead for each template.             * If we didn't cache, it would be hitting the file system             * twice as much (file_exists() & filemtime() [twice each]).             */            $this->cached = true;            return true;        }    }    /**     * This function returns a cached copy of a template (if it exists),     * otherwise, it parses it as normal and caches the content.     *     * @param $file string the template file     */    function fetch_cache($file) {        if($this->is_cached()) {            $fp = @fopen($this->cache_id, 'r');            $contents = fread($fp, filesize($this->cache_id));            fclose($fp);            return $contents;        }        else {            $contents = $this->fetch($file);            // Write the cache            if($fp = @fopen($this->cache_id, 'w')) {                fwrite($fp, $contents);                fclose($fp);            }            else {                die('Unable to write cache.');            }            return $contents;        }    }}

可以看到有2个class,第1个实现样板功能,第2个继承第1个进一步实现快取功能,原理相当简单,看fetch方法便知道,利用extract传进来的阵列变成键值为名称的变数,然后使用缓冲区,将样板档引用执行,便会自动套用变数把html产生,将结果存在变数内,然后再输出缓冲并回传,就可以取得套好的html字串了,真的非常有巧思,样板档会长这样子

<html>    <head>        <title><?=$title;?></title>        <link href="style.css" rel="stylesheet" type="text/css" />    </head>    <body>        <h1><?=$title;?></h1>        <?=$content;?>    </body></html>
<table cellpadding="3" border="0" cellspacing="1" bgcolor="#CCCCCC">    <tr>        <td bgcolor="#F0F0F0">Id</td>        <td bgcolor="#F0F0F0">Name</td>        <td bgcolor="#F0F0F0">Email</td>        <td bgcolor="#F0F0F0">Banned</td>    </tr><?php foreach($users as $user): ?>    <tr>        <td bgcolor="#FFFFFF" align="center"><?=$user['id'];?></td>        <td bgcolor="#FFFFFF"><?=$user['name'];?></td>        <td bgcolor="#FFFFFF"><a href="mailto:<?=$user['email'];?>"><?=$user['email'];?></a></td>        <td bgcolor="#FFFFFF" align="center"><?=($user['banned'] ? 'X' : ' ');?></td>    </tr><?php endforeach; ?></table>

绝大部分是html,少部分是php输出,之后使用方法如下:

$tpl = new Template('index.tpl'); // this is the outer template$tpl->set('title', 'User List');$body = new Template('body.tpl'); // This is the inner template/* * The get_list() method of the User class simply runs a query on * a database - nothing fancy or complex going on here. */$body->set('user_list', $user->get_list());$tpl->set('content', $body);echo $tpl->fetch('index.tpl');

只需要读取样板档,然后填入样板档内定义的变数,甚至可以填入另一个样板档,达到重複使用的效果,是不是非常简单易用呢,最后说明一下快取的部分,每次存取的时候,判断是否有相同快取档存在,快取档档名会使用传入的字串编成md5,作者建议使用网址带get的参数,这样参数不同时,快取得档案也不同,然后可以设置快取过期时间,会自动检查快取档到当前时间是否已超过过期时间,若还没则直接读取快取档内容,超过则重新建立,算是方便易用的快取方式喔~


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章