Facebook总股数不起作用

时间:2015-04-27 11:51:02

标签: php facebook facebook-graph-api

我正在使用donReach.com在github项目中提供的总份额计数PHP脚本。

问题 - 除facebook外,其他所有计数服务都很完美。它总是显示0个计数。

但是,如果我使用他们的API网址来检查我的任何网址共享https://count.donreach.com/?url=http://www.twistblogger.com/2015/04/floating-social-media-share-buttons-bar-blogger-total-share-count.html

它完美地展示了所有的计数。

所以我的问题是我的问题是什么?我使用相同的PHP脚本并按照指南上传到http://codefreak.hol.es/?url=http://www.twistblogger.com/2015/04/floating-social-media-share-buttons-bar-blogger-total-share-count.html,但它没有按预期的方式工作。

以下是共享计数代码:

<?php
require_once("config.php");
class shareCount {
    private $config;
    private $data;
    private $url;
    private $format;
    private $callback;
    private $cache;
    private $cache_directory;
    private $cache_time;

    function __construct() {
        $this->config = new Config;
        $this->cache = $this->config->cache;
        $this->cache_directory = $this->config->cache_directory;
        $this->cache_time = $this->config->cache_time;
        $this->data = new stdClass;
    }

    private function getVar($var, $strict = false) {
        if(array_key_exists($var, $_REQUEST) && $_REQUEST[$var] !== "") return $_REQUEST[$var];
        elseif($strict) return false;
        else return $this->config->$var;
    }

    public function get($url) {
        $this->url = $url;
        $this->data->url           = $this->url;
        $this->data->shares        = new stdClass;
        $this->data->shares->total = 0;

        return $this->getShares($url)->shares;
    }

    public function serve() {
        $this->url = $this->url ?: filter_input(INPUT_GET, 'url', FILTER_SANITIZE_URL);

        // kill the script if no URL provided
        if(!$this->url) die("Error: No URL specified.");

        $this->setFormat($this->format ?: $this->getVar('format'));
        $this->callback            = $this->callback ?: $this->getVar('callback');
        $this->data                = new stdClass;
        $this->data->url           = $this->url;
        $this->data->shares        = new stdClass;
        $this->data->shares->total = 0;

        $data = $this->getData();
        return $data;
    }

    // set format of the output
    private function setFormat ($format) {
        switch($format) {
            case "xml":
                $this->format = 'xml';
                header ("Content-Type:text/xml"); 
                break;
            case "jsonp": 
                $this->format = 'jsonp';
                header ("Content-Type: application/javascript"); 
                break;
            case "json": // only here for reference
            default:
                if($this->getVar('callback', true)) {
                    $this->format = 'jsonp';
                    header ("Content-Type: application/javascript"); 
                }
                else {
                    $this->format = 'json';
                    header ("Content-Type:application/json");
                }
        }
        return $format;
    }

    // query API to get share counts
    public function getShares($url = '') {
        $url = $url ?: $this->url;

        $shareLinks = array(
            "facebook"    => "https://api.facebook.com/method/links.getStats?format=json&urls=",
            "twitter"     => "http://urls.api.twitter.com/1/urls/count.json?url=",
            "google"      => "https://plusone.google.com/_/+1/fastbutton?url=",
            "linkedin"    => "https://www.linkedin.com/countserv/count/share?format=json&url=",
            "pinterest"   => "http://api.pinterest.com/v1/urls/count.json?url=",
            "stumbleupon" => "http://www.stumbleupon.com/services/1.01/badge.getinfo?url=",
            "delicious"   => "http://feeds.delicious.com/v2/json/urlinfo/data?url=",
            "reddit"      => "http://www.reddit.com/api/info.json?&url=",
            "buffer"      => "https://api.bufferapp.com/1/links/shares.json?url=",
            "vk"          => "https://vk.com/share.php?act=count&index=1&url="
        );

        foreach($shareLinks as $service=>$provider) {
            @$this->getCount($service, $provider . $this->url);
        }

        switch($this->format) {
            case 'xml':
                return $this->generateValidXmlFromObj($this->data, "data");
            case 'json':
            case 'jsonp':
                return json_encode($this->data);
            default:
                return $this->data;
        }
    }

