如何在php中为json api实现缓存系统

我在我的网站上有几个自定义社交按钮,我使用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;
    
    
  • Google Plus
  • 
        $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(提取关注者数量)
  • 
        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和数据库,但是我将起草一个仅限于数据库的解决方案(使用PDO for twitter),并将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;
    

    首先我要定义一个接口,以便不依赖任何实现:

    interface SocialFollowers
    {
        public function getFollowers();
    }
    

    然后,对于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;
        }
    }
    

    对于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);
        }
    });
    
    链接地址: http://www.djcxy.com/p/35845.html

    上一篇: How to implement cache system in php for json api

    下一篇: Port Vimeo Upload PHP POST Request