字体:  

教教你们这些***,如何使用SMARTY开发.[教育帖]

stc6895 发表于: 2008-6-26 13:48 来源: PHPChina 开源社区门户

本来是不想发这帖的...看见有那么多人说smarty复杂什么的.简直无语.

复杂不是错,学不会就是你的错了.

态度决定一切...存在必有其道理....

下面我就从我们目前开发的硬件管理平台mge来说说smarty的应用.

此次开发中smarty很好的帮助我们解决许多问题.从界面的构成到最终的视图装配.

系统版本1.1...
此产品的声明周期为2年,在2年中我们会坚持使用smarty.

先看图


11.jpg



22.jpg



33.jpg


如此华丽的界面我们看看其布局代码如何:

CODE:

<body>
{{include file="basic/block.html"}}
<div id="body" class="normal">
<div class="content">
<div id="content_title">{{include file="basic/header.html"}}</div>
<div id="content_main">
        <div id="panel">
        {{$panel}}
        </div>
        <div id="main_content">
        {{$main_content}}
        </div>
</div>
</div>        
</div>
{{include file="basic/cover.html"}}
</body>
好如此灵活多变的视图,我们仅采用了1个布局模版,7个组件模版,以及72个表单内容,就完成整个系统92套页面变化的制作。
模版之间冗余极小。

下面看模版代码

CODE:

<div id="form">
        <form action="{{$form.action}}" method="post">
                <table width="100%" cellspacing="0">
  <tr>
    <td width="23%">{{$ui.basecfg}}</td>
    <td width="77%"> </td>
  </tr>
  <tr>
    <td>{{$ui.icmp}}</td>
    <td><input name="icmp_block_broadcast" type="checkbox" class="formfld" value="yes" {{if $form.icmp_block_broadcast!=''}} checked="checked" {{/if}}>
{{$ui.blockicmpbroadcast}}  
<input name="icmp_block_all" type="checkbox" class="formfld" value="yes" {{if $form.icmp_block_all!=''}} checked="checked" {{/if}}>
{{$ui.blockicmpall}}</td>
  </tr>
  <tr>
    <td>{{$ui.tcpprot}}</td>
    <td><input name="block_tcp_synfin" type="checkbox" class="formfld" value="yes" {{if $form.block_tcp_synfin!=''}} checked="checked" {{/if}}>
      {{$ui.blocksynandfin}}<br/>
      <input name="enable_tcp_timestamp" type="checkbox" class="formfld" value="yes" {{if $form.enable_tcp_timestamp!=''}} checked="checked" {{/if}}>
      {{$ui.enabletcptimestamp}}<br/>
      <input name="enable_tcp_selectack" type="checkbox" class="formfld" value="yes" {{if $form.enable_tcp_selectack!=''}} checked="checked" {{/if}}>
      {{$ui.enableselectiveack}}<br/>
      <input name="enable_tcp_ecn" type="checkbox" class="formfld" value="yes" {{if $form.enable_tcp_ecn!=''}} checked="checked" {{/if}}>
      {{$ui.enableecn}}</td>
  </tr>
  <tr>
    <td>{{$ui.others}}</td>
    <td><input name="discard_igmp" type="checkbox" class="formfld" value="yes" {{if $form.discard_igmp!=''}} checked="checked" {{/if}}>
      {{$ui.discardigmp}}  
      <input name="discard_multicast" type="checkbox" class="formfld" value="yes" {{if $form.discard_multicast!=''}} checked="checked" {{/if}}>
      {{$ui.discardmulticast}}</td>
  </tr>
  <tr>
    <td colspan="2" align="center"><input name="btnSubmit" type="submit" class="formButton" value="{{$ui.ui_fw_settings_submit}}">   <input type=button class="formButton" onClick="javascript:history.go(-1)" value="{{$ui.ui_fw_settings_return}}"></td>
    </tr>
</table>

        </form>
</div>
采用多语言,单一注入的结构来简化assign的使用。语言包分为ui界面包,和数据包form。以保证表单的正常运作。

那么如何实现这一个华丽界面的输出呢。
看代码:

CODE:

