Smarty使用Memcache进行缓存

默认的Smarty缓存是使用File进行缓存的。在高并发的时候,压力会在IO方面。为了避免在高并发的时候,IO占用高。我写了一个Smarty的插件,将缓存写入Memcache。曾经想过自己写一个模板的,感觉后期的维护比较麻烦,所以。。。。

  1. <?php
  2. /**
  3.  * Smarty Cache Handler<br>
  4.  * utilizing Memcache extension (http://pecl.php.net/package/memcache)<br>
  5.  *
  6.  * Name:     mmcache_cache_handler<br>
  7.  * Type:     Cache Handler<br>
  8.  * Purpose:  Replacement for the file based cache handling of Smarty. mmcache_cache_handler() is
  9.  *           using Memcache extension to minimize disk usage.
  10.  * File:     memcache_cache_handler.php<br>
  11.  * Date:     May 20, 2009<br>
  12.  *
  13.  * Usage Example<br>
  14.  * <pre>
  15.  * $smarty = new Smarty;
  16.  * $smarty->cache_handler_func = 'mmcache_cache_handler';
  17.  * $smarty->caching = true;
  18.  * $smarty->display('index.tpl');
  19.  * </pre>
  20.  *
  21.  * @author   Kim Chow
  22.  * @version  Beta
  23.  *
  24.  * @param    string   $action         Cache operation to perform ( read | write | clear )
  25.  * @param    mixed    $smarty         Reference to an instance of Smarty
  26.  * @param    string   $cache_content  Reference to cached contents
  27.  * @param    string   $tpl_file       Template file name
  28.  * @param    string   $cache_id       Cache identifier
  29.  * @param    string   $compile_id     Compile identifier
  30.  * @param    integer  $exp_time       Expiration time
  31.  * @return   boolean                  TRUE on success, FALSE otherwise
  32.  *
  33.  * @link     http://pecl.php.net/package/memcache
  34.  *           (pecl memcache homepage)
  35.  * @link     http://smarty.php.net/manual/en/section.template.cache.handler.func.php
  36.  *           (Smarty online manual)
  37.  */
  38. function mmcache_cache_handler($action, &$smarty, &$cache_content, $tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null) {
  39. if (! function_exists ( "memcache_get" )) {
  40. $smarty->trigger_error ( "cache_handler: PHP Extension \"Memcache\" extension (http://pecl.php.net/package/memcache) not installed." );
  41. return false;
  42. }
  43. // Create unique cache id:
  44. // We are using smarty's internal functions here to be as compatible as possible.
  45. $memcache_id = "smarty_memcache_" . $cache_id . "_" . $tpl_file;
  46. $memcache = new memCacheClass ( );
  47. switch ($action) {
  48. case 'read' :
  49. // read cache from shared memory
  50. $cache_content = $memcache->get ( $memcache_id );
  51. if (! is_null ( $cache_content ) && _memcache_hasexpired ( $cache_content )) {
  52. // Cache has been expired so we clear it now by calling ourself with another parameter :)
  53. $cache_content = null;
  54. mmcache_cache_handler ( 'write', $smarty, $cache_content, $tpl_file, $cache_id, $compile_id );
  55. }
  56. $return = true;
  57. break;
  58. case 'write' :
  59. $result = $memcache->set ( $memcache_id, $cache_content, 0, $exp_time );
  60. if (! $result) {
  61. $smarty_obj->_trigger_error_msg ( 'cache_handler: query failed.' );
  62. }
  63. $return = $result;
  64. break;
  65. case 'clear' :
  66. if (empty ( $cache_id )) {
  67. $result = $memcache->delete ( $memcache_id );
  68. }
  69. if (! $result) {
  70. $smarty_obj->_trigger_error_msg ( 'cache_handler: query failed.' );
  71. }
  72. $return = $result;
  73. default :
  74. // error, unknown action
  75. $smarty->trigger_error ( "cache_handler: unknown action \"$action\"" );
  76. $return = false;
  77. break;
  78. }
  79. return $return;
  80. }
  81.  
  82. /**
  83.  * Helper function for mmcache_cache_handler()
  84.  * Checks whether a cached content has been expired by reading the content's header.
  85.  *
  86.  * @access  private
  87.  * @param   string    $cache_content      the cached content
  88.  * @return  boolean                       TRUE if cache has been expired, FALSE otherwise
  89.  *
  90.  * @see     mmcache_cache_handler()
  91.  */
  92. function _memcache_hasexpired(&$cache_content) {
  93. $split = explode ( "\n", $cache_content, 2 );
  94. $attributes = unserialize ( $split [0] );
  95. if ($attributes ['expires'] > 0 && time () > $attributes ['expires'])
  96. return true;
  97. else
  98. return false;
  99. }
  100.  
  101. ?>

上面的例子只是为了做个说明罢了,建议将Memcache进行封装,便于管理。

2009-5-21 修改:
1、加入缓存过期时间

RSS feed for comments on this post · TrackBack URL

发表评论

You must be logged in to post a comment.