Skip to content

控制输出的可缓存性 {/programmers/caching/caching-cacheable/}

如果启用了缓存,通常整个页面的最终输出都会被缓存。然而,Smarty3 提供了几个选项,可以排除缓存输出的某些部分。

注意

请确保在非缓存部分内使用的任何变量在从缓存加载页面时也从 PHP 中分配。

模板部分的可缓存性 {#cacheability.sections}

你可以通过使用{nocache}{/nocache} 标签,轻松地将模板的大部分内容排除在缓存之外。

今天的日期是
{nocache}
{$smarty.now|date_format}
{/nocache}

上述代码将在缓存的页面上输出当前日期。

标签的可缓存性 {#cacheability.tags}

通过在标签中添加 "nocache" 选项标志,可以禁用单个标签的缓存。

今天的日期是
{$smarty.now|date_format nocache}

变量的可缓存性 {#cacheability.variables}

你可以将变量 assign() 为不可缓存。任何使用这样的变量的标签都将自动在 nocache 模式下执行。

注意

如果一个标签在 nocache 模式下执行,你必须确保当页面从缓存加载时,该标签使用的所有其他变量也从 PHP 中分配。

注意

分配变量的 nocache 状态将影响编译的模板代码。如果你改变了状态,你必须手动删除现有的编译和缓存的模板文件,以强制重新编译。

// 将 $foo 分配为 nocahe 变量
$smarty->assign('foo',time(),true);


动态时间值是 {$foo}

插件的可缓存性 {#cacheability.plugins}

在注册插件时可以声明插件的可缓存性。registerPlugin() 的第三个参数称为 $cacheable,默认为 TRUE。

当注册一个 $cacheable=false 的插件时,每次显示页面时都会调用该插件,即使页面来自缓存。插件函数的行为有点像 {insert} 函数。

注意

$cacheable 状态将影响编译的模板代码。如果你改变了状态,你必须手动删除现有的编译和缓存的模板文件,以强制重新编译。

{insert} 不同,插件的属性默认不会被缓存。它们可以通过第四个参数 $cache_attrs 声明为可缓存。 $cache_attrs 是应该被缓存的属性名的数组,所以插件函数每次从缓存中获取时都会得到写入缓存时的值。

<?php
$smarty->setCaching(Smarty::CACHING_LIFETIME_CURRENT);

function remaining_seconds($params, $smarty) {
    $remain = $params['endtime'] - time();
    if($remain >= 0){
        return $remain . ' second(s)';
    }else{
        return 'done';
    }
}

$smarty->registerPlugin('function','remaining', 'remaining_seconds', false, array('endtime'));

if (!$smarty->isCached('index.tpl')) {
    // 从数据库获取 $obj 并分配...
    $smarty->assignByRef('obj', $obj);
}

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

其中 index.tpl 是:

剩余时间: {remaining endtime=$obj->endtime}

直到 $obj 的结束时间,每次显示页面时,剩余的秒数都会改变,即使页面被缓存。由于结束时间属性被缓存,所以只有在页面写入缓存时才需要从数据库中获取对象,而在后续的页面请求中则不需要。

index.php:

<?php
$smarty->setCaching(Smarty::CACHING_LIFETIME_CURRENT);

function smarty_block_dynamic($param, $content, $smarty) {
    return $content;
}
$smarty->registerPlugin('block','dynamic', 'smarty_block_dynamic', false);

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

其中 index.tpl 是:

页面创建时间: {'0'|date_format:'%D %H:%M:%S'}

{dynamic}

现在时间: {'0'|date_format:'%D %H:%M:%S'}

... 做其他事情 ...

{/dynamic}

当重新加载页面时,你会注意到两个日期是不同的。一个是"动态"的,一个是"静态"的。你可以在 {dynamic}...{/dynamic} 之间做任何事情,并确保它不会像页面的其余部分那样被缓存。

注意

上述示例只是为了演示动态块插件的工作方式。查看 模板部分的可缓存性 了解如何使用内置的 {nocache}{/nocache} 标签禁用模板部分的缓存。