CacheManager
As you can take from the
Roadmap, the 1.8 branch
contains a redesigned cache manager. The old dated implementation had various disadvantages while
using the cache classes or extend them, respectively.
Hence, the new implementation is much more convenient but yet powerful due to the easy extension API.
The
CacheManager itself only deals with the creation and configuration of the concrete
CacheProvider implementations, that present the write, read and clear capabilities.
The release already contains common providers and an abstract provider definition that allows you to
enhance the list of providers easily.
The
CacheManager expects a configuration file within the
tools::cache
namespace and the current application's context. The name of the config file is
cacheconfig.
For each cache manager, one configuration section must be present in the configuration containing the
following directives:
APF-Konfiguration
[my_cache_instance]
Cache.Provider.Namespace = ""
Cache.Provider.Class = ""
Cache.Active = ""
The
Cache.Provider.Namespace parameter defines the namespace of the provider
implementation,
Cache.Provider.Class contains the class name and
Cache.Active
defines the activity state of the cache manager. In case, the configuration directive contains "true",
the cache manager is considered active, otherwise not.
Please note, that each provider expects some more configuration attributes, described in the
following chapters.
The cache manager design includes the possibility to create several cache manager instances within
one application or one module. For this reason, a factory is used to create the cache managers.
Therefor, the
CacheManagerFabric features the
getCacheManager()
method, that creates the desired cache manager corresponing to the configuration section. Hence, the
fabrix ist created via the service manager, the fabric is a singleton to not slow down the performance
of the component due to several initialisation processes. Caching components have to be fast per se!
The following code box provides a typical application sample:
PHP-Code
$cMF = &$this->__getServiceObject('tools::cache','CacheManagerFabric');
$cM = &$cMF->getCacheManager('{config_section}');
$cacheKey = 'my_cache_key';
$cacheContent = $cM->getFromCache($cacheKey);
if($cacheContent === null){
$cacheContent = /* generate content */;
$cM->writeToCache($cacheKey,$cacheContent);
}
// clear cache if necessary
if(/* ... */){
if(/* ... */){
$cM->clearCache($cacheKey); // clean only the desired cache content
}
else{
$cM->clearCache(); // clean the entire namespace
}
}
As you can see, the cache manager has three API methods, that delegate the functionality to the
corresponding provider, that is currently used:
-
getFromCache(): Reads the desired cache content. If no content is available for
the given cache key, null is returned. This can be used to check, if a cache entry exists
at the same time.
-
writeToCache(): Writes the desired content to namespace configured within the
configuration section. The method returns true on success, otherwise false.
-
clearCache(): The clearCache() method can be used to maintain the cache.
If no cache key is provided during function call, the entire namespace is purged, if a key is
present, the cache content for this key is deleted.
The framework already includes four ready-to-use provider. These are aimed to solve common caching
issues. If there is not provider fitting your requirements, an own provider can be implemented as
described in chapter 4.
Der Text-Cache-Provider implementiert ein einfaches Filesystem-Caching. Hierbei wird unter einem
definierten Basis-Pfad der gewünschte Cache-Inhalt strukturiert abgelegt. Als erstes
Strukturelement wird der Namespace eingesetzt, gefolgt von einem weiteren Unterordner aus den ersten
beiden Zeichen des md5-Schlüssels des Cache-Keys.
To use this provider, the referenced configuration section must look like this:
APF-Konfiguration
[text_cache]
Cache.Provider.Namespace = "tools::cache::provider"
Cache.Provider.Class = "TextCacheProvider"
Cache.Active = ""
Cache.BaseFolder = ""
Cache.Namespace = ""
Cache.BaseFolder contains the cache base folder, that is managed by the CacheManager,
the attribute
Cache.Namespace names the namespace, that is the first structural
element within the base folder. Please note, that the sections of the namespace must be seperated by
"::" to create the desired subfolder structure.
Note: The text cache provider uses the
FilesystemManager
for cache folder management. For this reason, the user that is assigned to the webserver, must habe
write permissions to the base folder.
The object cache provider is based on the text cache provider described under section 3.1. As of the
text cache provider, the cache files are also stored on the filesystem. The difference is, that this
provider serializes the objects presented to the cache manager before storing them within a cache
file. This mechanism enables the developer to create a filesystem based object cache.
To use the provider, the following directives have to be included in the configuration section:
APF-Konfiguration
[object_cache]
Cache.Provider.Namespace = "tools::cache::provider"
Cache.Provider.Class = "ObjectCacheProvider"
Cache.Active = ""
Cache.BaseFolder = ""
Cache.Namespace = ""
The memcache provider gives you the opportunity to store PHP objects within a
memcached
server. To make the objects storable, they are serialized whilst saving and unserialized when retrieving
from the cache. Please note, that resource types cannot be serialized and have to be reinitialized
on unserialize.
To access a
memcached, the following configuration section must be provided:
APF-Konfiguration
[mem_cache]
Cache.Provider.Namespace = "tools::cache::provider"
Cache.Provider.Class = "MemCacheProvider"
Cache.Active = ""
Cache.Host = ""
Cache.Port = ""
Cache.PersistentConnect = ""
Cache.Namespace = ""
Despite the fact, that the PHP memcache functions do not support namespaces within the memcache
cache keys, the
MemCacheProviders supports namespaces. This is realized by the
internal cache key management. This renders possible to clear all cache keys within one namespace as
described in the above code sample.
Note: To use the
MemCacheProvider, the PHP extenstion
memcache
must be loaded!
The
DBCacheProvider uses a database table to store the cache information. In order
to use the database as a cache backend, the configuration section should look like this:
APF-Konfiguration
[database_cache]
Cache.Provider.Namespace = "tools::cache::provider"
Cache.Provider.Class = "DBCacheProvider"
Cache.Active = ""
Cache.Connection = ""
Cache.Table = ""
Cache.Namespace = ""
Thereby,
Cache.Connection specifies the database connection key, that is used to
create a database connection with the
ConnectionManager.
For this reason, a corresponding database connection configuration must be provided as described in
the ConnectionManager's class reference.
Cache.Table defines the name of the cache
table, that should be created with the statement below:
Code
CREATE TABLE `database_cache` (
`CacheID` int(5) NOT NULL auto_increment,
`namespace` varchar(100) NOT NULL default '',
`cachekey` varchar(100) NOT NULL default '',
`value` text NOT NULL,
PRIMARY KEY (`CacheID`),
KEY `cachevalues` (`namespace`,`cachekey`)
);
Allow me to call your attention to the fact, that the columns
namespace,
cachekey and
value must be named as printed above.
The design of the cache manager includes several components. The creation of the desired cache manager
instance is done by the
CacheManagerFabric. This component creates, initializes and
manages the concrete
CacheManager instances. The cache manager itself deals with the
initialization of the desired provider and features the interface methods described in chapter 2.
Thus, each provider implements the three abstract methods
read(),
write() and
clear() of the
AbstractCacheProvider
class. These functions is given the desired cache key and the cache content as desired. To access
the configuration params defined in the dedicated section, the private
__getCacheConfigAttribute() function can be used. Applying the name of the attribute,
the method returns the content of the given directive. For operating purposes, the method triggers
an error, if the attribute is not existing or empty. Details can be taken from the API definition
for the class on the
downloads page.
Thanks to the fact, that a provider is addressed by it's namespace and class name, an own provider
can be stored where ever you want. The body of a application specific provider looks like this:
PHP-Code
class MyCacheProvider extends AbstractCacheProvider
{
function MyCacheProvider(){
}
function read($cacheKey){
}
function write($cacheKey,$content){
}
function clear($cacheKey = null){
}
}
The return values are described in the API documentation of the
AbstractCacheProvider
class. If the functionality of existing providers should be used, you can easily inherit from the
desired provider. This is already used within the
ObjectCacheProvider, because the cache
folder and cache file name generation is also used within this provider.
The code box below gives you an idea, how a cache provider for image ressources could look like:
PHP-Code
class PNGImageCacheProvider extends TextCacheProvider
{
function PNGImageCacheProvider(){
}
function read($cacheKey){
$cacheFile = $this->__getCacheFile($cacheKey);
if(!file_exists($cacheFile)){
return null;
}
else{
return createimagefrompng($cacheFile);
}
}
function write($cacheKey,$img){
$cacheFile = $this->__getCacheFile($cacheKey);
FilesystemManager::createFolder(dirname($cacheFile));
imagepng($img,$cacheFile);
}
function clear($cacheKey = null){
if($cacheKey === null){
$baseFolder = $this->__getCacheConfigAttribute('Cache.BaseFolder');
FilesystemManager::deleteFolder($baseFolder,true);
}
else{
$cacheFile = $this->__getCacheFile($cacheKey);
FilesystemManager::removeFile($cacheFile);
}
}
}
Comments
Do you want to add a comment to the article above, or do you want to post additional hints? So please click
here. Comments already posted can be found below.
There are no comments belonging to this article.