开发者

Caching function results in PHP

I'm making a simple tool to cache function results

It look like:

global $function_results;
$function_results = array();

function getMembers($conditions, $default = array('order' => 'name', array('abc', 'def'))){

    //****Help need from here******
    //make unique id from parameters value and function name
    //ex: $uid;
    //****to here******

    global $function_results;
    if(isset($function_results[$uid])) return $function_results[$uid];
    else{
        //do function logic...
    }
}

(the function and开发者_C百科 its parameters are just an example)

Any suggestions?


Here is your missing code:

$numargs = func_num_args();
$arg_list = func_get_args();
$md5this = '';
for ($i = 0; $i < $numargs; $i++) {
    $md5this .= $i.':'.serialize($arg_list[$i]).';';
}
$uid = md5($md5this);

For your reference: http://php.net/manual/en/function.func-get-args.php


Here is a generic memoization solution that is compatible with PHP 5.2.x.

The call_memoized function:

  1. Generates a unique cache key based on the function name and arguments.
  2. If the cache is empty, invokes the function and updates the cache with the result.
  3. Returns the cached value.

Instead of using call_memoized directly, use the provided memoize function, which returns a new version of the given function that will automatically cache results from the same combination of parameters.

See example below.

Enjoy!

global $MEMO_CACHE;
$MEMO_CACHE = array();

/** Returns the result of the function with the given arguments. 
 * Invokes the function only once, thereafter returns the result 
 * cached by a key based on the function name and arguments. */
function call_memoized($fun, $args=array()) {
    global $MEMO_CACHE;

    // generate a cache key based on the function name and arguments
    $uid = md5(
        implode("|", array_merge((array)$fun, array_map(
            "serialize",
            $args)
        ))
    );

    // if there result hasn't been cached, call the function 
    // and update the cache with the result.
    if(!array_key_exists($uid, $MEMO_CACHE)) {
        $MEMO_CACHE[$uid] = call_user_func_array($fun, $args);
    }

    return $MEMO_CACHE[$uid];
}

/** Returns a memoized version of the given function that will cache 
 * its results for each unique set of inputs. */
function memoize($fun) {
    return create_function(
        '', 
        "\$args = func_get_args(); return call_memoized('$fun', \$args);"
    );
}

Example:

/** Returns a random number with the given greeting. */
function random($greeting) {
    return "$greeting! " . rand();
};

print("Five random numbers:</br />");
for($i=0; $i<5; $i++) {
    print(random("Spin the wheel") . "<br />");
}
print "<br />";

print("After memoizing the random function, it's not so random:<br />");
$not_so_random = memoize("random");
for($i=0; $i<5; $i++) {
    print($not_so_random("Spin the wheel") . "<br />");
}
print "<br />";

print("The same memoized function is invoked with a different argument, and 
       thus creates a different cache key:<br />");
for($i=0; $i<5; $i++) {
    print($not_so_random("Twirl the tire") . "<br />");
}

/* OUTPUT

Five random numbers:
Spin the wheel! 26488
Spin the wheel! 20049
Spin the wheel! 14006
Spin the wheel! 28599
Spin the wheel! 804

After memoizing the random function, it's not so random:
Spin the wheel! 32397
Spin the wheel! 32397
Spin the wheel! 32397
Spin the wheel! 32397
Spin the wheel! 32397

The same memoized function is invoked with a different argument, and 
thus creates a different cache key:
Twirl the tire! 2114
Twirl the tire! 2114
Twirl the tire! 2114
Twirl the tire! 2114
Twirl the tire! 2114
*/


I suppose $conditions is an array of some values and you want to create a unique identifier for each variant of that array? There is several ways to do that, eg.:

$uid = md5(serialize($conditions));


Have a look at memoized function implementation from Nspl:

function memoized(callable $function)
{
    return function() use ($function) {
        static $memory = array();
        $args = func_get_args();
        $key = serialize($args);
        if (!isset($memory[$key]) && !array_key_exists($key, $memory)) {
            $memory[$key] = call_user_func_array($function, $args);
        }

        return $memory[$key];
    };
}

Or if you looking for caching function results between server requests you can use Cachalot:

$cache = new \Cachalot\ApcCache();
$result = $cache->getCached($function, $args);

Different back-ends are supported: Apc, Xcache, Memcached, Redis, Couchbase.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