16

有点小问题。一直在使用 facebook 和 twitter API 并获得状态搜索查询的 JSON 输出没问题,但是我进一步阅读并意识到我最终可能会受到文档中引用的“速率限制”。

我想知道每小时缓存 JSON 输出是否容易,以便我至少可以尝试防止这种情况发生?如果是这样,它是如何完成的?当我尝试了一个 youtube 视频时,它并没有真正提供太多信息,只是如何将目录列表的内容写入 cache.php 文件,但它并没有真正指出这是否可以通过 JSON 输出完成,当然没有说如何使用 60 分钟的时间间隔或如何获取信息然后从缓存文件中返回。

任何帮助或代码将不胜感激,因为关于这种事情的教程似乎很少。

4

3 回答 3

36

这是一个简单的函数,它添加了缓存以获取一些 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');
        $cacheTime = trim(fgets($fh));

        // if data was cached recently, return cached data
        if ($cacheTime > strtotime('-60 minutes')) {
            return fread($fh);
        }

        // 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 的重复请求将在下一次从缓存中读取。它将时间戳写入缓存文件的第一行,超过一小时的缓存数据将被丢弃。这只是一个简单的示例,您可能想要自定义它。

于 2012-07-10T06:20:01.913 回答
8

使用缓存来避免速率限制是个好主意。下面是一些示例代码,展示了我如何在我最近编写的一些 php 代码中处理 Google+ 数据。

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);
        }
于 2012-07-10T06:09:22.253 回答
0

我知道这篇文章很旧,但它显示在谷歌所以对于每个人来说,我做了这个简单的卷曲 JSON url 并将其缓存在特定文件夹中的文件中,如果 5 分钟通过它会再次请求 json如果 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,当调用函数时,它应该像 htis ccurl('json_url','x') ,其中 x 是 id,如果你有问题请问我^_^ 也很享受(我可能稍后会更新它,所以它不会使用目录作为 id

于 2021-11-07T12:32:13.303 回答