How to implement cache system in php for json api
我在我的网站上有几个自定义的社交按钮,我使用API中的JSON为其获取共享号/关注者号。我试图实现一个缓存系统,以减少加载时间,消除因过度使用API而被"红色标记"的风险。但是,我在这方面没有成功,主要是因为我不太了解集成步骤。我希望有人能帮我集成一个缓存系统。
以下是Twitter、Google Plus和Instagram的PHP代码:
- 推特
1 2 3 4 5 6 7 8 9 10 11 12 13 | ob_start(); $twittershare = 'http://cdn.api.twitter.com/1/urls/count.json?url='.$product["href"] .''; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $twittershare); curl_setopt($ch, CURLOPT_HEADER, 0); $jsonstring = curl_exec($ch); curl_close($ch); $bufferstr = ob_get_contents(); ob_end_clean(); $json = json_decode($bufferstr); echo $json->count; |
- 谷歌Plus
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | $url = ''.$product["href"] .''; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL,"https://clients6.google.com/rpc?key=xxxxxxxxxx"); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, '[{"method":"pos.plusones.get","id":"p","params":{"nolog":true,"id":"' . $url . '","source":"widget","userId":"@viewer","groupId":"@self"},"jsonrpc":"2.0","key":"p","apiVersion":"v1"}]'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/json')); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $curl_results = curl_exec($ch); curl_close($ch); $json = json_decode($curl_results, true); $count = intval($json[0]['result']['metadata']['globalCounts']['count']); $data = array(); $data['plus_count'] = (string) $count; $data['url'] = $url; echo $data['plus_count']; |
号
- Instagram(获取追随者编号)
1 2 3 4 5 6 7 8 9 10 11 12 13 | ob_start(); $insta = 'https://api.instagram.com/v1/users/00000000?access_token={token}'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $insta); curl_setopt($ch, CURLOPT_HEADER, 0); $jsonstring = curl_exec($ch); curl_close($ch); $bufferstr = ob_get_contents(); ob_end_clean(); $json = json_decode($bufferstr); echo $json->data->counts->followed_by; |
希望你们能一步一步地指导我如何为上面的代码片段实现缓存系统。
好吧,正如我在评论中提到的,我会使用memcached和一个数据库,但是我会起草一个只包含数据库的解决方案(对于twitter使用pdo),并将memcached部分留给您作为奖励练习。;)我将通过Ajax加载跟随者信息,以减少页面加载时间,例如,当跟随者计数需要更新时。
我将使用以下数据库架构:
1 2 3 4 5 6 7 8 | CREATE TABLE IF NOT EXISTS `Followers` ( `id` int(11) NOT NULL AUTO_INCREMENT, `url` varchar(100) NOT NULL, `data` longtext NOT NULL, `followers` int(5) NOT NULL, `last_update` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
首先,我将定义一个接口,这样您就不需要依赖任何实现:
1 2 3 4 | interface SocialFollowers { public function getFollowers(); } |
号
然后,对于Twitter共享API,我将拥有一个实现类,该类获取数据库句柄和用于初始化的目标URL。类属性由检索到的数据填充(如果可用)。如果时间戳足够新,您将立即获得关注者数量,否则将查询API,存储结果,然后检索关注者数量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | class TwitterFollowers implements SocialFollowers { private $data = null; private $url =""; private $db = null; private $followers = null; protected $shareURL ="https://cdn.api.twitter.com/1/urls/count.json?url="; public function __construct($db, $url) { // initialize the database connection here // or use an existing handle $this->db = $db; // store the url $this->url = $url; // fetch the record from the database $stmt = $this->db->prepare('SELECT * FROM `Followers` WHERE url = :url ORDER BY last_update DESC LIMIT 1'); $stmt->bindParam(":url", $url); $stmt->execute(); $this->data = $stmt->fetch(PDO::FETCH_ASSOC); if (!empty($this->data)) $this->followers = $this->data["followers"]; } public function getFollowers() { // create a timestamp that's 30 minutes ago // if it's newer than the value from the database -> call the api $old = new DateTime(); $old->sub(new DateInterval("PT30M")); if (is_null($this->followers) || (new DateTime($this->data["last_update"]) < $old) ) { return $this->retrieveFromAPI(); } return $this->followers; } private function retrieveFromAPI() { // mostly untouched ob_start(); $twittershare = $this->shareURL . $this->url; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $twittershare); curl_setopt($ch, CURLOPT_HEADER, 0); $jsonstring = curl_exec($ch); curl_close($ch); $bufferstr = ob_get_contents(); ob_end_clean(); $json = json_decode($bufferstr); $this->followers = $json->count; // store the retrieved values in the database $stmt = $this->db->prepare('INSERT INTO Followers (url, data, followers)' .'VALUES (:url, :data, :followers)'); $stmt->execute(array( ":url" => $this->url, ":data" => $bufferstr, ":followers" => $this->followers )); return $this->followers; } } |
对于facebook,google+,下一个社交网络,你只需要添加另一个实现。
请记住,此代码未经测试。它遗漏了一些用于PDO查询的try/catch块,并且还有改进的空间(例如:缺少某种锁定机制以防止同一URL的并发检索,是否需要存储返回的blob等)。
希望这对你有帮助。
[编辑]我稍微更新了代码(修正了一些打字错误和转换问题),并测试了它。你可以在GitHub找到一个有效的版本。缺少的只是ajax片段(假设jquery),比如
1 2 3 4 5 6 7 8 9 10 | $.ajax({ url:"http://example.com/twitter.php", type:"get", data: {url:"http://stackoverflow.com"} success: function(data, textStatus, jqXHR) { // Update the corresponding counter like // $("#twitterfollowers").text(data); console.log(data); } }); |
。