在 PHP 中缓存 JSON 输出

2022-08-31 00:15:28

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

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

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


答案 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');
        $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的重复请求。它将时间戳写入缓存文件的第一行,并丢弃早于一小时的缓存数据。这只是一个简单的示例,您可能希望对其进行自定义。


答案 2

最好使用缓存来避免速率限制。这里有一些示例代码,显示了我如何在我最近写的一些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);
        }

推荐