<?php

class Cache_Exception_Logic extends InvalidArgumentException {}
class 
Cache_Exception_Runtime extends RuntimeException {}

class 
Cache
{
  protected
    
$_oEngine null;
  
  protected
    
$_sZone '',
    
$_aZonePath = array();
  
  
/**
   * @param string sZone Cache path, ex.: "MyCache" or "SomeGroup/Subgroup/MyCache"
   * @param string|object mEngine engine provided as string for name of engine or instance of object
   */
  
public function __construct($sZone$mEngine 'File')
  {
    
$aZone explode('/'$sZone);
    
$this->_sZone array_pop($aZone);
    
$this->_aZonePath $aZone;
    
    if(
is_string($mEngine))
    {
      
$sEngineObject 'Cache_Engine_' ucfirst(strtolower($mEngine));
      
$this->_oEngine = new $sEngineObject($this);
    }
    elseif(
is_object($mEngine))
      
$this->_oEngine $mEngine;
    
    if(
$this->_oEngine instanceof Cache_Engine)
      throw new 
Cache_Exception_Logic('Provided engine does not implements the Cache_Engine interface.');
  }
  
  
/**
   * All calls will be forwarded to Cache Engine
   */
  
public function __call($sMethod, array $aParams)
  {
    return 
call_user_func_array(array($this->_oEngine$sMethod), $aParams);
  }
}

interface 
Cache_Engine
{
  public function 
__construct(Cache $oParent);
  
  public function 
expired($iExpirityTime);
  public function 
load($iTimeout null);
  
  public function 
savePrepare($iTimeout null);
  public function 
save($mContent);
  public function 
saveFinalize();
  
  public function 
delete();
  public function 
deleteGroup($sZone);
}