33.3.6 缓存请求返回的数据
现在,我们回到getARS()函数,介绍一些关于缓存的内容。回忆一下,这个函数如下所示:
//Get an AmazonResultSet either from cache or a live query
//If a live query add it to the cache
function getARS($type,$parameters){
$cache=cached($type,$parameters);
if($cache){
//if found in cache
return$cache;
}else{
$ars=new AmazonResultSet;
if($type=='asin'){
$ars->ASINSearch(padASIN($parameters['asin']),$parameters['mode']);
}
if($type=='browse'){
$ars->browseNodeSearch($parameters['browsenode'],$parameters['page'],
$parameters['mode']);
}
if($type=='search'){
$ars->keywordSearch($parameters['search'],$parameters['page'],
$parameters['mode']);
}
cache($type,$parameters,$ars);
}
return$ars;
所有应用程序的SOAP缓存和XML缓存都是通过这个函数实现的。我们还有另一种缓存方法。首先,我们调用cached()方法判断所需的AmazonResultSet对象是否已经被缓存。如果已经被缓存,将直接返回数据,而不是生成一个新的请求:
$cache=cached($type,$parameters);
if($cache)//if found in cache{
return$cache;
}
如果没有被缓存,就必须从Amazon获得数据,然后再将其添加到缓存中:
cache($type,$parameters,$ars);
下面,让我们来看看这两个函数:cached()和cache(),如程序清单33-12所示。这些函数实现了Amazon所要求的缓存技术。
程序清单33-12 cached()和cache()函数——cachefunctions.php的缓存函数
//check if Amazon data is in the cache
//if it is,return it
//if not,return false
function cached($type,$parameters){
if($type=='browse'){
$filename=CACHE.'/browse.'.$parameters['browsenode'].'.'
.$parameters['page'].'.'.$parameters['mode'].'.dat';
}
if($type=='search'){
$filename=CACHE.'/search.'.$parameters['search'].'.'
.$parameters['page'].'.'.$parameters['mode'].'.dat';
}
if($type=='asin'){
$filename=CACHE.'/asin.'.$parameters['asin'].'.'
.$parameters['mode'].'.dat';
}
//is cached data missing or>1 hour old?
if(!file_exists($filename)||
((mktime()-filemtime($filename))>60*60)){
return false;
}
$data=file_get_contents($filename);
return unserialize($data);
}
//add Amazon data to the cache
function cache($type,$parameters,$data){
if($type=='browse'){
$filename=CACHE.'/browse.'.$parameters['browsenode'].'.'
.$parameters['page'].'.'.$parameters['mode'].'.dat';
}
if($type=='search'){
$filename=CACHE.'/search.'.$parameters['search'].'.'
.$parameters['page'].'.'.$parameters['mode'].'.dat';
}
if($type=='asin'){
$filename=CACHE.'/asin.'.$parameters['asin'].'.'
.$parameters['mode'].'.dat';
}
$data=serialize($data);
$fp=fopen($filename,'wb');
if(!$fp||(fwrite($fp,$data)==-1)){
echo('<p>Error,could not store cache file');
}
fclose($fp);
仔细查看以上代码,可以发现,缓存文件保存在一个由查询类型以及查询参数组成的文件名称的文件中。cache()函数通过对这些数据进行序列化操作,从而保存了这些数据。cached()函数也将在一个小时后覆盖这些数据,这是Amazon协议所规定的。
serialize()函数将所保存的程序数据转换成一个可以单独保存的字符串。在这个例子中,我们为AmazonResultSet对象创建了一个表示给对象的、可以用于保存的格式。调用unserialize()函数可以完成相反的操作,它可以将保存的数据转换成内存中的数据结构。请注意,像这样的反序列化一个对象意味着必须拥有该类的文件定义,这样在该类被载入后,该类就可以被理解并使用。
在我们的应用程序中,从缓存获取结果只需要很短的时间,而执行一个实时查询则要十秒钟的时间。