使用smarty的cache特别要注意的地方: 一定要用多级目录模式,但是默认的有问题,需要自己构造hash目录。本页最下面的评论中有我修改源码的解决方案 屈伟 2007/09/17 18:17

得到一个数组的大小, 类似于 count($array) :

if $answers|@count eq 0 

section 使用

	{% section name=i loop=$list_rand start=0 max=5 step=1 %}				
				<li> <a href="{%#BaseUrl#%}news/{%$list_rand[i].id %}" >{% $list_rand[i].title %}</a> </li>
	{% /section %}
			</ul>
		</div>
		<div style="float:right; width:49%;">
			<ul>
	{% section name=i loop=$list_rand start=5  step=1 %}				
				<li> <a href="{%#BaseUrl#%}news/{%$list_rand[i].id %}" >{% $list_rand[i].title %}</a> </li>
	{% /section %}
{%if  ($key+1) is div by 3 %}<br style="clear:both" /> {%/if%}
得到index的方法:  $smarty.section.sectionName.index 

模拟for

{assign var="loop" value="5"}{*给定循环次数*}
{section name="loop" loop=$loop}
    {$smarty.section.loop.index}  {*可以这样取得下标,内部将循环$loop次*}
{/section}

貌似php直接assign('loop'→5)就可以了:),刚才试了一下

缓存使用

$smarty->caching = true;
 
$tplFile = "user.tpl";
$cache_key = md5("user_tpl_". $user_id )  ;
 
if(!$smarty->is_cached($tplFile, $cache_key ) )  {
 
	// ...
	//代码
 
	$tpl->assign("news_list", $news_list );
}
$smarty->caching = 2;
$smarty->cache_lifetime = 60*60*24 ;
 
$smarty->display($tplFile, $cache_key );

应用

中文truncate问题:默认的truncate不支持中文。

function smarty_modifier_cn_truncate($string, $strlen = 20, $etc = '...',  $keep_first_style = false)
{
        $strlen = $strlen*2;
        $string = trim($string);
        if ( strlen($string) <= $strlen )        {
                return $string;
        }
        $str = strip_tags($string);
        $j = 0;
    for($i=0;$i<$strlen;$i++) {
      if(ord(substr($str,$i,1))>0xa0) $j++; 
        }
    if($j%2!=0) $strlen++; 
    $rstr=substr($str,0,$strlen);
    if (strlen($str)>$strlen  ) {$rstr .= $etc;} 
        if ( $keep_first_style == true && ereg('^<(.*)>$',$string) )        {
                if ( strlen($str) <= $strlen )        {
                        return $string;
                }
                $start_pos = strpos($string,substr($str,0,4));
                $end_pos = strpos($string,substr($str,-4));
                $end_pos = $end_pos+4;
                $rstr = substr($string,0,$start_pos) . $rstr . substr($string,$end_pos,strlen($string));
        }
    return $rstr; 
}

支持UTF-8和GBK的中文截取

function smarty_modifier_truncate_cn($string, $length = 80, $code = 'UTF-8', $etc = '...')
{
    if ($length == 0)
        return '';
    if($code == 'UTF-8'){
        $pa = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]/";
    }
    else{
    	$pa = "/[\x01-\x7f]|[\xa1-\xff][\xa1-\xff]/";
    }
    preg_match_all($pa, $string, $t_string);
    if(count($t_string[0]) > $length)
        return join('', array_slice($t_string[0], 0, $length)).$etc;
    return join('', array_slice($t_string[0], 0, $length));
}

自定义函数问题

smarty里可以直接使用自定义的函数,如:

自己写了个函数 function getcode($parm) {} 在smarty里可以这样: { $id|getcode } 这样$id就作为getcode的参数了。

但是如果函数有多个参数怎么办?

function getcode($a,$b,$c,$d) {
	echo "a:",$a," b:",$b," c:",$c," d:",$d ;
}

这样写就可以了!!! {% $a|getcode:$b:$c:$d %}

评论

Smarty的Cache有几个地方需要留意 1.带参数列表的php应用,cache的时候注意把完整的参数列表或者构造的SQL用MD5哈希一下,作为Cache的id。 2.display()函数可以被子类覆盖吧,比如我用Smarty的时候就继承了一个Smarty,构造了自己的Smarty_AB类,我研究一下能不能通过函数覆盖把他cache的文件hash掉,再不成可以直接考虑改丫源码。。。。 comment by yp @07-04-30 15:26

