PhpView:一个以PHP语言为模板语言的模板类

  1. PhpView:一个以PHP语言为模板语言的模板类  
  2.   
  3.   
  4.   
  5. 作者:谢声涛 shishengsoft@gmail.com  
  6.   
  7.   
  8.   
  9. Smarty用来实现代码与界面的分离,确实是一种不错的选择。但是Smarty有自创的一套语法,  
  10.   
  11. 使用起来感觉很麻烦,于是想到用PHP语言实现一个精简的模板类,名字就叫PhpView。  
  12.   
  13. 其实,最简单的模板机制就是在PHP脚本文件中include一个模板文件。但是这样缺点比较多。  
  14.   
  15.   
  16.   
  17. 一、使用示例  
  18.   
  19.   
  20.   
  21. <?php  
  22.   
  23.   
  24.   
  25. $t = new PhpView();  
  26.   
  27.   
  28.   
  29. $t->templateDir  = './template';  
  30.   
  31. $t->cacheDir     = './cache';  
  32.   
  33. $t->serializeDir = './serialize';  
  34.   
  35.   
  36.   
  37. $t->assign('title'$title);  
  38.   
  39. $t->assign('hello'$hello);  
  40.   
  41.   
  42.   
  43. $t->display("example.html");  
  44.   
  45.   
  46.   
  47. ?>  
  48.   
  49.   
  50.   
  51. 如上所示,和Smarty的接口很相似,好像现在一些PHP模板类都是大同小异的。  
  52.   
  53.   
  54.   
  55.   
  56.   
  57. 二、实现代码  
  58.   
  59.   
  60.   
  61. 文件名:PhpView.class.php  
  62.   
  63.   
  64.   
  65. <?php  
  66.   
  67. /******************************************************************************* 
  68.  
  69.  * 简介: 
  70.  
  71.  * 1、模板语言使用PHP语言,而其它模板类使用自定义的专用语言,需要进行正则替换。 
  72.  
  73.  * 2、支持缓存机制,模板数据变化,就刷新缓存文件。 
  74.  
  75.  * 3、可以设定缓存时间,缓存过期,就刷新缓存文件。 
  76.  
  77.  * 4、支持配置文件方式初始化设定目录,也可以后期更改目录,更加灵活(也许是多余)。 
  78.  
  79. ********************************************************************************/  
  80.   
  81. /** 
  82.  
  83.  * PHP视图模板类 
  84.  
  85.  * @class    PhpView 
  86.  
  87.  * @author   xie sheng tao <xie.s.t@163.com> 
  88.  
  89.  */  
  90.   
  91. class PhpView  
  92.   
  93. {  
  94.   
  95.     /** 
  96.  
  97.      * 是否使用缓存机制进行工作 
  98.  
  99.      * @var  boolean  $cacheEnable   true-启用缓存机制;false-关闭缓存机制 
  100.  
  101.      */  
  102.   
  103.     public $cacheEnable = true;  
  104.   
  105.   
  106.   
  107.     /** 
  108.  
  109.      * 缓存时间 
  110.  
  111.      * 超过缓存时间则自动更新缓存。 
  112.  
  113.      * @var  integer     $cacheExpire  0-永远不过期;> 0 判断。< 0 ?? 或者 = 0 始终过期;> 0 判断;< 0 永远不过期 
  114.  
  115.      */  
  116.   
  117.     public $cacheExpire = 0;  
  118.   
  119.       
  120.   
  121.     /** 
  122.  
  123.      * 模板文件的存贮目录 
  124.  
  125.      * @var  string  $templateDir 
  126.  
  127.      */  
  128.   
  129.     public $templateDir = '';  
  130.   
  131.   
  132.   
  133.     /** 
  134.  
  135.      * 缓存文件的存贮目录 
  136.  
  137.      * @var string   $cacheDir 
  138.  
  139.      */  
  140.   
  141.     public $cacheDir = '';  
  142.   
  143.   
  144.   
  145.     /** 
  146.  
  147.      * 序列化文件的存贮目录 
  148.  
  149.      * @var  string  $serializeDir 
  150.  
  151.      */  
  152.   
  153.     public $serializeDir = '';  
  154.   
  155.   
  156.   
  157.     /** 
  158.  
  159.      * 保存模板文件中使用的变量的名、值列表 
  160.  
  161.      * @var  array   $m_templateVarList 
  162.  
  163.      */  
  164.   
  165.     private $m_templateVarList = array();  
  166.   
  167.   
  168.   
  169.     /** 
  170.  
  171.      * 记住系统目录是否已经检查过并且符合要求。避免以全局方式使用时重复检查。 
  172.  
  173.      * @var  boolean     $m_sysDirReady   
  174.  
  175.      */  
  176.   
  177.     private $m_sysDirReady = false;  
  178.   
  179.   
  180.   
  181.     /** 
  182.  
  183.      * 当前操作使用的模板文件 
  184.  
  185.      * @var  string  $m_templateFile 
  186.  
  187.      */  
  188.   
  189.     private $m_templateFile = '';  
  190.   
  191.   
  192.   
  193.     /** 
  194.  
  195.      * 类的构造函数 
  196.  
  197.      */  
  198.   
  199.     public function __construct()  
  200.   
  201.     {  
  202.   
  203.         $this->readConfig();  
  204.   
  205.     }  
  206.   
  207.       
  208.   
  209.     /** 
  210.  
  211.      * 读取PhpView类的配置信息 
  212.  
  213.      */  
  214.   
  215.     public function readConfig()  
  216.   
  217.     {  
  218.   
  219.         if(file_exists("config.php"))  
  220.   
  221.         {  
  222.   
  223.             include_once("config.php");  
  224.   
  225.         }  
  226.   
  227.         if(isset($g_cacheEnable))  
  228.   
  229.         {  
  230.   
  231.             $this->cacheEnable = $g_cacheEnable;  
  232.   
  233.         }  
  234.   
  235.         if(isset($g_templateDir))  
  236.   
  237.         {  
  238.   
  239.             $this->templateDir =$g_templateDir;  
  240.   
  241.         }  
  242.   
  243.         if(isset($g_cacheDir))  
  244.   
  245.         {  
  246.   
  247.             $this->cacheDir = $g_cacheDir;  
  248.   
  249.         }  
  250.   
  251.         if(isset($g_serializeDir))  
  252.   
  253.         {  
  254.   
  255.             $this->serializeDir = $g_serializeDir;  
  256.   
  257.         }  
  258.   
  259.         if(isset($g_sysDirReady))  
  260.   
  261.         {  
  262.   
  263.             $this->m_sysDirReady = $g_sysDirReady;  
  264.   
  265.         }  
  266.   
  267.     }  
  268.   
  269.   
  270.   
  271.     /** 
  272.  
  273.      * 检测所需目录是否存在。如果不存在,则报错并退出。 
  274.  
  275.      * 所需目录为:模板文件目录、缓存文件目录、序列化文件目录 
  276.  
  277.      */  
  278.   
  279.     public function checkSysDir()  
  280.   
  281.     {  
  282.   
  283.         if($this->templateDir == '')  
  284.   
  285.         {  
  286.   
  287.             die("模板文件目录未设置。");  
  288.   
  289.         }  
  290.   
  291.           
  292.   
  293.         if(!is_readable($this->templateDir))  
  294.   
  295.         {  
  296.   
  297.             die("模板文件目录不可读。");  
  298.   
  299.         }  
  300.   
  301.   
  302.   
  303.         if($this->cacheDir == '')  
  304.   
  305.         {  
  306.   
  307.             die("缓存文件目录未设置。");  
  308.   
  309.         }  
  310.   
  311.           
  312.   
  313.         if(!(is_readable($this->cacheDir) && is_writable($this->cacheDir)))  
  314.   
  315.         {  
  316.   
  317.             die("缓存文件目录不可读写。");  
  318.   
  319.         }  
  320.   
  321.           
  322.   
  323.         if($this->serializeDir == '')  
  324.   
  325.         {  
  326.   
  327.             die("序列化文件目录未设置。");  
  328.   
  329.         }  
  330.   
  331.           
  332.   
  333.         if(!(is_readable($this->serializeDir) && is_writable($this->serializeDir)))  
  334.   
  335.         {  
  336.   
  337.             die("序列化文件目录不可读写。");  
  338.   
  339.         }  
  340.   
  341.           
  342.   
  343.         $this->m_sysDirReady = true;  
  344.   
  345.         return;  
  346.   
  347.     }  
  348.   
  349.   
  350.   
  351.     /** 
  352.  
  353.      * 指派模板文件中使用的变量 
  354.  
  355.      * @param   string  $varName   在模板中使用的变量名 
  356.  
  357.      * @param   any     &$varValue  PHP中支持的数据类型 
  358.  
  359.      * or 
  360.  
  361.      * @param   array   $varName    使用数组来传递名值列表,即变量名作为关联索引,变量值为元素值。 
  362.  
  363.      */  
  364.   
  365.     public function assign($varName$varValue = null)  
  366.   
  367.     {  
  368.   
  369.         if(func_num_args() == 1)  
  370.   
  371.         {  
  372.   
  373.             $varList = func_get_arg(0);  
  374.   
  375.             if(gettype($varList) == 'array')  
  376.   
  377.             {  
  378.   
  379.                 foreach($varList as $name=>$value)  
  380.   
  381.                 {  
  382.   
  383.                     $this->m_templateVarList[$name] = $value;  
  384.   
  385.                 }  
  386.   
  387.             }  
  388.   
  389.         }  
  390.   
  391.         else if(gettype($varName) == 'string')  
  392.   
  393.         {  
  394.   
  395.             $this->m_templateVarList[$varName] = $varValue;  
  396.   
  397.         }  
  398.   
  399.         return;  
  400.   
  401.     }  
  402.   
  403.   
  404.   
  405.     /** 
  406.  
  407.      * 调用模板文件,生成模板中的变量,输出到浏览器 
  408.  
  409.      * @param   string  $file  模板文件名 
  410.  
  411.      */  
  412.   
  413.     public function display($file)  
  414.   
  415.     {  
  416.   
  417.         if(!$this->m_sysDirReady)  
  418.   
  419.         {  
  420.   
  421.             $this->checkSysDir();   
  422.   
  423.         }  
  424.   
  425.           
  426.   
  427.         $this->m_templateFile = $file;  
  428.   
  429.           
  430.   
  431.         if($this->cacheEnable)  
  432.   
  433.         {  
  434.   
  435.             $this->cacheOutput();  
  436.   
  437.         }  
  438.   
  439.         else  
  440.   
  441.         {  
  442.   
  443.             $this->directOutput();  
  444.   
  445.         }  
  446.   
  447.         return;  
  448.   
  449.     }  
  450.   
  451.   
  452.   
  453.     /** 
  454.  
  455.      * 使用缓存机制处理模板 
  456.  
  457.      * 实现原理: 
  458.  
  459.      * 1、取得客户端请求的链接url。缓存文件和序列化文件的文件名使用此url命名。 
  460.  
  461.      * 2、将存贮当前模板变量的数组序列化为一个字符串。 
  462.  
  463.      * 3、读取模板文件对应的序列化文件,得到前一个模板变量数组的序列化字符串。 
  464.  
  465.      * 4、判断前后两次序列化字符串是否相等。如果相等,则直接把缓存文件的内容输出到浏览器。 
  466.  
  467.      *    否则,重新生成序列化文件和缓存文件,然后把模板处理结果输出到浏览器。 
  468.  
  469.      */  
  470.   
  471.     private function cacheOutput()  
  472.   
  473.     {  
  474.   
  475.         $html = '';  
  476.   
  477.         $cache_filename = @urlencode(basename(SERVER['REQUEST_URI']));  
  478.   
  479.         $cur_serialize = @serialize($this->m_templateVarList);  
  480.   
  481.         $pre_serialize = $this->readSerialize($cache_filename);  
  482.   
  483.   
  484.   
  485.         if($cur_serialize === $pre_serialize)  
  486.   
  487.         {  
  488.   
  489.             if(!$this->isCacheFileTimeout($cache_filename)){  
  490.   
  491.                 if($html = $this->readCacheFile($cache_filename))  
  492.   
  493.                 {  
  494.   
  495.                     echo '使用缓存文件.';  
  496.   
  497.                     echo $html;  
  498.   
  499.                     return;  
  500.   
  501.                 }  
  502.   
  503.             }  
  504.   
  505.             echo '缓存文件过期.';  
  506.   
  507.         }  
  508.   
  509.           
  510.   
  511.         echo '刷新缓存文件.';  
  512.   
  513.         $this->saveSerialize($cache_filename$cur_serialize);  
  514.   
  515.         /*foreach($this->m_templateVarList as $name => $value) 
  516.  
  517.         { 
  518.  
  519.             eval("/$name = /$value;"); // 通过 eval 函数生成模板文件中使用的变量 
  520.  
  521.         }*/  
  522.   
  523.         extract($this->m_templateVarList);  
  524.   
  525.   
  526.   
  527.         ob_start();  
  528.   
  529.         @include($this->templateDir . '/' . $this->m_templateFile);  
  530.   
  531.         //sleep(5);  
  532.   
  533.         $html = ob_get_contents();  
  534.   
  535.         ob_clean();  
  536.   
  537.         $this->writeCacheFile($cache_filename$html);  
  538.   
  539.         echo $html;  
  540.   
  541.         return;  
  542.   
  543.     }  
  544.   
  545.   
  546.   
  547.     /** 
  548.  
  549.      * 直接将模板处理结果输出到浏览器,不使用缓存机制 
  550.  
  551.      */  
  552.   
  553.     private function directOutput()  
  554.   
  555.     {  
  556.   
  557.         foreach($this->m_templateVarList as $name => $value)  
  558.   
  559.         {  
  560.   
  561.             eval("/$name = /$value;"); // 通过 eval 函数生成模板文件中使用的变量  
  562.   
  563.         }  
  564.   
  565.         ob_start();  
  566.   
  567.         @include($this->templateDir . '/' . $this->m_templateFile);  
  568.   
  569.         ob_flush();  
  570.   
  571.         return;  
  572.   
  573.     }  
  574.   
  575.   
  576.   
  577.     /** 
  578.  
  579.      * 将模板处理结果写入缓存文件 
  580.  
  581.      * @param    string  $file       缓存文件路径 
  582.  
  583.      * @param    string  $content    缓存内容 
  584.  
  585.      * @return   null 
  586.  
  587.      */  
  588.   
  589.     private function writeCacheFile($file$content)  
  590.   
  591.     {  
  592.   
  593.         $filename = $this->cacheDir . '/' . $file;  
  594.   
  595.         @file_put_contents($filename$content);  
  596.   
  597.         return;  
  598.   
  599.     }  
  600.   
  601.   
  602.   
  603.     /** 
  604.  
  605.      * 读取缓存文件 
  606.  
  607.      * @param    string  $file   缓存文件路径 
  608.  
  609.      * @return   string          缓存文件的内容 
  610.  
  611.      */  
  612.   
  613.     private function readCacheFile($file)  
  614.   
  615.     {  
  616.   
  617.         $filename = $this->cacheDir . '/' . $file;  
  618.   
  619.         $html = @file_get_contents($filename);  
  620.   
  621.         return $html;  
  622.   
  623.     }  
  624.   
  625.           
  626.   
  627.     /**  
  628.  
  629.      * 保存序列化字符串到文本文件中 
  630.  
  631.      * @param    string  $file       序列化文件路径 
  632.  
  633.      * @param    string  $content    序列化数据的字符串 
  634.  
  635.      * @return   null 
  636.  
  637.      */  
  638.   
  639.     private function saveSerialize($file$content)  
  640.   
  641.     {  
  642.   
  643.         $filename = $this->serializeDir . '/' . $file;  
  644.   
  645.         @file_put_contents($filename$content);  
  646.   
  647.         return;  
  648.   
  649.     }  
  650.   
  651.   
  652.   
  653.     /** 
  654.  
  655.      * 读取文本文件中存贮的序列化字符串 
  656.  
  657.      * @param    string  $file       序列化文件路径 
  658.  
  659.      * @return   string              序列化数据的字符串 
  660.  
  661.      */  
  662.   
  663.     private function readSerialize($file)  
  664.   
  665.     {  
  666.   
  667.         $filename = $this->serializeDir . '/' . $file;  
  668.   
  669.         $content = @file_get_contents($filename);  
  670.   
  671.         return $content;  
  672.   
  673.     }  
  674.   
  675.   
  676.   
  677.     /** 
  678.  
  679.      * 判断缓存文件是否过期 
  680.  
  681.      * @param    string      $file   缓存文件 
  682.  
  683.      * @return   boolean 
  684.  
  685.      */  
  686.   
  687.     private function isCacheFileTimeout($file)  
  688.   
  689.     {  
  690.   
  691.         if($this->cacheExpire == 0)//缓存时间为0,表示永远不过期  
  692.   
  693.         {  
  694.   
  695.             return false;  
  696.   
  697.         }  
  698.   
  699.   
  700.   
  701.         $cacheFile = $this->cacheDir . '/' . $file;  
  702.   
  703.         if(file_exists($cacheFile))  
  704.   
  705.         {  
  706.   
  707.             $modifyTime = filemtime($cacheFile);  
  708.   
  709.             $currentTime = time();  
  710.   
  711.             if(($currentTime - $modifyTime) > $this->cacheExpire){  
  712.   
  713.                 return true;  
  714.   
  715.             }  
  716.   
  717.             return false;  
  718.   
  719.         }  
  720.   
  721.         return true;  
  722.   
  723.     }  
  724.   
  725.   
  726.   
  727. // end class  
  728.   
  729.   
  730.   
  731. ?> 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值