有点小问题。我一直在玩facebook和twitter的API,并获得状态搜索查询的JSON输出,这没问题,但我读了更多,并意识到我最终可能会受到文档中引用的"速率限制"。
我想知道每小时缓存JSON输出是否容易,这样我至少可以尝试防止这种情况发生?如果是这样,是如何做到的?当我尝试一个youtube视频时,它并没有真正给出太多信息——只有如何将目录列表的内容写入cache.php文件,但它并没有指出是否可以使用JSON输出来完成这一点,当然也没有说明如何使用60分钟的时间间隔,或者如何从缓存文件中获取信息。
任何帮助或代码都将不胜感激,因为教程中似乎很少有关于这类事情的内容。
这里有一个简单的函数,它为获取一些URL内容添加了缓存:
function getJson($url) {
// cache files are created like cache/abcdef123456...
$cacheFile = 'cache' . DIRECTORY_SEPARATOR . md5($url);
if (file_exists($cacheFile)) {
$fh = fopen($cacheFile, 'r');
$size = filesize($cacheFile);
$cacheTime = trim(fgets($fh));
// if data was cached recently, return cached data
if ($cacheTime > strtotime('-60 minutes')) {
return fread($fh, $size);
}
// else delete cache file
fclose($fh);
unlink($cacheFile);
}
$json = /* get from Twitter as usual */;
$fh = fopen($cacheFile, 'w');
fwrite($fh, time() . "'n");
fwrite($fh, $json);
fclose($fh);
return $json;
}
它使用URL来识别缓存文件,下次将从缓存中读取对相同URL的重复请求。它将时间戳写入缓存文件的第一行,超过一小时的缓存数据将被丢弃。这只是一个简单的例子,您可能需要自定义它。
使用缓存来避免速率限制是个好主意。下面是一些示例代码,展示了我是如何为Google+数据做这件事的,在我最近写的一些php代码中。
private function getCache($key) {
$cache_life = intval($this->instance['cache_life']); // minutes
if ($cache_life <= 0) return null;
// fully-qualified filename
$fqfname = $this->getCacheFileName($key);
if (file_exists($fqfname)) {
if (filemtime($fqfname) > (time() - 60 * $cache_life)) {
// The cache file is fresh.
$fresh = file_get_contents($fqfname);
$results = json_decode($fresh,true);
return $results;
}
else {
unlink($fqfname);
}
}
return null;
}
private function putCache($key, $results) {
$json = json_encode($results);
$fqfname = $this->getCacheFileName($key);
file_put_contents($fqfname, $json, LOCK_EX);
}
并使用它:
// $cacheKey is a value that is unique to the
// concatenation of all params. A string concatenation
// might work.
$results = $this->getCache($cacheKey);
if (!$results) {
// cache miss; must call out
$results = $this->getDataFromService(....);
$this->putCache($cacheKey, $results);
}
我知道这篇文章很旧,但它显示在谷歌上,所以对于所有寻找它的人来说,我做了一个简单的帖子,卷曲一个JSON url并将其缓存在特定文件夹中的文件中,当JSON再次被请求时,如果经过了5分钟,它会卷曲它,如果5分钟还没有通过,它会从文件中显示它,它使用时间戳来跟踪时间,是的,享受
function ccurl($url,$id){
$path = "./private/cache/$id/";
$files = scandir($path);
$files = array_values(array_diff(scandir($path), array('.', '..')));
if(count($files) > 1){
foreach($files as $file){
unlink($path.$file);
$files = scandir($path);
$files = array_values(array_diff(scandir($path), array('.', '..')));
}
}
if(empty($files)){
$c = curl_init();
curl_setopt($c, CURLOPT_URL, $url);
curl_setopt($c, CURLOPT_TIMEOUT, 15);
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_USERAGENT,
'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0');
$response = curl_exec($c);
curl_close ($c);
$fp = file_put_contents($path.time().'.json', $response);
return $response;
}else {
if(time() - str_replace('.json', '', $files[0]) > 300){
unlink($path.$files[0]);
$c = curl_init();
curl_setopt($c, CURLOPT_URL, $url);
curl_setopt($c, CURLOPT_TIMEOUT, 15);
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_USERAGENT,
'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0');
$response = curl_exec($c);
curl_close ($c);
$fp = file_put_contents($path.time().'.json', $response);
return $response;
}else {
return file_get_contents($path. $files[0]);
}
}
}
对于用法,为所有缓存的文件创建一个目录,对我来说,它的/private/cache
,然后在里面为请求缓存创建另一个目录(例如x),当调用函数时,它应该像htisccurl('json_url','x')
其中x是id,如果你有问题,请问我^_^也可以享受(我稍后可能会更新它,这样它就不会使用id 的目录