关于smarty中的$cache_id及$compile_id

首先引用Smarty官方网站上的一段代码:

You can also pass a $cache_id as an optional second parameter in case you want multiple caches for the given template.


<?php
require('Smarty.class.php');
$smarty = new Smarty;

$smarty->caching 1;

$my_cache_id $_GET['article_id'];

$smarty->display('index.tpl'$my_cache_id);
?>

Above, we are passing the variable $my_cache_id to display() as the $cache_id. For each unique value of $my_cache_id, a separate cache will be generated for index.tpl. In this example, article_id was passed in the URL and is used as the $cache_id.


简单来说$cache_id就是用于通过一个模板文件,如上面的index.tpl来生成多个缓存文件,如index_1.html,index_2.html,1与2可以理解为url中的参数,这样通过一个url就能生成多个缓存页面,比如新闻系统里面可能就会用到这些


$compile_id

  Smarty.class.php中的说明
  /**
     * Set this if you want different sets of compiled files for the same
     * templates. This is useful for things like different languages.
     * Instead of creating separate sets of templates per language, you
     * set different compile_ids like 'en' and 'de'.
     *
     * @var string
     */
    var $compile_id            = null;


Persistant compile identifier. As an alternative to passing the same $compile_id to each and every function call, you can set this $compile_id and it will be used implicitly thereafter.


With a $compile_id you can work around the limitation that you cannot use the same $compile_dir for different $template_dirs. If you set a distinct $compile_id for each $template_dir then Smarty can tell the compiled templates apart by their $compile_id.


If you have for example a prefilter that localizes your templates (that is: translates language dependend parts) at compile time, then you could use the current language as $compile_id and you will get a set of compiled templates for each language you use.


Another application would be to use the same compile directory across multiple domains / multiple virtual hosts.


上文的大致翻译

$compile_id

    持续化的编译识别符。我们不用在每次函数调用时显式传递同一个$compile_id,而是可以设置该$compile_id,而它将被隐式调用。

    使用$compile_id,你可以绕开对不同的$template_dirs不能使用相同的$compile_dir的限制。如果你对每个$template_dir赋予一个唯一的$compile_id,那么Smarty就可以根据它们的$compile_id来区别各个编译的模板。

    例如,在编译时你有一个前过滤器以当地化你的模板(即:翻译与语种相关的部分),那么你就可以用当前语种作为$compile_id,从而对于每个你使用的语种,你将获得一套编译的模板。

    另一个应用是,对于多域名/多虚拟主机使用相同的编译目录。

例子12-6. 虚拟主机环境下的$compile_id



Example 12-6. $compile_id in a virtual host enviroment

<?php

$smarty
->compile_id $_SERVER['SERVER_NAME'];
$smarty->compile_dir '/path/to/shared_compile_dir';

?>

关于smarty的cache_id和compile_id的说明

我一直对smarty的cache_id和compile_id有点混淆,总分不清有什么区别,好在以前没有遇到smarty的复杂应用,所以也就作罢了,不过这阵子一直在做多语言,多风格并存的UTF-8编码的网站,为了提高效率,决定使用smarty的缓存,就不得不好好看看了。对于我这个问题,很自然应该根据语言,风格(缓存组:language|theme)来缓存。那是放在cache_id里还是compile_id里呢?看看手册上对此的说明:

As an optional third parameter, you can pass a compile_id. This is in the event that you want to compile different versions of the same template, such as having separate templates compiled for different languages. Another use for compile_id is when you use more than one $template_dir but only one $compile_dir. Set a separate compile_id for each $template_dir, otherwise templates of the same name will overwrite each other. You can also set the $compile_id variable once instead of passing this to each call to this function.

这样看来,compile_id一般是用在你有多个template_dir但只有一个compile_dir,或者对同一个模板有不通的编译结果的情况下。比如showNews.php?newsId=123这样的情况,很自然的$_GET['newsId']应该作为compile_id存在。


简单来说$compile_id用于编译不同目录下的模板文件,以示区分生成的编译文件名,告诉Smarty你现在要编译哪个目录下的文件,主要用在$template_dir是一个以上目录的情况下

Smarty.class.php中的方法fetch中有如下的一行
$_smarty_compile_path = $this->_get_compile_path($resource_name);
然后方法_get_compile_path再调用方法_get_auto_filename方法,我们可以看到,_get_auto_filename的第三个参数就是$this->compile_id(也就是我们这儿所说的$compile_id),从
_get_auto_filename可以看到,编译文件名是跟参数$compile_id关联的,也就是说默认情况下一般不传$compile_id的时候$compile_id是空值,如果传入了$compile_id,则生成的编译文件名就与$compile_id关联起来了。
下面的前提是认为$compile_dir是同一个目录的情况下
1.现在假设某目录下有一个名为index.tpl.tml的模板文件,现在我们需要一套英文的模板、一套中文的模板,编译模板时,如果不传入$compile_id参数,则后一个生成的编译文件则覆盖前一个文件了,因为他们的文件名是相同的,所以如果你想让两个编译文件同时存在,则必须传入不同$compile_id参数,如en代表英文模板,cn代表中文模板。

2.现在假设a目录与b目录下均有一个名为index.tpl.tml的模板文件,如果不传入$compile_id参数,则后一个生成的编译文件则覆盖前一个文件了,因为他们的文件名是相同的,只是模板所在的目录名不相同而已。所以如果你想让两个编译文件同时存在,则必须传入$compile_id参数以示区分。

  /**
     * Get the compile path for this resource
     *
     * @param string $resource_name
     * @return string results of {@link _get_auto_filename()}
     */
    function _get_compile_path($resource_name)
    {
        return $this->_get_auto_filename($this->compile_dir, $resource_name,
                                         $this->_compile_id) . '.php';
    }

/**
     * get a concrete filename for automagically created content
     *
     * @param string $auto_base
     * @param string $auto_source
     * @param string $auto_id
     * @return string
     * @staticvar string|null
     * @staticvar string|null
     */
    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 = str_replace('%7C',$_compile_dir_sep,(urlencode($auto_id)));
            // split into separate directories
            $_return .= $auto_id . $_compile_dir_sep;
        }

        if(isset($auto_source)) {
            // make source name safe for filename
            $_filename = urlencode(basename($auto_source));
            $_crc32 = sprintf('%08X', crc32($auto_source));
            // prepend %% to avoid name conflicts with
            // with $params['auto_id'] names
            $_crc32 = substr($_crc32, 0, 2) . $_compile_dir_sep .
                      substr($_crc32, 0, 3) . $_compile_dir_sep . $_crc32;
            $_return .= '%%' . $_crc32 . '%%' . $_filename;
        }

        return $_return;
    }

posted on 2009-05-19 12:10  5201314  阅读(562)  评论(0编辑  收藏  举报

导航