缓存函数导致PHP

时间:2010-08-22 06:05:39

标签: php caching memoization

我正在制作一个缓存功能结果的简单工具

看起来像:

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...
    }
}

(函数及其参数只是一个例子)

有什么建议吗?

4 个答案:

答案 0 :(得分:9)

这是您遗失的代码:

$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);

供参考:http://php.net/manual/en/function.func-get-args.php

答案 1 :(得分:5)

这是一个与PHP 5.2.x兼容的通用memoization解决方案。

call_memoized函数:

  1. 根据函数名称和参数生成唯一的缓存键。
  2. 如果缓存为空,则调用该函数并使用结果更新缓存。
  3. 返回缓存的值。
  4. 使用提供的memoize函数,而不是直接使用call_memoized,该函数返回给定函数的新版本,该函数将自动缓存来自相同参数组合的结果。

    见下面的例子。

    享受!

    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);"
        );
    }
    

    示例:

    /** 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
    */
    

答案 2 :(得分:3)

查看memoized中的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];
    };
}

或者,如果您在服务器请求之间查找缓存功能结果,则可以使用Cachalot

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

支持不同的后端:Apc,Xcache,Memcached,Redis,Couchbase。

答案 3 :(得分:2)

我认为$conditions是一些值的数组,你想为该数组的每个变体创建一个唯一的标识符?有几种方法可以做到这一点,例如:

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