PHP里面有一个很流行的词:“模板”,所谓“模板”,是一种在Web开发中将html文件和脚本分离的一种做法,试图更清楚的划分程序员和美工的界限,等等功能。 我一直很郁闷的就是,写程序的时候必须在模板和PHP之间来回奔波,每用一种模板,都要适应它们的语法,抱怨它们的不足。 至于模板的好处,我就不说了,网上多的是。 为什么不用传统的html和php混合编写的方式?各有各的看法。 如果用模板,至少有两个缺点: 1、速度 不管哪一种模板,都要将模板语言转换成PHP语句,即使是号称有“编译”功能的Smarty、smarttemplate等等。尤其是Smarty,Smarty过于庞大和复杂,即使经过编译,php程序每次还是得初始化Smarty类、经过一系列判断…… 如果你去看看Smarty缓存文件,或许你会觉得,里面的代码象你刚学php的时候写的…… 2、功能 在用模板写程序的时候,“多种循环”和“文件嵌套”经常会将人折磨的很郁闷,反正我在刚开始用这些模板的时候就是。 如果直接用混合PHP和html的方式,这种问题马上就迎刃而解了。 最近做的一个项目里面,一直被Smarty的庞大和效率所困扰,最终决定放弃这个庞然大物,选择了最古老的PHP与HTML代码混合的方式。但是姑且还是将其称为“模板”吧。 用Smarty的时候,我是自己写了一个类,按照phplib的方法名重写封装了一下Smarty。决定放弃Smarty以后,模板文件肯定要全部重写,但是为了尽量减少程序的修改,我将这个类全部重新改写了,去处了所有与Smarty相关的代码,取而代之的是下面这个简单的类:
<?php class ezj_template { /** * @access public * @var string */ var $t_dir = ''; var $skin = ''; var $common = ''; var $template_cfg = array(); var $main = ''; var $vars = array(); function ezj_template() { global $ezj; $this->t_dir = ROOT_PATH . $ezj->cache['template']['tpl_path'] . '/'; @include( $this->t_dir . '_config.php' ); $this->template_cfg = $_template_config; }//-- end of constructor /* * 将模板内容输出到浏览器 @param string $cache_id @param string $compile_id @access public @return void */ function output($cache_id = null, $compile_id = null) { global $ezj , $db; require_once( VIEWS . 'template/class.template_common.php' ); $this->common = new template_common(&$this); $this->common->run(); @header("HTTP/1.0 200 OK"); @header("HTTP/1.1 200 OK"); @header("Content-type: text/html;charset=utf-8"); if ($ezj->vars['header_no_cache']) { @header("Cache-Control: no-cache, must-revalidate, max-age=0"); @header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); @header("Pragma: no-cache"); } if ( $ezj->vars['gunzip_enabled']==1 ) { $buffer = @ob_get_contents(); @ob_end_clean(); @ob_start('ob_gzhandler'); print $buffer; } extract($this->vars); $t = &$this->t_dir; @include_once( $t . $this->main ); if ( defined('WITHOUT_SHUTDOWN') ) { $ezj->_destruct(); } }//-- end of method `output` function set_var($tpl_var, $value = null) { $this->assign($tpl_var , $value); } function set_file($file) { $this->main = $file; } function assign($var , $value=null) { if ( is_array($var) ) { foreach($var as $k=>$v) { $this->vars[$k] = $v; } }else { $this->vars[$var] = $value; } } }//-- end of class `ezj_template` ?>
这个类里面比较关键的$main , $vars , function output(),第一个记录了将要输出的模板(其实是一个php文件),第二个以数组方式保存所谓的“模板变量”,第三个是将模板内容输出到浏览器。 在我的思路里面,所谓的“模板”不再是单纯的HTML和模板语言结合的文件,而是一个传统的PHP与HTML混合的文件,在模板类向浏览器输出内容的时候,把这个“模板”include进来就可以了,下面就是一个我项目里的“模板”文件:
<?php include($t.'include/header.php');?> <?php if ( $_popup ) { ?> <?=$_pop_window?> <?php } ?> <table width="780" border="0" align="center" cellpadding="0" cellspacing="0"> <tbody> <tr> <td width="479" height="34" background="<?=$_tpl_path?>images/index_05.gif"> <?php if ( $_tpl_cfg_show_search ) { ?> <?php include($t.'include/search.php');?> <?php } ?> </td> <td width="301" background="<?=$_tpl_path?>images/index_05.gif"><IMG SRC="<?=$_tpl_path?>images/index_09.gif" WIDTH=301 HEIGHT=34 ALT=""></td> </tr> </tbody> </table> <table width="780" border="0" align="center" cellpadding="0" cellspacing="0"> </tbody> <tr> <td width="213" height="404" valign="top" background="<?=$_tpl_path?>images/index_20.gif"> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td><IMG SRC="<?=$_tpl_path?>images/index_13.gif" WIDTH=237 HEIGHT=23 ALT=""></td> </tr> </table> <?php if ( $_tpl_cfg_show_vote ) { ?> <table width="237" border="0" cellspacing="0" cellpadding="0"> <tr> <td><table width="100%" border="0" cellpadding="0" cellspacing="0" class="black-12-20"> <tr> <td width="16%"><img src="<?=$_tpl_path?>images/index_15.gif" width=37 height=33 alt=""></td> <td width="80%" background="<?=$_tpl_path?>images/index_16.gif"><strong><?=$_vote_module_disp_name?></strong></td> <td width="4%"><IMG SRC="<?=$_tpl_path?>images/index_18.gif" WIDTH=29 HEIGHT=33 ALT=""></td> </tr> </table></td> </tr> <tr> <td> <table width="100%" border="0" align="center" cellpadding="0" cellspacing="0"> <tr> <td height="9"><img src="<?=$_tpl_path?>images/spacer.gif" width="1" height="1"></td> </tr> </table> <?php include($t.$_vote_module_file);?> </td> </tr> </table> <?php } ?> <?php if ( $_tpl_cfg_show_link ) { ?> <table width="237" border="0" cellspacing="0" cellpadding="0"> <tr> <td> <table width="100%" border="0" cellpadding="0" cellspacing="0" class="black-12-20"> <tr> <td width="16%"><img src="<?=$_tpl_path?>images/index_15.gif" width=37 height=33 alt=""></td> <td width="80%" background="<?=$_tpl_path?>images/index_16.gif"><strong><?=$_link_module_disp_name?></strong></td> <td width="4%"><IMG SRC="<?=$_tpl_path?>images/index_18.gif" WIDTH=29 HEIGHT=33 ALT=""></td> </tr> </table> </td> </tr> <tr> <td ><?php include($t.$_link_module_file);?></td> </tr> </table> <table width="33%" border="0" align="center" cellpadding="0" cellspacing="0"> <tr> <td height="66"> <?php if ( $_tpl_cfg_enable_service_module ) { ?> <div align="center"><a href="javascript:" onClick="MM_openBrWindow('<?=$_common_files?>service/fuwutai.php','','width=531,height=373')"><img src="<?=$_tpl_path?>images/service.gif" width="177" height="49" border='0'></a></div> <?php } ?> </td> </tr> </table> <?php } ?> </td> <td width="567" valign="top"> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td><IMG SRC="<?=$_tpl_path?>images/index_14.gif" WIDTH=543 HEIGHT=23 ALT=""></td> </tr> </table> <?php if ( $_tpl_cfg_show_news ) { ?> <table width="95%" border="0" align="center" cellpadding="0" cellspacing="0"> <tr> <td colspan="2"> <table width="100%" border="0" align="center" cellpadding="0" cellspacing="0" class="black-12-20"> <tr> <td width="2%"><img src="<?=$_tpl_path?>images/index_15.gif" width=37 height=33 alt=""></td> <td width="93%" background="<?=$_tpl_path?>images/index_16.gif"><strong><?=$_news_module_disp_name?></strong></td> <td width="5%"><IMG SRC="<?=$_tpl_path?>images/index_18.gif" WIDTH=29 HEIGHT=33 ALT=""></td> </tr> </table> </td> </tr> <tr> <td colspan='2' align='center'> <?php include($t.$_news_module_file);?> </td> </tr> </table> <?php } ?> <?php if ( $_tpl_cfg_show_prod ) { ?> <table width="95%" border="0" align="center" cellpadding="0" cellspacing="0"> <tr> <td colspan="2"><table width="100%" border="0" align="center" cellpadding="0" cellspacing="0" class="black-12-20"> <tr> <td width="2%"><img src="<?=$_tpl_path?>images/index_15.gif" width=37 height=33 alt=""></td> <td width="93%" background="<?=$_tpl_path?>images/index_16.gif"><strong><?=$_prod_module_disp_name?></strong></td> <td width="5%"><IMG SRC="<?=$_tpl_path?>images/index_18.gif" WIDTH=29 HEIGHT=33 ALT=""></td> </tr> </table></td> </tr> <tr> <td width="100%" height="121" valign="top" colspan='2'> <?php include($t.$_prod_module_file);?> </td> </table> <?php } ?> </td> </tr> </table> </td> </tr> </tbody> </table> <?php include($t.'include/foot.php');?> </body> </html>
我从这样的修改中获得了下列好处: 1、效率 根据我的调试,在用Smarty之前,项目首页在我的本本上基本上要消耗0.1x~0.2x秒之间,放弃Smarty以后,基本稳定在0.07x以下 2、更加精简的PHP文件
备注:Smarty是一个好东西,但是并不是任何时候都适合用Smarty来开发项目^^