Namespaces

  • Latte
    • Loaders
    • Macros
    • Runtime
  • Nette
    • Application
      • Responses
      • Routers
      • UI
    • Bridges
      • ApplicationLatte
      • ApplicationTracy
      • CacheLatte
      • DatabaseDI
      • DatabaseTracy
      • DITracy
      • FormsLatte
      • Framework
      • HttpTracy
      • SecurityTracy
    • Caching
      • Storages
    • ComponentModel
    • Database
      • Drivers
      • Reflection
      • Table
    • DI
      • Config
        • Adapters
      • Extensions
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Latte
    • Loaders
    • Localization
    • Mail
    • Neon
    • PhpGenerator
    • Reflection
    • Security
    • Templating
    • Utils
  • NetteModule
  • none
  • Tracy

Classes

  • DevNullStorage
  • FileJournal
  • FileStorage
  • MemcachedStorage
  • MemoryStorage
  • PhpFileStorage
  • SQLiteStorage

Interfaces

  • IJournal
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  • Other releases
  • Nette homepage
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (https://nette.org)
  5:  * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
  6:  */
  7: 
  8: namespace Nette\Caching\Storages;
  9: 
 10: use Nette;
 11: use Nette\Caching\Cache;
 12: 
 13: 
 14: /**
 15:  * Memcached storage.
 16:  *
 17:  * @author     David Grudl
 18:  */
 19: class MemcachedStorage extends Nette\Object implements Nette\Caching\IStorage
 20: {
 21:     /** @internal cache structure */
 22:     const META_CALLBACKS = 'callbacks',
 23:         META_DATA = 'data',
 24:         META_DELTA = 'delta';
 25: 
 26:     /** @var \Memcache */
 27:     private $memcache;
 28: 
 29:     /** @var string */
 30:     private $prefix;
 31: 
 32:     /** @var IJournal */
 33:     private $journal;
 34: 
 35: 
 36:     /**
 37:      * Checks if Memcached extension is available.
 38:      * @return bool
 39:      */
 40:     public static function isAvailable()
 41:     {
 42:         return extension_loaded('memcache');
 43:     }
 44: 
 45: 
 46:     public function __construct($host = 'localhost', $port = 11211, $prefix = '', IJournal $journal = NULL)
 47:     {
 48:         if (!static::isAvailable()) {
 49:             throw new Nette\NotSupportedException("PHP extension 'memcache' is not loaded.");
 50:         }
 51: 
 52:         $this->prefix = $prefix;
 53:         $this->journal = $journal;
 54:         $this->memcache = new \Memcache;
 55:         if ($host) {
 56:             $this->addServer($host, $port);
 57:         }
 58:     }
 59: 
 60: 
 61:     public function addServer($host = 'localhost', $port = 11211, $timeout = 1)
 62:     {
 63:         if ($this->memcache->addServer($host, $port, TRUE, 1, $timeout) === FALSE) {
 64:             $error = error_get_last();
 65:             throw new Nette\InvalidStateException("Memcache::addServer(): $error[message].");
 66:         }
 67:     }
 68: 
 69: 
 70:     /**
 71:      * @return \Memcache
 72:      */
 73:     public function getConnection()
 74:     {
 75:         return $this->memcache;
 76:     }
 77: 
 78: 
 79:     /**
 80:      * Read from cache.
 81:      * @param  string key
 82:      * @return mixed|NULL
 83:      */
 84:     public function read($key)
 85:     {
 86:         $key = urlencode($this->prefix . $key);
 87:         $meta = $this->memcache->get($key);
 88:         if (!$meta) {
 89:             return NULL;
 90:         }
 91: 
 92:         // meta structure:
 93:         // array(
 94:         //     data => stored data
 95:         //     delta => relative (sliding) expiration
 96:         //     callbacks => array of callbacks (function, args)
 97:         // )
 98: 
 99:         // verify dependencies
100:         if (!empty($meta[self::META_CALLBACKS]) && !Cache::checkCallbacks($meta[self::META_CALLBACKS])) {
101:             $this->memcache->delete($key, 0);
102:             return NULL;
103:         }
104: 
105:         if (!empty($meta[self::META_DELTA])) {
106:             $this->memcache->replace($key, $meta, 0, $meta[self::META_DELTA] + time());
107:         }
108: 
109:         return $meta[self::META_DATA];
110:     }
111: 
112: 
113:     /**
114:      * Prevents item reading and writing. Lock is released by write() or remove().
115:      * @param  string key
116:      * @return void
117:      */
118:     public function lock($key)
119:     {
120:     }
121: 
122: 
123:     /**
124:      * Writes item into the cache.
125:      * @param  string key
126:      * @param  mixed  data
127:      * @param  array  dependencies
128:      * @return void
129:      */
130:     public function write($key, $data, array $dp)
131:     {
132:         if (isset($dp[Cache::ITEMS])) {
133:             throw new Nette\NotSupportedException('Dependent items are not supported by MemcachedStorage.');
134:         }
135: 
136:         $key = urlencode($this->prefix . $key);
137:         $meta = array(
138:             self::META_DATA => $data,
139:         );
140: 
141:         $expire = 0;
142:         if (isset($dp[Cache::EXPIRATION])) {
143:             $expire = (int) $dp[Cache::EXPIRATION];
144:             if (!empty($dp[Cache::SLIDING])) {
145:                 $meta[self::META_DELTA] = $expire; // sliding time
146:             }
147:         }
148: 
149:         if (isset($dp[Cache::CALLBACKS])) {
150:             $meta[self::META_CALLBACKS] = $dp[Cache::CALLBACKS];
151:         }
152: 
153:         if (isset($dp[Cache::TAGS]) || isset($dp[Cache::PRIORITY])) {
154:             if (!$this->journal) {
155:                 throw new Nette\InvalidStateException('CacheJournal has not been provided.');
156:             }
157:             $this->journal->write($key, $dp);
158:         }
159: 
160:         $this->memcache->set($key, $meta, 0, $expire);
161:     }
162: 
163: 
164:     /**
165:      * Removes item from the cache.
166:      * @param  string key
167:      * @return void
168:      */
169:     public function remove($key)
170:     {
171:         $this->memcache->delete(urlencode($this->prefix . $key), 0);
172:     }
173: 
174: 
175:     /**
176:      * Removes items from the cache by conditions & garbage collector.
177:      * @param  array  conditions
178:      * @return void
179:      */
180:     public function clean(array $conditions)
181:     {
182:         if (!empty($conditions[Cache::ALL])) {
183:             $this->memcache->flush();
184: 
185:         } elseif ($this->journal) {
186:             foreach ($this->journal->clean($conditions) as $entry) {
187:                 $this->memcache->delete($entry, 0);
188:             }
189:         }
190:     }
191: 
192: }
193: 
Nette 2.2 API documentation generated by ApiGen 2.8.0