【问题标题】:Caching JSON output in PHP在 PHP 中缓存 JSON 输出
【发布时间】:2012-07-09 14:05:29
【问题描述】:

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

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

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

【问题讨论】:

    标签: php json caching


    【解决方案1】:

    这里有一个简单的函数,可以添加缓存来获取一些 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 的重复请求将在下一次从缓存中读取。它将时间戳写入缓存文件的第一行,超过一小时的缓存数据将被丢弃。这只是一个简单的示例,您可能需要对其进行自定义。

    【讨论】:

    • 最后一个似乎很简单,但我将如何在我的网站上使用它。我对 PHP 还是很陌生,只是在过去的一年里才开始学习,所以请原谅我的菜鸟。我不确定 $json = /* 像往常一样从 twitter 中获取的内容 */;部分。我是这样用的吗:
    • 我的代码:- code $query = "i%20hate%20my%20girlfriend"; $query = urlencode($query); $url = "search.twitter.com/search.json?q={$query}&rpp=100&result_type=recent&lang=en"; $tweet = file_get_contents($url); $tweet_array = json_decode($tweet, true); foreach ($tweet_array['results'] as $data) { $profileimg = $data['profile_image_url']; $postfrom = $data['from_user_name']; $postfromid = $data['from_user_id']; $created = $data['created_at']; $message = $data['text'];
    • 我已经对我的代码发表了评论,我不确定如何将其放入 cmets 框中,希望您能够将其复制并粘贴并将其分开,以便您知道它的样子.我对如何处理这个函数有点困惑。
    • 在您的情况下,$tweet = file_get_contents($url) 行为您提供了原始 JSON 数据。这就是你要找的。在上述函数中,使用$json = file_get_contents($url);。在您的代码中,使用 $tweet = getJson($url); 来获取和缓存 URL。
    • 为那个家伙干杯,感谢您的帮助!
    【解决方案2】:

    使用缓存来避免速率限制是个好主意。 下面是一些示例代码,展示了我是如何处理 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);
            }
    

    【讨论】:

      【解决方案3】:

      我知道这篇文章很旧,但它显示在谷歌,所以对于每个人来说,我做了一个简单的卷曲 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

      【讨论】:

        猜你喜欢
        • 2016-10-19
        • 1970-01-01
        • 2010-09-26
        • 1970-01-01
        • 1970-01-01
        • 2011-01-26
        • 1970-01-01
        • 1970-01-01
        • 2016-05-26
        相关资源
        最近更新 更多