+ -
当前位置:首页 → 问答吧 → 一个小型Php模板引擎

一个小型Php模板引擎

时间:2009-10-10

来源:互联网

一个小型的php模板引擎,结合dz模板封装的。
复制代码
  1. <?php
  2. /**
  3. * 文件名: template.class.php
  4. * 功能: 模板引擎
  5. * 使用方法:inlucde此文件,输出模板的时候:include Template::showTemplate($tpl);
  6. * $tpl 为字符串是模板的副目录名/文件名
  7. * 示例代码如下:
  8. ***********************************php程序********************************************************
  9. *            inlucde('template.class.php');
  10. *            $sHello = 'hello world';
  11. *            $aUsers = array(
  12. *                 'one' =>array(
  13. *                            'user'=>'user1',
  14. *                            'sex' =>'f',
  15. *                            'age' =>21
  16. *                        ),
  17. *                'two' =>array(
  18. *                            'user'=>'user2',
  19. *                            'sex' =>'f',
  20. *                            'age' =>22
  21. *                        ),
  22. *                'three' =>array(
  23. *                            'user'=>'user3',
  24. *                            'sex' =>'f',
  25. *                            'age' =>23
  26. *                        ),
  27. *                'four' =>array(
  28. *                            'user'=>'user4',
  29. *                            'sex' =>'f',
  30. *                            'age' =>24
  31. *                        ),
  32. *                'five' =>array(
  33. *                            'user'=>'user5',
  34. *                            'sex' =>'f',
  35. *                            'age' =>25
  36. *                        ),
  37. *                'sex' =>array(
  38. *                            'user'=>'user6',
  39. *                            'sex' =>'f',
  40. *                            'age' =>26
  41. *                        ),
  42. *                'seven' =>array(
  43. *                            'user'=>'user7',
  44. *                            'sex' =>'f',
  45. *                            'age' =>27
  46. *                        )
  47. *                    );
  48. *            include Template::showTemplate('test');
  49. **************************************xhtml页面********************************************************
  50. * 模板文件写法:
  51. * 直接输出变量:<!--{$sHello}-->或者<!--{eval print $test;}-->
  52. * 逻辑输出写法(if...else):<!--{if $sHello == ''}-->变量为空<!--{else}--><!--{$sHello}--><!--{/if}-->
  53. * 数组输出写法:
  54. *                <!--{loop $aUsers $value}-->
  55.                     <!--{if $value[user] == 'user2'}-->two<!--{else}-->one<!--{/if}--><br />
  56.                     $value[sex]<br />
  57.                     $value[age]<br />
  58.                 <!--{/loop}-->
  59. *
  60. * 调用模板写法:<!--{template templateName}-->或者<!--{template dir/name}-->
  61. * templateName为 模板文件名,注:不带扩展名|| dir为副目录名,name为模板文件名
  62. * 测试环境目录结构为:
  63. *                        template
  64. *                            |________cache
  65. *                            |
  66. *                            |________default
  67. *                            |                |
  68. *                            |                |______admin
  69. *                            |             |     |
  70. *                            |             |         |____index.htm
  71. *                            |             | |
  72. *                            |             |         |____admin.htm
  73. *                            |             |
  74. *                            |             |______article
  75. *                            |                         |
  76. *                            |                         |_______cateList.htm
  77. *                            |                         |
  78. *                            |                         |_______index.htm
  79. * |
  80. *                            |
  81. * |_______template.class.php
  82. *                            |
  83. *                            |_______test.php
  84. *
  85. * 版权: 七夜
  86. * 作者: 七夜, qq:64438136, email : [email protected], msn : [email protected]
  87. * 创建日期: 2008-2-25
  88. * 修改日期
  89. */
  90. class Template
  91. {
  92.     /**
  93.      *全局成员数组
  94.      */
  95.     static private $sGlobal = array(
  96.                 'i' => 0,    
  97.                 'block_search' =>array(),
  98.                 'block_replace' => array()
  99.             );
  100.     /**
  101.      *选择模板目录
  102.      */
  103.     static private $sSelectTemplatePath = 'default';
  104.     /**
  105.      *模板目录
  106.      */
  107.     static private $sTemplateDir = 'template';
  108.     /**
  109.      *检测模板更新:设置0为永远不检测,设置1总是检测
  110.      */
  111.     static private $nTemplateRefresh = 1;
  112.     
  113.     /**
  114.      *模板缓存时间,必须开启模板更新检测也有效
  115.      */
  116.     static private $nTemplateCacheTime = 3600;
  117.     
  118.     /**
  119.      * 构造方法
  120.      */
  121.     function __construct()
  122.     {
  123.         //......
  124.     }
  125.     
  126.     /**
  127.      * 输出模板
  128.      * @param string $name
  129.      * @return string
  130.      */
  131.     static public function showTemplate($name)
  132.     {
  133.         $tpl = Template::$sTemplateDir.'/'.Template::$sSelectTemplatePath.'/'.$name;
  134.         $objfile = Template::$sTemplateDir.'/cache/'.str_replace('/','_',$tpl).'.php';
  135.         if(!file_exists($objfile))
  136.         {
  137.             include_once('./template.class.php');
  138.             Template::parse_template($tpl);
  139.         }
  140.             return $objfile;
  141.     }
  142.     /**
  143.      * 子模板更新检查
  144.      * @function checkCacheTemplate
  145.      * @param string $subfiles,$mktime,$tpl
  146.      * @return void
  147.      */
  148.     static public function checkCacheTemplate($subfiles, $mktime, $tpl)
  149.     {
  150.         if(Template::$nTemplateRefresh && (Template::$nTemplateRefresh == 1 || mt_rand(1, Template::$nTemplateRefresh) == 1))
  151.         {
  152.             $subfiles = explode('|', $subfiles);
  153.             foreach ($subfiles as $subfile)
  154.             {
  155.                 @$submktime = filemtime($subfile.'.htm');
  156.                 $endTime = time() - $submktime;
  157.                 if($submktime > Template::$nTemplateCacheTime)
  158.                 {
  159.                     include_once('./template.class.php');
  160.                     Template::parse_template($tpl);
  161.                     break;
  162.                 }
  163.             }
  164.         }
  165.     }
  166.     
  167.     /**
  168.      * 模板解析
  169.      * @function parse_template
  170.      * @param string $tpl
  171.      * @return void
  172.      */
  173.     static private function parse_template($tpl)
  174.     {    
  175.         //包含模板
  176.         Template::$sGlobal['sub_tpls'] = array($tpl);
  177.         $tplfile = $tpl.'.htm';
  178.         $objfile = Template::$sTemplateDir.'/cache/'.str_replace('/','_',$tpl).'.php';
  179.         //read Template
  180.         $template = Template::readContents($tplfile);
  181.         if(empty($template)) {
  182.             exit(Template::showError("Template file : $tplfile Not found or have no access!"));
  183.         }
  184.         //模板
  185.         $template = preg_replace("/\<\!\-\-\{template\s+([a-z0-9_\/]+)\}\-\-\>/ie", "Template::readTemplateContents('\\1')", $template);
  186.     //    print $template;
  187.         //处理子页面中的代码
  188.         $template = preg_replace("/\<\!\-\-\{template\s+([a-z0-9_\/]+)\}\-\-\>/ie", "Template::readTemplateContents('\\1')", $template);
  189.         //PHP代码
  190.         $template = preg_replace("/\<\!\-\-\{eval\s+(.+?)\s*\}\-\-\>/ies", "Template::evaltags('\\1')", $template);
  191.         //start
  192.         //变量
  193.         $var_regexp = "((\\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)(\[[a-zA-Z0-9_\-\.\"\'\[\]\$\x7f-\xff]+\])*)";
  194.         $template = preg_replace("/\<\!\-\-\{(.+?)\}\-\-\>/s", "{\\1}", $template);
  195.         $template = preg_replace("/([\n\r]+)\t+/s", "\\1", $template);
  196.         $template = preg_replace("/(\\\$[a-zA-Z0-9_\[\]\'\"\$\x7f-\xff]+)\.([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)/s", "\\1['\\2']", $template);
  197.         $template = preg_replace("/\{(\\\$[a-zA-Z0-9_\[\]\'\"\$\.\x7f-\xff]+)\}/s", "<?=\\1?>", $template);
  198.         $template = preg_replace("/$var_regexp/es", "Template::addquote('<?=\\1?>')", $template);
  199.         $template = preg_replace("/\<\?\=\<\?\=$var_regexp\?\>\?\>/es", "Template::addquote('<?=\\1?>')", $template);
  200.         //逻辑
  201.         $template = preg_replace("/\{elseif\s+(.+?)\}/ies", "Template::stripvtags('<?php } elseif(\\1) { ?>','')", $template);
  202.         $template = preg_replace("/\{else\}/is", "<?php } else { ?>", $template);
  203.         //循环
  204.         for($i = 0; $i < 5; $i++)
  205.         {
  206.             $template = preg_replace("/\{loop\s+(\S+)\s+(\S+)\}(.+?)\{\/loop\}/ies", "Template::stripvtags('<?php if(is_array(\\1)) { foreach(\\1 as \\2) { ?>','\\3<?php } } ?>')", $template);
  207.             $template = preg_replace("/\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}(.+?)\{\/loop\}/ies", "Template::stripvtags('<?php if(is_array(\\1)) { foreach(\\1 as \\2 => \\3) { ?>','\\4<?php } } ?>')", $template);
  208.             $template = preg_replace("/\{if\s+(.+?)\}(.+?)\{\/if\}/ies", "Template::stripvtags('<?php if(\\1) { ?>','\\2<?php } ?>')", $template);
  209.         }
  210.         //常量
  211.         $template = preg_replace("/\{([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/s", "<?=\\1?>", $template);
  212.         
  213.         //替换
  214.         if(!empty(Template::$sGlobal['block_search']))
  215.         {
  216.             $template = str_replace(Template::$sGlobal['block_search'], Template::$sGlobal['block_replace'], $template);
  217.         }
  218.         
  219.         //换行
  220.         $template = preg_replace("/ \?\>[\n\r]*\<\? /s", " ", $template);
  221.         
  222.         //附加处理
  223.         $nTemplateRefresh = Template::$nTemplateRefresh;
  224.         $template = "<?php Template::checkCacheTemplate('".implode('|', Template::$sGlobal['sub_tpls'])."', $nTemplateRefresh, '$tpl');?>\r\n$template";
  225.         
  226.         //write
  227.         if(!Template::writeTemplateCacheContents($objfile, $template))
  228.         {
  229.             exit(Template::showError("File: $objfile can not be write!"));
  230.         }
  231.     }
  232.      /**
  233.      * php变量
  234.      * @function addquote
  235.      * @param string $var
  236.      * @return string
  237.      */
  238.      static private function addquote($var)
  239.      {
  240.         return str_replace("\\\"", "\"", preg_replace("/\[([a-zA-Z0-9_\-\.\x7f-\xff]+)\]/s", "['\\1']", $var));
  241.      }
  242.      /**
  243.      * php变量
  244.      * @function striptagquotes
  245.      * @param string $expr
  246.      * @return string
  247.      */
  248.      static private function striptagquotes($expr)
  249.      {
  250.         $expr = preg_replace("/\<\?\=(\\\$.+?)\?\>/s", "\\1", $expr);
  251.         $expr = str_replace("\\\"", "\"", preg_replace("/\[\'([a-zA-Z0-9_\-\.\x7f-\xff]+)\'\]/s", "[\\1]", $expr));
  252.         print $expr;
  253.      }
  254.     
  255.      /**
  256.      * php标签
  257.      * @function evaltags
  258.      * @param string $php
  259.      * @return string
  260.      */
  261.      static private function evaltags($php)
  262.      {
  263.         $i = Template::$sGlobal['i']++;
  264.         $search = "<!--EVAL_TAG_{$i} -->";
  265.         Template::$sGlobal['block_search'][Template::$sGlobal['i']] = $search;
  266.         Template::$sGlobal['block_replace'][Template::$sGlobal['i']] = "<?php ".Template::stripvtags($php)." ?>";        
  267.         return $search;
  268.      }
  269.      /**
  270.      * 替换输出标签
  271.      * @function stripvtags
  272.      * @param string $expr,$statement
  273.      * @return string
  274.      */
  275.      static private function stripvtags($expr, $statement='')
  276.      {
  277.         $expr = str_replace("\\\"", "\"", preg_replace("/\<\?\=(\\\$.+?)\?\>/s", "\\1", $expr));
  278.         $statement = str_replace("\\\"", "\"", $statement);
  279.         return $expr.$statement;
  280.      }
  281.     
  282.      /**
  283.      * 读取模板
  284.      * @function readTemplateContents
  285.      * @param string $name
  286.      * @return string
  287.      */
  288.      static private function readTemplateContents($name)
  289.      {
  290.         $tpl = Template::$sTemplateDir.'/'.Template::$sSelectTemplatePath.'/'.$name;
  291.         Template::$sGlobal['sub_tpls'][] = $tpl;
  292.         $file = $tpl.'.htm';
  293.         $content = Template::readContents($file);
  294.         return $content;
  295.      }
  296.      /**
  297.      * 读取文件内容
  298.      * @function readContents
  299.      * @param string $filename
  300.      * @return string
  301.      */
  302.      static private function readContents($filename)
  303.      {
  304.         $content = '';
  305.         if(function_exists('file_get_contents'))
  306.         {
  307.             @$content = file_get_contents($filename);
  308.         }else
  309.             {
  310.                 if(@$fp = fopen($filename, 'r'))
  311.                  {
  312.                     @$content = fread($fp, filesize($filename));
  313.                     @fclose($fp);
  314.                  }
  315.              }
  316.         return $content;
  317.      }
  318.      /**
  319.      * 写入文件
  320.      * @function writeTemplateCacheContents
  321.      * @param string $filename,$writetext,$openmod
  322.      * @return boolean
  323.      */
  324.      static private function writeTemplateCacheContents($filename, $writetext, $openmod='w')
  325.      {
  326.         if(@$fp = fopen($filename, $openmod))
  327.         {
  328.             flock($fp, 2);
  329.             fwrite($fp, $writetext);
  330.             fclose($fp);
  331.             return true;
  332.         } else
  333.             {
  334.                 exit(Template::showError('error'. "File: $filename write error."));
  335.                 return false;
  336.             }
  337.      }
  338.     /**
  339.      * 显示错误信息
  340.      * @function showError
  341.      * @param string $message
  342.      * @return void
  343.      */
  344.      static private function showError($message)
  345.      {
  346.          print $message;
  347.      }
  348.     
  349.     /**
  350.      *析构方法
  351.      */
  352.      function __destruct()
  353.      {
  354.          //......
  355.      }
  356. }
  357. ?>

作者: 七夜   发布时间: 2009-10-10

把一本书的代码搬上来

作者: fengrui   发布时间: 2009-10-10

不错。如果是原创的话。

作者: afeiship   发布时间: 2009-10-11

作者: lovets87   发布时间: 2009-10-11

作者: 263290692   发布时间: 2009-10-11

谁弄个 演示 程序发上来吧,刚学PHP 希望谁做个演示发上来.

作者: 99hk   发布时间: 2009-10-15

热门下载

更多