    // query API to get share counts
    private function getCount($service, $url){
        if(function_exists('curl_version')) {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_USERAGENT, 'shareCount/1.1 by abemedia');
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1);
            $data = curl_exec($ch);
            curl_close($ch);
        }
        else {
            $data = @file_get_contents($url);
        }

        $count = 0;
        if ($data) {
            switch($service) {
            case "facebook":
                $data = json_decode($data);
                $count = (is_array($data) ? $data[0]->total_count : $data->total_count);
                break;
            case "google":
                preg_match( '/window\.__SSR = {c: ([\d]+)/', $data, $matches );
                if(isset($matches[0])) $count = str_replace( 'window.__SSR = {c: ', '', $matches[0] );
                break;
            case "pinterest":
                $data = substr( $data, 13, -1);
            case "linkedin":
            case "twitter":
                $data = json_decode($data);
                $count = $data->count;
                break;
            case "stumbleupon":
                $data = json_decode($data);
                $count = $data->result->views;
                break;
            case "delicious":
                $data = json_decode($data);
                $count = $data[0]->total_posts;
                break;
            case "reddit":
                $data = json_decode($data);
                foreach($data->data->children as $child) {
                    $ups+= (int) $child->data->ups;
                    $downs+= (int) $child->data->downs;
                }
                $count = $ups - $downs;
                break;
            case "buffer":
                $data = json_decode($data);
                $count = $data->shares;
                break;
            case "vk":
                $data = preg_match('/^VK.Share.count\(\d+,\s+(\d+)\);$/i', $data, $matches);
                $count = $matches[1];
                break;
            default:
                // kill the script if trying to fetch from a provider that doesn't exist
                die("Error: Service not found");
            }
            $count = (int) $count;
            $this->data->shares->total += $count;
            $this->data->shares->$service = $count;
        } 
        return;
    }

    // Get data and return it. If cache is active check for cached data and create it if unsuccessful.
    private function getData() {
        if($this->cache) $key = md5($this->url) . '.' . ($this->format == 'jsonp' ? 'json' : $this->format);
        switch($this->cache) {
            case 'memcache':
                if(!function_exists('memcache_connect')) 
                { 
                    die('Memcache isn\'t installed'); 
                } 
                else
                {
                    $memcache = new Memcache;
                    $memcache->addServer($this->config->cache_server, $this->config->cache_port, $this->config->cache_persistent);
                    if(!$memcache->connect($this->config->cache_server, $this->config->cache_port)) 
                    { 
                        die('Couldn\'t connect to Memcache host'); 
                    } 
                    $data = $memcache->get($key);
                    if ($data === false) {
                        $data = $this->getShares();
                        $memcache->set($key, $data, $this->cache_time);
                    }
                }
                break;
            case 'apc':
                if (apc_exists($key)) {
                    $data = apc_fetch($key);
                }
                else {
                    $data = $this->getShares();
                    apc_store($key, $data, $this->cache_time);
                }
                break;
            case 'file': 
                $data = $this->getCacheFile($key);
                break;
            default:
                $data = $this->getShares();
        }
        // if the format is JSONP wrap in callback function
        if($this->format == 'jsonp') $data = $this->callback . '(' . $data . ')';

        return $data;
    }

    // get cache file - create if doesn't exist
    private function getCacheFile($key) {
        if (!file_exists($this->cache_directory)) {
            mkdir($this->cache_directory, 0777, true);
        }
        $file = $this->cache_directory . $key;
        $file_created = ((@file_exists($file))) ? @filemtime($file) : 0;
        @clearstatcache();
        if (time() - $this->cache_time < $file_created) {
            return file_get_contents($file);
        }
        $data = $this->getShares();
        $fp = @fopen($file, 'w'); 
        @fwrite($fp, $data);
        @fclose($fp);
        return $data;
    }

    // Delete expired file cache. Use "kill" parameter to also flush the memory and delete all cache files.
    public function cleanCache($kill = null) {
        // flush memcache
        if($kill) {
            switch($this->cache) {
                case 'memcache':
                    $memcache = new Memcache;
                    $memcache->flush();
                    break;
                case 'apc':
                    apc_clear_cache();
                    apc_clear_cache('user');
                    apc_clear_cache('opcode');
                    break;
            }
        }
        // delete cache files
        if ($handle = @opendir($this->cache_directory)) {
            while (false !== ($file = @readdir($handle))) {
                if ($file != '.' and $file != '..') {
                    $file_created = ((@file_exists($file))) ? @filemtime($file) : 0;
                    if (time() - $this->cache_time < $file_created or $kill) {
                        echo $file . ' deleted.<br>';
                        @unlink($this->cache_directory . '/' . $file);
                    }
                }
            }
            @closedir($handle);
        }
    }

    // output share counts as XML
    // functions adopted from http://www.sean-barton.co.uk/2009/03/turning-an-array-or-object-into-xml-using-php/
    public static function generateValidXmlFromObj(stdClass $obj, $node_block='nodes', $node_name='node') {
        $arr = get_object_vars($obj);
        return self::generateValidXmlFromArray($arr, $node_block, $node_name);
    }

    public static function generateValidXmlFromArray($array, $node_block='nodes', $node_name='node') {
        $xml = '<?xml version="1.0" encoding="UTF-8" ?>';
        $xml .= '<' . $node_block . '>';
        $xml .= self::generateXmlFromArray($array, $node_name);
        $xml .= '</' . $node_block . '>';
        return $xml;
    }

    private static function generateXmlFromArray($array, $node_name) {
        $xml = '';
        if (is_array($array) || is_object($array)) {
            foreach ($array as $key=>$value) {
                if (is_numeric($key)) {
                    $key = $node_name;
                }
                $xml .= '<' . $key . '>' . self::generateXmlFromArray($value, $node_name) . '</' . $key . '>';
            }
        } else {
            $xml = htmlspecialchars($array, ENT_QUOTES);
        }
        return $xml;
    }
}
</code>

