Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Apress.Pro.Drupal.7.Development.3rd.Edition.Dec.2010.pdf
Скачиваний:
73
Добавлен:
14.03.2016
Размер:
12.64 Mб
Скачать

CHAPTER 16 CACHING

To begin, a request causes the web server to execute index.php. A line of PHP code inside index.php is to include includes/bootstrap.inc, which contains the core functions for bootstrap loading. Next, index.php makes a call to drupal_bootstrap().

drupal_bootstrap() is in charge of executing each bootstrap phase. For caching, we need to concern ourselves only with the DRUPAL_BOOTSTRAP_PAGE_CACHE bootstrap phase. This phase attempts to load the page from the cache_page bin.

Static Page Caching

By default, Drupal sends a "Vary: Cookie" HTTP header for anonymous page views. This tells a HTTP proxy that it may return a page from its local cache without contacting the web server, if the user sends the same Cookie header as the user who originally requested the cached page. Without "Vary: Cookie", authenticated users would also be served the anonymous page from the cache. If the site has mostly anonymous users except a few known editors/administrators, the Vary header can be omitted. This allows for better caching in HTTP proxies (including reverse proxies), i.e., even if clients send different cookies, they still get content served from the cache if aggressive caching is enabled and the minimum cache time is non-zero. However, authenticated users should access the site directly (i.e., not use an HTTP proxy, and bypass the reverse proxy if one is used) in order to avoid getting cached pages from the proxy.

To enable the ability, edit your settings.php file and uncomment the following line:

#$conf['omit_vary_cookie'] = TRUE;

Blocks

Depending on their content, blocks may be cacheable. Drupal’s block caching can be enabled or disabled using the administrative interface at Configuration -> Performance (see Figure 16-1).

Block caching is accomplished when a module that provides a block declares the cacheability of that block when responding to the list operation of hook_block_info(). For example, here is part of the hook_block_info() implementation of modules/user/user.module:

/**

* Implements hook_block_info(). */

function user_block_info() { global $user;

$blocks['login']['info'] = t('User login'); // Not worth caching. $blocks['login']['cache'] = DRUPAL_NO_CACHE;

$blocks['new']['info'] = t('Who\'s new');

// Too dynamic to cache. $blocks['online']['info'] = t('Who\'s online'); $blocks['online']['cache'] = DRUPAL_NO_CACHE; return $blocks;

}

372

CHAPTER 16 CACHING

In the preceding example, all the blocks provided by the user module declare that they should not be cached, with one exception. The “Who’s new” block does not declare a cache preference, which means that if the administrator has enabled block caching and then enables the “Who’s new” block, it will receive the default caching setting of DRUPAL_CACHE_PER_ROLE. That means that a separate cached version of the block will be stored for each role. To be more precise, a separate cached version will be stored for each combination of roles; the cache ID is created by concatenating the current user’s role IDs (see _block_get_cache_id() in modules/block/block.module). The possible constants for caching are shown in Table 16-2.

Table 16-2. Possible Constants for Caching

Constant

Value

Meaning

 

 

 

DRUPAL_CACHE_CUSTOM

-2

The block is handling its own cache.

DRUPAL_NO_CACHE

-1

Do not cache this block.

DRUPAL_CACHE_PER_ROLE

 

Each1 role sees a separate cached block.*

DRUPAL_CACHE_PER_USER

 

Each2 user sees a separate cached block.

DRUPAL_CACHE_PER_PAGE

 

Each4 page has its own cached block.

DRUPAL_CACHE_GLOBAL

8

Blocks are cached once for all users.

* Default for blocks that do not declare a cache setting

All blocks that are cached are cached on a per-theme and per-language basis. This prevents users from seeing a block that is themed by a theme other than the one the user is viewing when multiple themes are enabled, and it prevents blocks from showing up in the wrong language when multiple languages are enabled.

Note Blocks are never cached for the superuser (user 1).

The block constants (like menu constants) can be used together using PHP bitwise operators. For example, the “Book navigation” block provided by the book module’s implementation of hook_block_info() uses both DRUPAL_CACHE_PER_ROLE and DRUPAL_CACHE_PER_PAGE:

373

CHAPTER 16 CACHING

/**

* Implements hook_block_info(). */

function book_block_info() { $block = array();

$block['navigation']['info'] = t('Book navigation'); $block['navigation']['cache'] = DRUPAL_CACHE_PER_PAGE | DRUPAL_CACHE_PER_ROLE;

return $block;

}

The DRUPAL_CACHE_PER_ROLE and DRUPAL_CACHE_PER_USER constants should not be combined with the bitwise OR operator (|), as the two caching modes are mutually exclusive.

Using the Cache API

Module developers looking to take advantage of the cache API have two functions they need to know: cache_set() and cache_get().

Caching Data with cache_set()

cache_set() is used for writing data to the cache. The function signature follows:

cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT)

And the function parameters are as follows:

$cid: A unique cache ID string that acts as a key to the data. Colons are used to delimit the hierarchy of possibilities.

$bin: The name of the cache bin to store the data in. Valid core values are

'cache_block', 'cache_bootstrap', 'cache_field', 'cache_filter', 'cache_form', 'cache_menu', 'cache_page', 'cache_update', or 'cache' for the default cache.

$data: The data to store in the cache. PHP objects and arrays will be automatically serialized.

$expire: The length of time for which the cached data is valid. Possible values are CACHE_PERMANENT, CACHE_TEMPORARY, or a Unix timestamp. If a Unix timestamp is given, the data will be treated as if it were marked CACHE_TEMPORARY after the current time exceeds the Unix timestamp.

A common iteration pattern for cache_set() can be seen in modules/filter/filter.module:

