[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * PHPExcel_CachedObjectStorage_Memcache 5 * 6 * Copyright (c) 2006 - 2015 PHPExcel 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 * 22 * @category PHPExcel 23 * @package PHPExcel_CachedObjectStorage 24 * @copyright Copyright (c) 2006 - 2015 PHPExcel (http://www.codeplex.com/PHPExcel) 25 * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL 26 * @version ##VERSION##, ##DATE## 27 */ 28 class PHPExcel_CachedObjectStorage_Memcache extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache 29 { 30 /** 31 * Prefix used to uniquely identify cache data for this worksheet 32 * 33 * @var string 34 */ 35 private $cachePrefix = null; 36 37 /** 38 * Cache timeout 39 * 40 * @var integer 41 */ 42 private $cacheTime = 600; 43 44 /** 45 * Memcache interface 46 * 47 * @var resource 48 */ 49 private $memcache = null; 50 51 52 /** 53 * Store cell data in cache for the current cell object if it's "dirty", 54 * and the 'nullify' the current cell object 55 * 56 * @return void 57 * @throws PHPExcel_Exception 58 */ 59 protected function storeData() 60 { 61 if ($this->currentCellIsDirty && !empty($this->currentObjectID)) { 62 $this->currentObject->detach(); 63 64 $obj = serialize($this->currentObject); 65 if (!$this->memcache->replace($this->cachePrefix . $this->currentObjectID . '.cache', $obj, null, $this->cacheTime)) { 66 if (!$this->memcache->add($this->cachePrefix . $this->currentObjectID . '.cache', $obj, null, $this->cacheTime)) { 67 $this->__destruct(); 68 throw new PHPExcel_Exception("Failed to store cell {$this->currentObjectID} in MemCache"); 69 } 70 } 71 $this->currentCellIsDirty = false; 72 } 73 $this->currentObjectID = $this->currentObject = null; 74 } // function _storeData() 75 76 77 /** 78 * Add or Update a cell in cache identified by coordinate address 79 * 80 * @param string $pCoord Coordinate address of the cell to update 81 * @param PHPExcel_Cell $cell Cell to update 82 * @return PHPExcel_Cell 83 * @throws PHPExcel_Exception 84 */ 85 public function addCacheData($pCoord, PHPExcel_Cell $cell) 86 { 87 if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) { 88 $this->storeData(); 89 } 90 $this->cellCache[$pCoord] = true; 91 92 $this->currentObjectID = $pCoord; 93 $this->currentObject = $cell; 94 $this->currentCellIsDirty = true; 95 96 return $cell; 97 } // function addCacheData() 98 99 100 /** 101 * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell? 102 * 103 * @param string $pCoord Coordinate address of the cell to check 104 * @return boolean 105 * @return boolean 106 */ 107 public function isDataSet($pCoord) 108 { 109 // Check if the requested entry is the current object, or exists in the cache 110 if (parent::isDataSet($pCoord)) { 111 if ($this->currentObjectID == $pCoord) { 112 return true; 113 } 114 // Check if the requested entry still exists in Memcache 115 $success = $this->memcache->get($this->cachePrefix.$pCoord.'.cache'); 116 if ($success === false) { 117 // Entry no longer exists in Memcache, so clear it from the cache array 118 parent::deleteCacheData($pCoord); 119 throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in MemCache'); 120 } 121 return true; 122 } 123 return false; 124 } 125 126 127 /** 128 * Get cell at a specific coordinate 129 * 130 * @param string $pCoord Coordinate of the cell 131 * @throws PHPExcel_Exception 132 * @return PHPExcel_Cell Cell that was found, or null if not found 133 */ 134 public function getCacheData($pCoord) 135 { 136 if ($pCoord === $this->currentObjectID) { 137 return $this->currentObject; 138 } 139 $this->storeData(); 140 141 // Check if the entry that has been requested actually exists 142 if (parent::isDataSet($pCoord)) { 143 $obj = $this->memcache->get($this->cachePrefix . $pCoord . '.cache'); 144 if ($obj === false) { 145 // Entry no longer exists in Memcache, so clear it from the cache array 146 parent::deleteCacheData($pCoord); 147 throw new PHPExcel_Exception("Cell entry {$pCoord} no longer exists in MemCache"); 148 } 149 } else { 150 // Return null if requested entry doesn't exist in cache 151 return null; 152 } 153 154 // Set current entry to the requested entry 155 $this->currentObjectID = $pCoord; 156 $this->currentObject = unserialize($obj); 157 // Re-attach this as the cell's parent 158 $this->currentObject->attach($this); 159 160 // Return requested entry 161 return $this->currentObject; 162 } 163 164 /** 165 * Get a list of all cell addresses currently held in cache 166 * 167 * @return string[] 168 */ 169 public function getCellList() 170 { 171 if ($this->currentObjectID !== null) { 172 $this->storeData(); 173 } 174 175 return parent::getCellList(); 176 } 177 178 /** 179 * Delete a cell in cache identified by coordinate address 180 * 181 * @param string $pCoord Coordinate address of the cell to delete 182 * @throws PHPExcel_Exception 183 */ 184 public function deleteCacheData($pCoord) 185 { 186 // Delete the entry from Memcache 187 $this->memcache->delete($this->cachePrefix . $pCoord . '.cache'); 188 189 // Delete the entry from our cell address array 190 parent::deleteCacheData($pCoord); 191 } 192 193 /** 194 * Clone the cell collection 195 * 196 * @param PHPExcel_Worksheet $parent The new worksheet 197 * @return void 198 */ 199 public function copyCellCollection(PHPExcel_Worksheet $parent) 200 { 201 parent::copyCellCollection($parent); 202 // Get a new id for the new file name 203 $baseUnique = $this->getUniqueID(); 204 $newCachePrefix = substr(md5($baseUnique), 0, 8) . '.'; 205 $cacheList = $this->getCellList(); 206 foreach ($cacheList as $cellID) { 207 if ($cellID != $this->currentObjectID) { 208 $obj = $this->memcache->get($this->cachePrefix.$cellID.'.cache'); 209 if ($obj === false) { 210 // Entry no longer exists in Memcache, so clear it from the cache array 211 parent::deleteCacheData($cellID); 212 throw new PHPExcel_Exception("Cell entry {$cellID} no longer exists in MemCache"); 213 } 214 if (!$this->memcache->add($newCachePrefix . $cellID . '.cache', $obj, null, $this->cacheTime)) { 215 $this->__destruct(); 216 throw new PHPExcel_Exception("Failed to store cell {$cellID} in MemCache"); 217 } 218 } 219 } 220 $this->cachePrefix = $newCachePrefix; 221 } 222 223 /** 224 * Clear the cell collection and disconnect from our parent 225 * 226 * @return void 227 */ 228 public function unsetWorksheetCells() 229 { 230 if (!is_null($this->currentObject)) { 231 $this->currentObject->detach(); 232 $this->currentObject = $this->currentObjectID = null; 233 } 234 235 // Flush the Memcache cache 236 $this->__destruct(); 237 238 $this->cellCache = array(); 239 240 // detach ourself from the worksheet, so that it can then delete this object successfully 241 $this->parent = null; 242 } 243 244 /** 245 * Initialise this new cell collection 246 * 247 * @param PHPExcel_Worksheet $parent The worksheet for this cell collection 248 * @param array of mixed $arguments Additional initialisation arguments 249 */ 250 public function __construct(PHPExcel_Worksheet $parent, $arguments) 251 { 252 $memcacheServer = (isset($arguments['memcacheServer'])) ? $arguments['memcacheServer'] : 'localhost'; 253 $memcachePort = (isset($arguments['memcachePort'])) ? $arguments['memcachePort'] : 11211; 254 $cacheTime = (isset($arguments['cacheTime'])) ? $arguments['cacheTime'] : 600; 255 256 if (is_null($this->cachePrefix)) { 257 $baseUnique = $this->getUniqueID(); 258 $this->cachePrefix = substr(md5($baseUnique), 0, 8) . '.'; 259 260 // Set a new Memcache object and connect to the Memcache server 261 $this->memcache = new Memcache(); 262 if (!$this->memcache->addServer($memcacheServer, $memcachePort, false, 50, 5, 5, true, array($this, 'failureCallback'))) { 263 throw new PHPExcel_Exception("Could not connect to MemCache server at {$memcacheServer}:{$memcachePort}"); 264 } 265 $this->cacheTime = $cacheTime; 266 267 parent::__construct($parent); 268 } 269 } 270 271 /** 272 * Memcache error handler 273 * 274 * @param string $host Memcache server 275 * @param integer $port Memcache port 276 * @throws PHPExcel_Exception 277 */ 278 public function failureCallback($host, $port) 279 { 280 throw new PHPExcel_Exception("memcache {$host}:{$port} failed"); 281 } 282 283 /** 284 * Destroy this cell collection 285 */ 286 public function __destruct() 287 { 288 $cacheList = $this->getCellList(); 289 foreach ($cacheList as $cellID) { 290 $this->memcache->delete($this->cachePrefix.$cellID . '.cache'); 291 } 292 } 293 294 /** 295 * Identify whether the caching method is currently available 296 * Some methods are dependent on the availability of certain extensions being enabled in the PHP build 297 * 298 * @return boolean 299 */ 300 public static function cacheMethodIsAvailable() 301 { 302 if (!function_exists('memcache_add')) { 303 return false; 304 } 305 306 return true; 307 } 308 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |