How to create a simple stateless cache class in PHP i need to create a cache class to avoid making the same calculations more than needed. My idea was something really basic like

class transient_cache {
    static private $cache = array();
    static public function get_value( array $obj, $key ) {
        // $obj is an array( $object, $method )
        $classname = get_class( $obj[0] );
        $method = $obj[1];
        if( ! isset( self::$cache[$classname] ) ) {
            self::$cache[$classname] = array();
        }
        if( ! isset( self::$cache[$classname][$method] ) ) {
            self::$cache[$classname][$method] = array();
        }
        if( ! isset( self::$cache[$classname][$method][$key] ) ) {
            self::$cache[$classname][$method][$key] = call_user_func( $obj );
        }
        return  self::$cache[$classname][$method][$key];
    }   
}


Do you think this approach is correct or would you suggest something better?
I would say that there isn't a correct or incorrect way of achieving this. Everyones requirements differ.

You probably want to expand this out, there's a lot going on in the one static method you have in that class. Whilst I don't have anything against mediator patterns, I would probably combine a number of patterns to build a powerful caching class, as well as utilising magic methods (I know some people are averse to this).

I need to note the below is a lot more complicated and would benefit from some refactoring to be stored against the actual method rather than a key.

class Cache {

    /**
     * Cached objects
     * @static array
     */
    private static $cache = array();

    /**
     * Per instance class name
     * @var string
     */
    private $call;

    /**
     * Per instance method name
     * @static array
     */
    private $method;

    /**
     * Construct the class and build cache array if not set
     * @param string $method
     * @param string $class
     * @param string $key 
     */
    public function __construct($method, $class, $key)
    {
        if ( ! isset(static::$cache[$class] )
            static::$cache[$class] = array();

        if ( ! isset(static::$cache[$class][$method] )
            static::$cache[$class][$method] = array();

        // Set the class for this instance
        $this-&gt;call = $class;

        // Set the method for this instance
        $this-&gt;method= $method;

        // Set the key for the cache
        $this-&gt;key = $key;
    }

    /**
     * Get the cached value
     * @return mixed Cached value
     */
    public function get()
    {
        return $this-&gt;{$this-&gt;key};
    }

    /**
     * Get magic method to return the key
     * @param string $key
     */
    public function __get($key)
    {
        if (isset(static::$cache[$this-&gt;call][$this-&gt;method][$key]))
            return static::$cache[$this-&gt;call][$this-&gt;method][$key];

        return static::$cache[$this-&gt;call][$this-&gt;method][$key] = call_user_func(array($this-&gt;call, $this-&gt;method));
    }

    /**
     * Call static magic method, catches all statically called methods
     * and builds an instance of the cache class using a reflector
     * @param $method
     * @param $args 
     */
    public static function __callStatic($method, $args)
    {
        $method = str_replace(__CLASS__ . '::', '', $method);

        $ref = new ReflectionClass(__CLASS__);

        $inst = $ref-&gt;newInstanceArgs($args);

        return $inst-&gt;get();
    }


}

Usage

$result = Cache::{method}({class}, {key};


To retrieve say a user object from the User class with method get_user;

$user = Cache::get_user('User', 'user_object');


The main advantage to this is that the class can be extended easily using other design patterns such as a Facade that further simplifies the class API. It can also be added to easily with further methods within the class body itself rather than by a pure static call. The class can also be instantiated with the new keyword providing the ability to create separate cache instances that utilise the same static properties and methods.

I need to add this class is very much a prototype that I thought of when I saw your class above. I love cacheing stuff in general and providing standardised interfaces for it is always a great thing to do across all applications you write.