对于facebook计数,此脚本使用

"https://api.facebook.com/method/links.getStats?format=json&urls=",

但在那种情况下它甚至根本没有显示facebook计数选项然后我将https替换为http并且facebook计数开始显示但始终保持为零。我也试过用graph.facebook.com/?id=更改它,但结果是一样的。

我从未使用PHP脚本,我对PHP一无所知,但我会根据您的建议尽力而为。

请指导我。任何帮助将深表感谢。谢谢!

2 个答案:

答案 0 :(得分:0)

请参阅https://developers.facebook.com/docs/graph-api/reference/v2.3/url

要查找股票编号,您必须解决以下问题:

https://graph.facebook.com/v2.3/?id=http%3A%2F%2Fwww.imdb.com%2Ftitle%2Ftt2015381%2F

您将收到URL这样的对象:

{
  "og_object": {
    "id": "10150298925420108", 
    "description": "Directed by James Gunn.  With Chris Pratt, Vin Diesel, Bradley Cooper, Zoe Saldana. A group of intergalactic criminals are forced to work together to stop a fanatical warrior from taking control of the universe.", 
    "title": "Guardians of the Galaxy (2014)", 
    "type": "video.movie", 
    "updated_time": "2015-04-22T02:19:13+0000", 
    "url": "http://www.imdb.com/title/tt2015381/"
  }, 
  "share": {
    "comment_count": 4, 
    "share_count": 109631
  }, 
  "id": "http://www.imdb.com/title/tt2015381/"
}

share_count字段包含您的信息。

<强> UPD

在函数getCount中,您必须改为编写

 case "facebook":
                $data = json_decode($data);
                $count = (is_array($data) ? $data[0]->total_count : $data->total_count);
                break;

类似的东西:

 case "facebook":
                $data = json_decode($data);
                $count = (is_array($data) ? $data["share"]->share_count : $data->share->share_count);
                break;

抱歉,我没有对此进行测试,因此您必须对其进行调试并找出哪种格式正确。

答案 1 :(得分:0)

如果您在Facebook中有应用程序,它非常简单,无需登录,您可以获取facebook计数器。

尝试一下:

https://graph.facebook.com/?id={URL}&fields=engagement&access_token={your-app_id}|{your-app_secret}

响应将类似于:

{
  "engagement": {
    "reaction_count": 36,
    "comment_count": 2,
    "share_count": 20,
    "comment_plugin_count": 3
  },
  "id": "https://www.example.com"
}

Ref:https://developers.facebook.com/docs/facebook-login/access-tokens