function actionPolicyList()
                {
                        parent::_setBack();
                        $policylist=$this->obj_App->getWebPolicy($_GET);
                        foreach ($policylist as $key=>$rc)
                        {
                                $rc['operate']['adv'] = url('ctlAppProtect','PolicyEdit',array('pol_id'=>$key));
                                $rc['operate']['del'] = url('ctlAppProtect','PolicyDel',array('pol_id'=>$key));
                                $list[]= $rc;
                        }
                        $data = array('btnAdd'=>url('ctlAppProtect','PolicyAdd'),'list'=>$list);
                        $tpl_form[] = parent::_getTplGrid('se_webpolicy',$data);
               
                        $tpl_tab= parent::_getTplComponent('tab',$tpl_form);
                        
                        
                        
                        $window = array('title'=>_T('nv_se_webpolicy'),'content'=>$tpl_tab );
                        $tpl_window = parent::_getTplComponent('window',$window);
                        
                        parent::_display($tpl_window);
                }
---------------------

CODE:

$policylist=$this->obj_App->getWebPolicy($_GET);
                        foreach ($policylist as $key=>$rc)
                        {
                                $rc['operate']['adv'] = url('ctlAppProtect','PolicyEdit',array('pol_id'=>$key));
                                $rc['operate']['del'] = url('ctlAppProtect','PolicyDel',array('pol_id'=>$key));
                                $list[]= $rc;
                        }
这两句获得数据并构造,由于系统在1.1版本,很多地方需要调整,以后这将一起归并到form对象或数据构造层去。

CODE:

$data = array('btnAdd'=>url('ctlAppProtect','PolicyAdd'),'list'=>$list);//构造form数据
                        $tpl_form[] = parent::_getTplGrid('se_webpolicy',$data);//获得列表组件
                        $tpl_tab= parent::_getTplComponent('tab',$tpl_form);//注入列表组件 ,获得tab组件
                        $window = array('title'=>_T('nv_se_webpolicy'),'content'=>$tpl_tab );注入tab,构造窗体数据
                        $tpl_window = parent::_getTplComponent('window',$window);最终获得窗体数据,准备输出。
这里是构造数据,注入模版,装配视图的地方,以后会归并到视图装配层去。如此上两大段代码将被2行代码取代。大大减少代码冗余。这里我们将smarty重新封装了一次。以达到代码精简。

以下核心代码就暂时不帖。嘿嘿。。不能透露啊。。

总结:
smarty不是错,错的是用它的人,效率低可以从其他方面入手。所以各位***们别总说smarty怎么怎么的,从其他方面入手改善其性能。无味的争执是无趣的。存在必有道理。注重技术选型,哪里会有这么多的争执。

[ 本帖最后由 神仙 于 2008-6-30 15:00 编辑 ]

最新回复

ruhong65 at 2008-6-26 13:58:36
smarty~~~~~~~~~~~
ruhong65 at 2008-6-26 14:02:38
小鸡崽 这个名字我喜欢
peacock at 2008-6-26 14:10:34
非常喜欢smarty,想让它简单,它就能非常简单,想让它复杂,它也能很复杂。
fyland at 2008-6-26 14:48:07
技术问题暂且搁一边不说,楼主这种说话语气实在让人不舒服,不知道能否改一改?
七月十五 at 2008-6-26 14:50:52
just so so ...

[ 本帖最后由 七月十五 于 2008-6-26 14:52 编辑 ]
mayongzhan at 2008-6-26 16:45:13
天天看程序员吵...很有意思......................................

比流氓吵的文明多了.....


新一论的吵架 即将诞生于本贴~~~
pylong at 2008-6-26 16:51:53
占座看吵架
xinzf at 2008-6-26 17:03:10
LZ的语气,貌似很强,很大,很无礼,很自大
coolphp at 2008-6-26 18:12:50
送LZ四个字,
牛×哄哄!
fhjr999 at 2008-6-26 18:39:04
楼上的兄台,不要盗版我的名字,虽然我叫牛哄哄,比你那个少了个X,但我一样告你侵权的。
fhjr999 at 2008-6-26 18:45:36
我不喜欢smarty,但是我也不至于坚决反对别人去用。

smarty确实比较复杂,至于学不会是自己的问题,这个我不赞同,一样工具,应该在提供同样功能的情况下,尽可能简单,这样才符合潮流,未来的事物越来越多,越来越高级,如果都搞复杂化的话,人类很快就会玩完的,到了老死,也许还在基础部分转悠。

