Cri*_*ghi 5 php api json curl caching
我的网站上有一些自定义社交按钮,我可以使用API中的json获取共享编号/关注者编号.我试图实现一个缓存系统来减少加载时间,并消除因过度使用API而被"标记为红色"的风险.但是,我在这方面没有成功,主要是因为我不太了解整合步骤.我希望有人可以帮我集成缓存系统.
以下是Twitter,Google Plus和Instagram的php代码:
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;
$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'];
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 加载关注者信息,以减少页面加载时间,例如需要更新关注者计数时。
我将使用以下数据库架构:
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;
Run Code Online (Sandbox Code Playgroud)
首先,我定义一个接口,这样您就不需要依赖任何实现:
interface SocialFollowers
{
public function getFollowers();
}
Run Code Online (Sandbox Code Playgroud)
然后,对于 twitter 共享 API,我有一个实现类,它获取数据库句柄和用于初始化的目标 URL。类属性由检索到的数据(如果可用)填充。如果时间戳足够新,您将立即获得关注者数量,否则将查询 API,存储结果,然后检索关注者数量。
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;
}
}
Run Code Online (Sandbox Code Playgroud)
对于 Facebook、Google+ 等下一个社交网络,您只需要添加另一个实现即可。
请记住,此代码未经测试。它错过了 PDO 查询的一些 try/catch 块,并且还有改进的空间(例如:缺少某种锁定机制来防止并发检索同一 URL,是否有必要存储返回的 blob 等)。
希望这对您有帮助。
[编辑]我稍微更新了代码(修复了一些拼写错误和转换问题)并进行了测试。您可以在github找到工作版本。所缺少的只是 ajax 片段(假设是 jQuery),例如
$.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);
}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1813 次 |
| 最近记录: |