老葛的Drupal培训班 Think in Drupal
根据它们的内容,区块也可以被缓存。使用管理界面“管理➤站点配置 ➤性能”,可以启用或者禁用Drupal的区块缓存(参看图15-5)。
图15-5. 用来控制区块缓存行为的管理界面
当一个模块实现hook_block()时,可以在list操作下,声明区块的缓存能力,这样就能实现区块缓存了。例如,下面是modules/user/user.module的hook_block()实现中的部分代码:
function user_block($op = 'list', $delta = 0, $edit = array()) {
global $user;
if ($op == 'list') {
$blocks[0]['info'] = t('User login');
// Not worth caching.
$blocks[0]['cache'] = BLOCK_NO_CACHE;
$blocks[1]['info'] = t('Navigation');
// Menu blocks can't be cached because each menu item can have
// a custom access callback. menu.inc manages its own caching.
$blocks[1]['cache'] = BLOCK_NO_CACHE;
$blocks[2]['info'] = t('Who\'s new');
// Too dynamic to cache.
$blocks[3]['info'] = t('Who\'s online');
$blocks[3]['cache'] = BLOCK_NO_CACHE;
return $blocks;
}
...
}
在前面的例子中,除了一个区块以外,用户模块提供的所有区块都声明了它们不应该被缓存。“新进用户”区块没有声明缓存选项,这意味着如果管理员启用了区块缓存,接着又启用“新进用户”区块,那么该区块将使用默认缓存设置BLOCK_CACHE_PER_ROLE。这意味着为每一个角色存储一个区块的单独的缓存版本。更精确的说,将为角色的每个联合体存储一个单独的缓存版本;通过把当前用户的角色ID连接起来(参看modules/block/block.module中的_block_get_cache_id()),来创建缓存ID。可以用于区块缓存的常量,参看表15-2
表 15-2.区块缓存的常量
BLOCK_NO_CACHE -1 这个区块不被缓存。
BLOCK_CACHE_PER_ROLE 1 每个角色看到一个单独的缓存区块。*
BLOCK_CACHE_PER_USER 2 每个用户看到一个单独的缓存区块。
BLOCK_CACHE_PER_PAGE 4 每个页面都有它自己的缓存区块。
BLOCK_CACHE_GLOBAL 8 为所有用户只缓存一次区块。
* 没有为区块声明缓存设置时的默认值
所有被缓存的区块,都是基于单个主题和单个语言进行缓存的。这意味着,当启用了多个主题时,在用户当前使用的主题下,不会出现为其它主题缓存的区块;当启用了多个语言时,在用户当前使用的语言下,不会出现为其它语言缓存的区块。
通过使用PHP的位逻辑运算符,可以联合使用多个区块常量(类似于菜单常量)。例如,书籍模块的hook_block()提供的“书籍导航”区块,就同时使用了BLOCK_CACHE_PER_ROLE和BLOCK_CACHE_PER_PAGE:
function book_block($op = 'list', $delta = 0, $edit = array()) {
$block = array();
switch ($op) {
case 'list':
$block[0]['info'] = t('Book navigation');
$block[0]['cache'] = BLOCK_CACHE_PER_PAGE | BLOCK_CACHE_PER_ROLE;
return $block;
...
}
不能为BLOCK_CACHE_PER_ROLE和BLOCK_CACHE_PER_USER常量使用位逻辑运算符(|),这是因为这两种缓存模式是相互排斥的。