至于性能问题,smarty编译的缓存,确实不怎么样,跟高性能是搭不上边的,至于从其他地方优化,我不是很明白,是说的模板之外的地方的优化吗??
如果是这样的话,模板之外的地方同样优化,同时选择一个高性能的模板引擎,这样不是更好吗??
fhjr999 at 2008-6-26 18:47:31
采用一些简单的方法的话,模板引擎完全可以作到性能高于原生PHP+HTML的。
wlxm007 at 2008-6-26 21:38:09
SA LI BA JI
forweike at 2008-6-26 23:10:48
呵呵,楼主高手,我还在初学SMARTY呢
zshtom at 2008-6-26 23:49:28
可以这么说 我就算是小鸡仔  个人的程序 坚决不会用 公司程序一定会用
zshtom at 2008-6-26 23:56:12
可以这么说 我就算是小鸡仔  个人的程序 坚决不会用 公司程序一定会用  

我自己做的模板 达到了几个 smarty 没有做到的
编译的文件 将php解析开关次数减少至最小 这个可以效率提高一些
模板中支持 调用php 函数  
无论多少层模板文件之间的嵌套 最后生成的编译文件只有一个主模板的文件  减少包含次数
编译文件中自动去掉没用的换行
使用简单不用assign 直接包含一个文件即可 所有赋值有php自动完成 这个类似dz的模板 语法也和dz的模板一样

总之smarty 呢就是麻烦

最后 比较讨厌楼主说话的语气  对smarty 没有好感的不仅仅是小鸡仔
fhjr999 at 2008-6-27 01:02:46
呵呵,楼上的跟我的很像啊。

除了我现在还用assign,不过新版本打算抛弃,也采用DZ那种模式(其实最开始我用的就是DZ那种模式),解析部分与模板掉用部分也分离,争取正常使用时,只需要加载一个小小的函数。

打算加入变量名前缀功能,在模板中的变量不需要写前缀,编译时会自动添加。例如你设置了前缀为v_
模板中的标签{$name}会被编译为<?=$v_name?>
便于将模板中用到的数据与其他区分开来。

还有优化部分,我的优化语句是/>\s+</替换为> <,相邻标签的编译结果也合并,这样的话,完全可以做到使用模板引擎比原生PHP+HTML性能更高,而且高的还不是一个小数目。

[ 本帖最后由 fhjr999 于 2008-6-27 01:04 编辑 ]
fyland at 2008-6-27 09:21:23

QUOTE:

原帖由 fhjr999 于 2008-6-27 01:02 发表
呵呵,楼上的跟我的很像啊。

除了我现在还用assign,不过新版本打算抛弃,也采用DZ那种模式(其实最开始我用的就是DZ那种模式),解析部分与模板掉用部分也分离,争取正常使用时,只需要加载一个小小的函数 ...
“这样的话,完全可以做到使用模板引擎比原生PHP+HTML性能更高,而且高的还不是一个小数目。”
================================================================================================
heredoc整个模板就一对<?php ?>标签
Phzzy at 2008-6-27 09:32:56
<?php
require "core.php";
run();
?>


如此华丽庞大的网站,竟然只有两行代码, omg~
fhjr999 at 2008-6-27 09:41:23
我没说是多对啊。

我说的模板引擎可以做到比heredoc性能更高,理由是:
1,模板引擎可以过滤缓存中多余的空格、TAB、回车,对于一个良好缩进的模板来说,这部分的体积并不小,这样优化,要比PHP的输出压缩好的多,不仅可以让程序执行更快,而且往浏览器输送数据的时间也可以简短。
2,完完全全的按需加载,咱们在正常规划程序的时候,一般是将同一类型的函数放入一个文件,比如字符串处理函数。一个文件中有多个函数,但是往往咱们只需要使用其中的1,2个,除此之外的函数就是冗余的。而且在脚本中加载函数库时,也往往是在文件头部包含,但是也许是要到脚本底部才用的到。而模板引擎完全可以避免这两点,真正做到按需加载。
3,将页面区块合并成一个整体,如果一个页面分成多个小区域的话,模板引擎可以将这些小区域全部合并成一个整体,我没有测试,但是我想,这样对减小硬盘IO,应该还是很有帮助的,当然,如果你采用了一些缓存技术,就不算这一条。