嗯,我也重构了。smary好像有很多插件,估计自己不用写能找到。我找找。 — 屈伟 2007/05/02 10:48
设置$use_sub_dirs=true可以开启分级目录功能,默认创建2级目录
如果设置display(“template.tpl”, “dir1|dir2|dir3”),可以生成多级目录,我们可以根据自己需要,通过合适的hash函数,从$cache_id来生成hash目录. — shwan
oh,good! 默认的就够了。哈哈。手册了就只有一个 $use_sub_dirs 变量 ,我说怎么没看到呢。 — 屈伟 2007/05/16 14:48
smarty cache有点弱智。想多级目录原来要 dir1|dir2|dir3 这样些cache_id 。直接给一个cache_id,smarty居然把cache_id作为一个文件夹,然后把display的文件名hash了。以前没注意这个问题,一个9万条记录的系统,结果一个目录下搞了9万个目录。都快气死我了。只要修改了smarty的源码。如下:将smarty.class.php中 函数_get_auto_filename 修改为:
function _get_auto_filename($auto_base, $auto_source = null, $auto_id = null)
{
	$_compile_dir_sep =  $this->use_sub_dirs ? DIRECTORY_SEPARATOR : '^';
	$_return = $auto_base . DIRECTORY_SEPARATOR;

	if(isset($auto_id)) {
		// make auto_id safe for directory names
		$auto_id = md5($auto_id);
		// split into separate directories
		$_return .= substr($auto_id, 0,2) . $_compile_dir_sep . substr($auto_id, 2,2). $_compile_dir_sep . $auto_id ; 
	}
	if(isset($auto_source)) {
		// make source name safe for filename
		$_filename = urlencode(basename($auto_source));
		$_crc32 = sprintf('%08X', crc32($auto_source));
		$_return .= '%%' . $_crc32 . '%%' . $_filename;
	}

	return $_return;
}

这丫真有点弱智,默认的hash连模板编译目录都给hash了。没任何意义啊。怎么也不可能有几千个模板吧。我随便将那个给去掉了。 — 屈伟 2007/09/17 18:15

smarty模板模拟foreach

以实际项目开发为例,我需要在页面的footer显示数据库内友情链接,写一次,能在任何地方都可用; ①在smarty/plugins/下写一个function.link_list.php文件

<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
 * 友情链接列表
 */
function smarty_function_link_list($params, &$smarty) {
	$name = "link_list";
	$CI = & get_instance ();
	$CI->load->database();
	$sql = "SELECT * FROM `links` ORDER BY `cdate` ASC";
	$linklist = $CI->db->query($sql)->result_array();
	$smarty->assign($name, $linklist);

}

②打开smarty下的Smarty_Compiler.class.php文件,搜索“switch ($tag_command) {”,在其内部添加

case 'link_list':
      $this->_push_tag('link_list');
      return $this->_compile_link_list_start($tag_args);
      break;
case '/link_list':
      $this->_pop_tag('link_list');
      return "<?php endforeach; endif; unset(\$_from); ?>";

③在该文件内,添加下面函数

function _compile_link_list_start($tag_args)
    {
    	$this->_add_plugin('function', 'link_list');
        $attrs = $this->_parse_attrs($tag_args);
        $_cache_attrs = '';
        $arg_list = $this->_compile_arg_list('function', 'link_list', $attrs, $_cache_attrs);
        $output ='<?php '; 
        $output .= $this->_compile_plugin_call('function','link_list').'(array('.implode(',', $arg_list)."), \$this);";
		$output .=' ?>';
        $tag_args .=' from=$link_list ';
		return $output.$this->_compile_foreach_start($tag_args);
    }

这样,在模板页内就可以使用

{%link_list item=link%}
<a href="{%$link.link_url%}" target="_blank">{%$link.title%}</a> 
{%/link_list%}

来循环出来所有友情链接

Smarty中in_array函数的应用

php脚本:

$Action= array("article","soft","news");
$smarty->assign("Action",$Action);

模板:

<!–{if ‘article’|in_array:$Action}–>在数组内<!–{else}–>非数组内的值<!–{/if}–>

User:alex_shao@foxmail.com 2009-11-18 10:02:07

php/smarty.txt · 最后更改: 2009/11/18 14:06 由 alex_best
到顶部
chimeric.de = chi`s home Creative Commons License Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0 红麦软件 红麦软件