web/drupal/includes/cache.inc
branchdrupal
changeset 74 0ff3ba646492
equal deleted inserted replaced
73:fcf75e232c5b 74:0ff3ba646492
       
     1 <?php
       
     2 // $Id: cache.inc,v 1.17.2.2 2009/05/26 08:10:33 goba Exp $
       
     3 
       
     4 /**
       
     5  * Return data from the persistent cache. Data may be stored as either plain text or as serialized data.
       
     6  * cache_get will automatically return unserialized objects and arrays.
       
     7  *
       
     8  * @param $cid
       
     9  *   The cache ID of the data to retrieve.
       
    10  * @param $table
       
    11  *   The table $table to store the data in. Valid core values are 'cache_filter',
       
    12  *   'cache_menu', 'cache_page', or 'cache' for the default cache.
       
    13  */
       
    14 function cache_get($cid, $table = 'cache') {
       
    15   global $user;
       
    16 
       
    17   // Garbage collection necessary when enforcing a minimum cache lifetime
       
    18   $cache_flush = variable_get('cache_flush_'. $table, 0);
       
    19   if ($cache_flush && ($cache_flush + variable_get('cache_lifetime', 0) <= time())) {
       
    20     // Reset the variable immediately to prevent a meltdown in heavy load situations.
       
    21     variable_set('cache_flush_'. $table, 0);
       
    22     // Time to flush old cache data
       
    23     db_query("DELETE FROM {". $table ."} WHERE expire != %d AND expire <= %d", CACHE_PERMANENT, $cache_flush);
       
    24   }
       
    25 
       
    26   $cache = db_fetch_object(db_query("SELECT data, created, headers, expire, serialized FROM {". $table ."} WHERE cid = '%s'", $cid));
       
    27   if (isset($cache->data)) {
       
    28     // If the data is permanent or we're not enforcing a minimum cache lifetime
       
    29     // always return the cached data.
       
    30     if ($cache->expire == CACHE_PERMANENT || !variable_get('cache_lifetime', 0)) {
       
    31       $cache->data = db_decode_blob($cache->data);
       
    32       if ($cache->serialized) {
       
    33         $cache->data = unserialize($cache->data);
       
    34       }
       
    35     }
       
    36     // If enforcing a minimum cache lifetime, validate that the data is
       
    37     // currently valid for this user before we return it by making sure the
       
    38     // cache entry was created before the timestamp in the current session's
       
    39     // cache timer. The cache variable is loaded into the $user object by
       
    40     // sess_read() in session.inc.
       
    41     else {
       
    42       if ($user->cache > $cache->created) {
       
    43         // This cache data is too old and thus not valid for us, ignore it.
       
    44         return 0;
       
    45       }
       
    46       else {
       
    47         $cache->data = db_decode_blob($cache->data);
       
    48         if ($cache->serialized) {
       
    49           $cache->data = unserialize($cache->data);
       
    50         }
       
    51       }
       
    52     }
       
    53     return $cache;
       
    54   }
       
    55   return 0;
       
    56 }
       
    57 
       
    58 /**
       
    59  * Store data in the persistent cache.
       
    60  *
       
    61  * The persistent cache is split up into four database
       
    62  * tables. Contributed modules can add additional tables.
       
    63  *
       
    64  * 'cache_page': This table stores generated pages for anonymous
       
    65  * users. This is the only table affected by the page cache setting on
       
    66  * the administrator panel.
       
    67  *
       
    68  * 'cache_menu': Stores the cachable part of the users' menus.
       
    69  *
       
    70  * 'cache_filter': Stores filtered pieces of content. This table is
       
    71  * periodically cleared of stale entries by cron.
       
    72  *
       
    73  * 'cache': Generic cache storage table.
       
    74  *
       
    75  * The reasons for having several tables are as follows:
       
    76  *
       
    77  * - smaller tables allow for faster selects and inserts
       
    78  * - we try to put fast changing cache items and rather static
       
    79  *   ones into different tables. The effect is that only the fast
       
    80  *   changing tables will need a lot of writes to disk. The more
       
    81  *   static tables will also be better cachable with MySQL's query cache
       
    82  *
       
    83  * @param $cid
       
    84  *   The cache ID of the data to store.
       
    85  * @param $data
       
    86  *   The data to store in the cache. Complex data types will be automatically serialized before insertion.
       
    87  *   Strings will be stored as plain text and not serialized.
       
    88  * @param $table
       
    89  *   The table $table to store the data in. Valid core values are 'cache_filter',
       
    90  *   'cache_menu', 'cache_page', or 'cache'.
       
    91  * @param $expire
       
    92  *   One of the following values:
       
    93  *   - CACHE_PERMANENT: Indicates that the item should never be removed unless
       
    94  *     explicitly told to using cache_clear_all() with a cache ID.
       
    95  *   - CACHE_TEMPORARY: Indicates that the item should be removed at the next
       
    96  *     general cache wipe.
       
    97  *   - A Unix timestamp: Indicates that the item should be kept at least until
       
    98  *     the given time, after which it behaves like CACHE_TEMPORARY.
       
    99  * @param $headers
       
   100  *   A string containing HTTP header information for cached pages.
       
   101  */
       
   102 function cache_set($cid, $data, $table = 'cache', $expire = CACHE_PERMANENT, $headers = NULL) {
       
   103   $serialized = 0;
       
   104   if (is_object($data) || is_array($data)) {
       
   105     $data = serialize($data);
       
   106     $serialized = 1;
       
   107   }
       
   108   $created = time();
       
   109   db_query("UPDATE {". $table ."} SET data = %b, created = %d, expire = %d, headers = '%s', serialized = %d WHERE cid = '%s'", $data, $created, $expire, $headers, $serialized, $cid);
       
   110   if (!db_affected_rows()) {
       
   111     @db_query("INSERT INTO {". $table ."} (cid, data, created, expire, headers, serialized) VALUES ('%s', %b, %d, %d, '%s', %d)", $cid, $data, $created, $expire, $headers, $serialized);
       
   112   }
       
   113 }
       
   114 
       
   115 /**
       
   116  *
       
   117  * Expire data from the cache. If called without arguments, expirable
       
   118  * entries will be cleared from the cache_page and cache_block tables.
       
   119  *
       
   120  * @param $cid
       
   121  *   If set, the cache ID to delete. Otherwise, all cache entries that can
       
   122  *   expire are deleted.
       
   123  *
       
   124  * @param $table
       
   125  *   If set, the table $table to delete from. Mandatory
       
   126  *   argument if $cid is set.
       
   127  *
       
   128  * @param $wildcard
       
   129  *   If set to TRUE, the $cid is treated as a substring
       
   130  *   to match rather than a complete ID. The match is a right hand
       
   131  *   match. If '*' is given as $cid, the table $table will be emptied.
       
   132  */
       
   133 function cache_clear_all($cid = NULL, $table = NULL, $wildcard = FALSE) {
       
   134   global $user;
       
   135 
       
   136   if (!isset($cid) && !isset($table)) {
       
   137     // Clear the block cache first, so stale data will
       
   138     // not end up in the page cache.
       
   139     cache_clear_all(NULL, 'cache_block');
       
   140     cache_clear_all(NULL, 'cache_page');
       
   141     return;
       
   142   }
       
   143 
       
   144   if (empty($cid)) {
       
   145     if (variable_get('cache_lifetime', 0)) {
       
   146       // We store the time in the current user's $user->cache variable which
       
   147       // will be saved into the sessions table by sess_write(). We then
       
   148       // simulate that the cache was flushed for this user by not returning
       
   149       // cached data that was cached before the timestamp.
       
   150       $user->cache = time();
       
   151 
       
   152       $cache_flush = variable_get('cache_flush_'. $table, 0);
       
   153       if ($cache_flush == 0) {
       
   154         // This is the first request to clear the cache, start a timer.
       
   155         variable_set('cache_flush_'. $table, time());
       
   156       }
       
   157       else if (time() > ($cache_flush + variable_get('cache_lifetime', 0))) {
       
   158         // Clear the cache for everyone, cache_lifetime seconds have
       
   159         // passed since the first request to clear the cache.
       
   160         db_query("DELETE FROM {". $table ."} WHERE expire != %d AND expire < %d", CACHE_PERMANENT, time());
       
   161         variable_set('cache_flush_'. $table, 0);
       
   162       }
       
   163     }
       
   164     else {
       
   165       // No minimum cache lifetime, flush all temporary cache entries now.
       
   166       db_query("DELETE FROM {". $table ."} WHERE expire != %d AND expire < %d", CACHE_PERMANENT, time());
       
   167     }
       
   168   }
       
   169   else {
       
   170     if ($wildcard) {
       
   171       if ($cid == '*') {
       
   172         db_query("DELETE FROM {". $table ."}");
       
   173       }
       
   174       else {
       
   175         db_query("DELETE FROM {". $table ."} WHERE cid LIKE '%s%%'", $cid);
       
   176       }
       
   177     }
       
   178     else {
       
   179       db_query("DELETE FROM {". $table ."} WHERE cid = '%s'", $cid);
       
   180     }
       
   181   }
       
   182 }
       
   183