4
* PHPExcel_CachedObjectStorage_APC
6
* Copyright (c) 2006 - 2015 PHPExcel
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.
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.
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
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##
28
class PHPExcel_CachedObjectStorage_APC extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache
31
* Prefix used to uniquely identify cache data for this worksheet
36
private $cachePrefix = null;
44
private $cacheTime = 600;
47
* Store cell data in cache for the current cell object if it's "dirty",
48
* and the 'nullify' the current cell object
52
* @throws PHPExcel_Exception
54
protected function storeData()
56
if ($this->currentCellIsDirty && !empty($this->currentObjectID)) {
57
$this->currentObject->detach();
60
$this->cachePrefix . $this->currentObjectID . '.cache',
61
serialize($this->currentObject),
65
throw new PHPExcel_Exception('Failed to store cell ' . $this->currentObjectID . ' in APC');
67
$this->currentCellIsDirty = false;
69
$this->currentObjectID = $this->currentObject = null;
73
* Add or Update a cell in cache identified by coordinate address
76
* @param string $pCoord Coordinate address of the cell to update
77
* @param PHPExcel_Cell $cell Cell to update
78
* @return PHPExcel_Cell
79
* @throws PHPExcel_Exception
81
public function addCacheData($pCoord, PHPExcel_Cell $cell)
83
if (($pCoord !== $this->currentObjectID) && ($this->currentObjectID !== null)) {
86
$this->cellCache[$pCoord] = true;
88
$this->currentObjectID = $pCoord;
89
$this->currentObject = $cell;
90
$this->currentCellIsDirty = true;
96
* Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell?
99
* @param string $pCoord Coordinate address of the cell to check
100
* @throws PHPExcel_Exception
103
public function isDataSet($pCoord)
105
// Check if the requested entry is the current object, or exists in the cache
106
if (parent::isDataSet($pCoord)) {
107
if ($this->currentObjectID == $pCoord) {
110
// Check if the requested entry still exists in apc
111
$success = apc_fetch($this->cachePrefix.$pCoord.'.cache');
112
if ($success === false) {
113
// Entry no longer exists in APC, so clear it from the cache array
114
parent::deleteCacheData($pCoord);
115
throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in APC cache');
123
* Get cell at a specific coordinate
126
* @param string $pCoord Coordinate of the cell
127
* @throws PHPExcel_Exception
128
* @return PHPExcel_Cell Cell that was found, or null if not found
130
public function getCacheData($pCoord)
132
if ($pCoord === $this->currentObjectID) {
133
return $this->currentObject;
137
// Check if the entry that has been requested actually exists
138
if (parent::isDataSet($pCoord)) {
139
$obj = apc_fetch($this->cachePrefix . $pCoord . '.cache');
140
if ($obj === false) {
141
// Entry no longer exists in APC, so clear it from the cache array
142
parent::deleteCacheData($pCoord);
143
throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in APC cache');
146
// Return null if requested entry doesn't exist in cache
150
// Set current entry to the requested entry
151
$this->currentObjectID = $pCoord;
152
$this->currentObject = unserialize($obj);
153
// Re-attach this as the cell's parent
154
$this->currentObject->attach($this);
156
// Return requested entry
157
return $this->currentObject;
161
* Get a list of all cell addresses currently held in cache
165
public function getCellList()
167
if ($this->currentObjectID !== null) {
171
return parent::getCellList();
175
* Delete a cell in cache identified by coordinate address
178
* @param string $pCoord Coordinate address of the cell to delete
179
* @throws PHPExcel_Exception
181
public function deleteCacheData($pCoord)
183
// Delete the entry from APC
184
apc_delete($this->cachePrefix.$pCoord.'.cache');
186
// Delete the entry from our cell address array
187
parent::deleteCacheData($pCoord);
191
* Clone the cell collection
194
* @param PHPExcel_Worksheet $parent The new worksheet
195
* @throws PHPExcel_Exception
198
public function copyCellCollection(PHPExcel_Worksheet $parent)
200
parent::copyCellCollection($parent);
201
// Get a new id for the new file name
202
$baseUnique = $this->getUniqueID();
203
$newCachePrefix = substr(md5($baseUnique), 0, 8) . '.';
204
$cacheList = $this->getCellList();
205
foreach ($cacheList as $cellID) {
206
if ($cellID != $this->currentObjectID) {
207
$obj = apc_fetch($this->cachePrefix . $cellID . '.cache');
208
if ($obj === false) {
209
// Entry no longer exists in APC, so clear it from the cache array
210
parent::deleteCacheData($cellID);
211
throw new PHPExcel_Exception('Cell entry ' . $cellID . ' no longer exists in APC');
213
if (!apc_store($newCachePrefix . $cellID . '.cache', $obj, $this->cacheTime)) {
215
throw new PHPExcel_Exception('Failed to store cell ' . $cellID . ' in APC');
219
$this->cachePrefix = $newCachePrefix;
223
* Clear the cell collection and disconnect from our parent
227
public function unsetWorksheetCells()
229
if ($this->currentObject !== null) {
230
$this->currentObject->detach();
231
$this->currentObject = $this->currentObjectID = null;
234
// Flush the APC cache
237
$this->cellCache = array();
239
// detach ourself from the worksheet, so that it can then delete this object successfully
240
$this->parent = null;
244
* Initialise this new cell collection
246
* @param PHPExcel_Worksheet $parent The worksheet for this cell collection
247
* @param array of mixed $arguments Additional initialisation arguments
249
public function __construct(PHPExcel_Worksheet $parent, $arguments)
251
$cacheTime = (isset($arguments['cacheTime'])) ? $arguments['cacheTime'] : 600;
253
if ($this->cachePrefix === null) {
254
$baseUnique = $this->getUniqueID();
255
$this->cachePrefix = substr(md5($baseUnique), 0, 8) . '.';
256
$this->cacheTime = $cacheTime;
258
parent::__construct($parent);
263
* Destroy this cell collection
265
public function __destruct()
267
$cacheList = $this->getCellList();
268
foreach ($cacheList as $cellID) {
269
apc_delete($this->cachePrefix . $cellID . '.cache');
274
* Identify whether the caching method is currently available
275
* Some methods are dependent on the availability of certain extensions being enabled in the PHP build
279
public static function cacheMethodIsAvailable()
281
if (!function_exists('apc_store')) {
284
if (apc_sma_info() === false) {