// Store in cache with a minimum expiration time of 1 day. if ($cache) {

cache_set($cid, $text, 'cache_filter', REQUEST_TIME + (60 * 60 * 24));

}

374

CHAPTER 16 CACHING

Retrieving Cached Data with cache_get() and cache_get_multiple()

cache_get() is for retrieving the cached data. The function signature follows:

cache_get($cid, $bin = 'cache')

And the function parameters are as follows:

$cid: This is the cache ID of the data to retrieve.

$bin: This is the name of the cache bin to store the data in. Valid core values are

'cache_block', 'cache_bootstrap', 'cache_field', 'cache_filter', 'cache_form', 'cache_menu', 'cache_page', 'cache_update', or 'cache' for the default cache.

A common pattern for cache_get() can be seen in modules/filter/filter.module.

// Check for a cached version of this piece of text. if ($cached = cache_get($cid, 'cache_filter')) {

return $cached->data;

}

To return data from cache for a given array of cache IDs, use the cache_get_multiple() function. The function signature follows. The only difference from cache_get is you are passing an array of cids.

cache_get_multiple(array &$cids, $bin = 'cache)

Checking to See If Cache Is Empty with cache_is_empty()

There may be instances where you want to know whether a cache bin is empty. You can use the cache_is_empty function to check whether a specific bin has cached data in it. The function returns TRUE if the cache bin is empty. The function signature is as follows:

cache_is_empty($bin)

And the function parameters are

$bin: This is the name of the cache bin to store the data in. Valid core values are

'cache_block', 'cache_bootstrap', 'cache_field', 'cache_filter', 'cache_form', 'cache_menu', 'cache_page', 'cache_update', or 'cache' for the default cache.

Clearing Cache with cache_clear_all()

If your module knows best when its data becomes stale, it should take responsibility for clearing caches at an appropriate time. Two guiding principles should be applied to cache clearing:

Clear the most specific cache possible. Do not broadly wipe all Drupal’s caches just because a bit of module-specific data has changed! It’s the equivalent of ripping out and replacing all the carpeting in the house because the kitchen floor needs sweeping.

375

CHAPTER 16 CACHING

Use cached data as long as you can. Although the point of caching is to increase responsiveness by decreasing the amount of work that needs to be done, there is significant work involved in clearing cached data, especially if there is a lot of it.

The following subsections describe some ways of clearing cached data.

Using the $reset Parameter

Many Drupal functions that do internal caching with static variables have an optional reset that clears its internal cache. For example, here’s our old friend node_load().

node_load($nid = NULL, $vid = NULL, $reset = FALSE)

The third parameter in the function call is whether to reset the node_load_multiple cache.

Using cache_clear_all()

The main function for clearing cached data is cache_clear_all() in includes/cache.inc. The function signature is as follows:

function cache_clear_all($cid = NULL, $bin = NULL, $wildcard = FALSE) {...}

The $cid and $bin parameters have the same meaning as they do for cache_set() and cache_get(). The $wildcard parameter is used to indicate that the $cid being passed should be treated as a substring with any right-hand matches being cleared. Some examples follow.

Clear the specific entry foo:bar from the cache table:

$cid = 'foo:bar'; cache_clear_all($cid, 'cache');

Clear any expirable entry in the cache table that was set by the foo module (and thus has a $cid that begins with the foo: prefix):

$cid = 'foo:'; // Will match cache keys foo:bar, foo:baz, etc. cache_clear_all($cid, 'cache', TRUE);

The actual database query that is run in the preceding case is

db_delete($this->bin)

->condition('cid', db_like($cid) . '%', 'LIKE') ->execute();

If the foo module keeps its data in its own cache table named cache_foo, that table needs to be specified so cache_clear_all() knows which to clear:

$cid = 'foo:bar'; cache_clear_all($cid, 'cache_foo');

376

CHAPTER 16 CACHING

If you want to completely empty a cache table, pass * as the $cid and set the $wildcard parameter to TRUE. This example clears the entire cache_foo table:

cache_clear_all('*', 'cache_foo', TRUE);

Clear any expirable entries from the page and block caches (i.e., the cache_page and cache_block tables):

cache_clear_all();

Using hook_flush_caches()

Drupal has a central function that flushes all the caches, including the JavaScript and CSS caches. Here is the drupal_flush_all_caches() function from includes/common.inc:

/**

*Flush all cached data on the site.

*Empties cache tables, rebuilds the menu cache and theme registries, and

*invokes a hook so that other modules' cache data can be cleared as well.

*/

function drupal_flush_all_caches() {

// Change query-strings on css/js files to enforce reload for all users. _drupal_flush_css_js();

registry_rebuild(); drupal_clear_css_cache(); drupal_clear_js_cache();

//Rebuild the theme data. Note that the module data is rebuilt above, as

//part of registry_rebuild().

system_rebuild_theme_data(); drupal_theme_rebuild();

menu_rebuild(); node_types_rebuild();

//Don't clear cache_form - in-progress form submissions may break.

//Ordered so clearing the page cache will always be the last action.

$core = array('cache', 'cache_filter', 'cache_bootstrap', 'cache_page'); $cache_tables = array_merge(module_invoke_all('flush_caches'), $core); foreach ($cache_tables as $table) {

cache_clear_all('*', $table, TRUE);

}

}

If you are using your own cache tables, the hook_flush_caches() function gives your module a chance to clear its caches when the “Clear cached data” button is clicked on the Configuration -> Performance page. An implementation of hook_flush_caches() is simple to write; your module should simply return the names of any cache bins that should be flushed. Here’s an example from the update status module:

377

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]