Apache Zeta Components Manual :: File Source for apc_array.php
Source for file apc_array.php
Documentation is available at apc_array.php
* File containing the ezcCacheStorageFileApcArray class.
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* @version //autogentag//
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* This class is a replacement for the {@link ezcCacheStorageFileArray} class. Tries
* to serve data from a local APC cache if possible.
* Options for this class are defined in {@link ezcCacheStorageFileApcArrayOptions}.
* @apichange This class might be removed in future versions. Please use
* {@link ezcCacheStack} to achieve the desired behaior.
* @version //autogentag//
* Creates a new cache storage in the given location. The location in case
* of this storage class must a valid file system directory.
* Options can contain the 'ttl' (Time-To-Live). This is per default set
* to 1 day. The option 'permissions' can be used to define the file
* permissions of created cache items.
* For details about the options see {@link ezcCacheStorageFileApcArrayOptions}.
* @throws ezcBasePropertyNotFoundException
* If you tried to set a non-existent option value.
* @param string $location Path to the cache location. Must be a valid path
* @param array(string=>string) $options Options for the cache storage
public function __construct( $location, array $options =
array() )
// Overwrite parent set options with new ezcCacheStorageFileApcArrayOptions
* Fetches the data from the cache.
* @param string $filename The ID/filename from where to fetch the object
* @param bool $useApc Use APC or the file system
* @return mixed The fetched data or false on failure
protected function fetchData( $filename, $useApc =
false )
$data =
$this->backend->fetch( $filename );
return ( is_object( $data ) ) ?
$data->data :
false;
return ( include $filename );
* Fetches the object from the cache.
* @param string $filename The ID/filename from where to fetch the data
* @return mixed The fetched object or false on failure
$data =
$this->backend->fetch( $filename );
return ( is_object( $data ) ) ?
$data :
false;
* Wraps the data in order to be stored in APC ($useApc = true) or on the
* file system ($useApc = false).
* @throws ezcCacheInvalidDataException
* If the data submitted can not be handled by this storage (object,
* @param mixed $data Simple type or array
* @param bool $useApc Use APC or not
* @return mixed Prepared data
protected function prepareData( $data, $useApc =
false )
return "<?php\nreturn " .
var_export( $data, true ) .
";\n?>\n";
* Stores data to the cache storage.
* @throws ezcBaseFilePermissionException
* If the directory to store the cache file could not be created.
* This exception means most likely that your cache directory
* has been corrupted by external influences (file permission
* @throws ezcBaseFileIoException
* If an error occured while writing the data to the cache. If this
* exception occurs, a serious error occured and your storage might
* be corruped (e.g. broken network connection, file system broken,
* @throws ezcCacheInvalidDataException
* If the data submitted can not be handled by the implementation
* of {@link ezcCacheStorageFile}. Most implementations can not
* handle objects and resources.
* @throws ezcCacheApcException
* If the data could not be stored in APC.
* @param string $id Unique identifier
* @param mixed $data The data to store
* @param array(string=>string) $attributes Attributes describing the cached data
* @return string The ID string of the newly cached data
public function store( $id, $data, $attributes =
array() )
// Generates the identifier
// Purges the Registry Cache
if ( isset
( $this->registry[$filename] ) )
// Deletes the files if it already exists on the filesystem
if ( unlink( $filename ) ===
false )
// Deletes the data from APC if it already exists
$this->backend->delete( $filename );
// Prepares the data for filesystem storage
// Tries to create the directory on the filesystem
&&
!mkdir( $dirname, 0777, true ) )
// Tries to write the file the filesystem
// Tries to set the file permissions
chmod( $filename, $this->options->permissions );
// Prepares the data for APC storage
$dataObj->atime =
time();
if ( !$this->backend->store( $filename, $dataObj, $this->properties['options']['ttl'] ) )
// Returns the ID for no good reason
* Restores the data from the cache.
* @param string $id The item ID to restore
* @param array(string=>string) $attributes Attributes describing the data to restore
* @param bool $search Whether to search for items if not found directly
* @return mixed The cached data on success, otherwise false
public function restore( $id, $attributes =
array(), $search =
false )
// Generates the identifier
// Grabs the data object from the APC
// Checks the APC object exists
&& isset
( $dataObj->atime ) )
// Checks the APC object is still valid
if ( !isset
( $this->registry[$filename] )
&&
time() ===
$dataObj->atime )
// Make sure the FileSystem still has the file and that it hasn't changed
&&
@filemtime( $filename ) ===
$dataObj->mtime )
$dataObj->atime =
time();
$this->backend->delete( $filename );
// Searches the filesystem for the file
if ( !isset
( $this->registry[$filename] )
&&
count( $files =
$this->search( $id, $attributes ) ) ===
1 )
$filename =
$files[0][2];
// There are more elements found during search, so false is returned
// Returns false if no data is stored anywhere
$this->backend->delete( $filename );
if ( isset
( $this->registry[$filename] ) )
// Creates a Registry Object -- should only happen once per page load
if ( !isset
( $this->registry[$filename] ) )
$this->registry[$filename] =
new stdClass();
$this->registry[$filename]->data =
false;
$this->registry[$filename]->mtime =
$useApc ?
$dataObj->mtime :
null;
// Purges the data if it is expired
if ( $this->properties['options']['ttl'] !==
false
$this->delete( $id, $attributes, false ); // don't search
// Returns the data from the Registry Cache
if ( $this->registry[$filename]->data !==
false )
return ( $this->registry[$filename]->data );
else if ( $useApc ===
true
&&
( isset
( $dataObj->data ) ||
is_null( $dataObj->data ) ) )
$this->registry[$filename]->data =
$dataObj->data; // primes the Registry cache
return ( $dataObj->data );
// Returns data from the filesystem
// Grabs the data from the filesystem
// Stores it in the Registry Cache
$this->registry[$filename]->data =
$dataStr;
// Prepares the data for APC storage
$dataObj->atime =
time();
* Deletes the data associated with $id or $attributes from the cache.
* @throws ezcBaseFilePermissionException
* If an already existsing cache file could not be unlinked.
* This exception means most likely that your cache directory
* has been corrupted by external influences (file permission
* @param string $id The item ID to purge
* @param array(string=>string) $attributes Attributes describing the data to restore
* @param bool $search Whether to search for items if not found directly
public function delete( $id =
null, $attributes =
array(), $search =
false )
// Generates the identifier
// Checks if the file exists on the filesystem
$delFiles[] =
array( $id, $attributes, $filename );
else if ( $search ===
true )
$delFiles =
$this->search( $id, $attributes );
foreach ( $delFiles as $count =>
$filename )
// Deletes from Registry Cache
if ( isset
( $this->registry[$filename[2]] ) )
$this->backend->delete( $filename[2] );
if ( isset
( $this->registry[$location][$filename[0]][$filename[2]] ) )
unset
( $this->registry[$location][$filename[0]][$filename[2]] );
// Deletes from the filesystem
if ( @unlink( $filename[2] ) ===
false )
'Could not unlink cache file.'
$deletedIds[] =
$filename[0];
* Checks the path in the location property exists, and is read-/writable. It
* throws an exception if not.
* @throws ezcBaseFileNotFoundException
* If the storage location does not exist. This should usually not
* happen, since {@link ezcCacheManager::createCache()} already
* performs sanity checks for the cache location. In case this
* exception is thrown, your cache location has been corrupted
* after the cache was configured.
* @throws ezcBaseFileNotFoundException
* If the storage location is not a directory. This should usually
* not happen, since {@link ezcCacheManager::createCache()} already
* performs sanity checks for the cache location. In case this
* exception is thrown, your cache location has been corrupted
* after the cache was configured.
* @throws ezcBaseFilePermissionException
* If the storage location is not writeable. This should usually not
* happen, since {@link ezcCacheManager::createCache()} already
* performs sanity checks for the cache location. In case this
* exception is thrown, your cache location has been corrupted
* after the cache was configured.
* Calculates the lifetime remaining for a cache object.
* If the TTL option is set to false, this method will always return 1 for
* @param string $filename The file to calculate the remaining lifetime for
* @param bool $useApc Use APC or not
* @return int The remaining lifetime in seconds (0 if no time remaining)
protected function calcLifetime( $filename, $useApc =
false )
$ttl =
$this->options->ttl;
// Calculate when the APC object was created
// we've likely already looked this thing up in APC, so we'll grab the local object
if ( isset
( $this->registry[$filename] ) )
else // otherwise we'll grab it from APC
( $lifeTime =
( time() -
$dataObj->mtime ) ) >
$ttl
// Calculate when the filesystem file was created
&&
( ( $modTime =
@filemtime( $filename ) ) !==
false ) )
( $lifeTime =
( time() -
$modTime ) ) <
$ttl