这个问题与一个关于Java的问题类似,但我正在使用PHP,所以我认为它不符合重复的要求。
当调用此函数时,我希望有一种生成确定性键的方法。该函数应像读取缓存一样运行。如果键存在,则检索数据。如果不存在,则调用函数存储数据,然后返回数据。
这是我目前的代码,它可以工作,但我不确定它是否安全、确定性足够或唯一性足够,因为我对这些主题一窍不通。
我的问题只涉及第三行,其中密钥是通过调用函数和提供给该函数的参数计算出来的。在某些情况下,我遇到了碰撞。我正在寻找改进方法,使其更有用且哈希值一致但不太可能发生碰撞。第三个参数可以忽略,因为它只是一种绕过缓存的方式。
此函数的调用示例: $data = $db->cachedCall('getUserByEmail',[$this->email],true); $data = $db->cachedCall('getCell',['SELECT id FROM foobar WHERE foo=:bar',[':bar'=>55]]);
如果可能的话,我希望同时保证密钥具有一致的长度。
当调用此函数时,我希望有一种生成确定性键的方法。该函数应像读取缓存一样运行。如果键存在,则检索数据。如果不存在,则调用函数存储数据,然后返回数据。
这是我目前的代码,它可以工作,但我不确定它是否安全、确定性足够或唯一性足够,因为我对这些主题一窍不通。
// $call = function being called $args = arguments to that function
// $force = force cache to bypassed, then updated
public function cachedCall($call,$args = [],$force = false)
{
$cache = \App\App::getInstance()->cache;
$key = md5($call) . md5(serialize($args));
$res = $cache->get($key);
if($res === -1 || $force){
$res = call_user_func_array([$this,$call],$args);
if(!empty($res) && $res !== false && $res !== 0 && !is_null($res)){
$cache->set($key,$res,0); //never set empty data in the cache.
}
}
return $res;
}
我的问题只涉及第三行,其中密钥是通过调用函数和提供给该函数的参数计算出来的。在某些情况下,我遇到了碰撞。我正在寻找改进方法,使其更有用且哈希值一致但不太可能发生碰撞。第三个参数可以忽略,因为它只是一种绕过缓存的方式。
此函数的调用示例: $data = $db->cachedCall('getUserByEmail',[$this->email],true); $data = $db->cachedCall('getCell',['SELECT id FROM foobar WHERE foo=:bar',[':bar'=>55]]);
如果可能的话,我希望同时保证密钥具有一致的长度。
$key = md5($caller . md5($call) . md5(serialize($args)));
有什么问题吗?它使用了参数和调用的起点。看看 "$caller" 是如何生成的,将其打印出来并决定这是否是您想要的。 - Harry$this
是什么?它是单例还是您的应用程序中有多个对象实例? - user149341