10

无论是使用 Facebook PHP SDK,还是仅仅使用 curl 加载数据$contents = file_get_contents("https://graph.facebook.com/$id?access_token=$accessToken"),响应都需要大约一秒钟的时间。

当我需要检查一堆 id 的数据时,这算得很慢。

在浏览器中,如果我输入一个 facebook 图表 url,我几乎可以立即得到结果,不到 PHP 所用时间的十分之一。

是什么导致了这个问题,我怎样才能让它像在任何浏览器中一样快?我知道浏览器可以做到。也必须有一种方法可以在 PHP 中使其快速。

IDEA:也许我需要在 cURL 中配置一些东西?

我试过的:

  • 使用 PHP SDK。一样慢。我首先尝试使用的原因file_get_contents()是因为我希望 PHP SDK 没有正确配置。
  • 使用setopt($ch, CURLOPT_SSL_VERIFYPEER, false);. 这并没有什么不同。回答后接受编辑:实际上,这与重用 curl 句柄一起使后续请求非常快。

编辑:这是我用来测量执行请求所需时间的代码的 pastebin:http: //pastebin.com/bEbuqq5g。我将以前说微秒的文本更正为秒。这就是产生类似于我在这个问题的评论中所写的结果的结果:Facebook 图表在 PHP 中非常慢。另请注意,即使访问令牌已过期,它们也会花费类似的缓慢时间,就像在我的 pastebin 示例中一样。

编辑 2: ssl 应该有部分问题。我尝试对http://graph.facebook.com/4(无 httpS)进行基准测试,结果三个请求需要 1.2 秒,而同样的,但使用 https 需要 2.2 秒。但这绝不是一个解决方案,因为对于任何需要访问令牌的请求,我必须使用 https。

4

5 回答 5

8

file_get_contents在 PHP 中可能会非常慢,因为它没有正确发送/处理标头,导致文件传输完成时 HTTP 连接没有正确关闭。我还阅读了有关 DNS 问题的信息,但我没有任何相关信息。

我强烈推荐的解决方案是使用 PHP SDK,它设计用于对 Facebook 进行 API 调用,或者使用cURL(SDK 使用)。使用 cURL,您可以真正配置请求的很多方面,因为它基本上是为进行这样的 API 调用而设计的。

PHP SDK 信息:https ://developers.facebook.com/docs/reference/php/

PHP SDK 源码:https ://github.com/facebook/facebook-php-sdk

如果您选择不使用 SDK,您可以查看他们如何在base_facebook.php中使用 cURL 。下面是一些示例代码,您可以使用 cURL 来获取:

function get_url($url)
{
   $ch = curl_init();
   curl_setopt($ch, CURLOPT_URL, $url); 
   curl_setopt($ch, CURLOPT_HEADER, FALSE);  // Return contents only
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);  // return results instead of outputting
   curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10) // Give up after connecting for 10 seconds 
   curl_setopt($ch, CURLOPT_TIMEOUT, 60);  // Only execute 60s at most
   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);  // Don't verify SSL cert
   $response = curl_exec($ch);
   curl_close($ch);
   return $response;
}

$contents = get_url("https://graph.facebook.com/$id?access_token=$accessToken");

该函数将在失败时返回 FALSE。

我看到你说你使用了 PHP SDK,但也许你没有设置 cURL。尝试安装或更新它,如果它仍然看起来很慢,你应该使用

curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_VERBOSE, TRUE);

并检查输出。

于 2012-08-22T12:46:54.847 回答
7

我想知道如果我在curl_exec()没有执行 a 的情况下执行两个后续调用会发生什么curl_close(),从而启用 HTTP Keep-Alive。

测试代码:

$ch = curl_init('https://graph.facebook.com/xxx');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

// FIRST REQUEST
curl_exec($ch);
print_r(curl_getinfo($ch));

// SECOND REQUEST
curl_exec($ch);
print_r(curl_getinfo($ch));

curl_close($ch);

下面是结果,显示了来自的部分输出curl_getinfo()

// FIRST REQUEST
[total_time] => 0.976259
[namelookup_time] => 0.008271
[connect_time] => 0.208543
[pretransfer_time] => 0.715296

// SECOND REQUEST
[total_time] => 0.253083
[namelookup_time] => 3.7E-5
[connect_time] => 3.7E-5
[pretransfer_time] => 3.9E-5

第一个请求很慢,几乎一秒钟,与您的经验相似。但是从第二次请求的时间(仅 0.25 秒)您可以看到 keep-alive 产生了多大的差异。

当然,您的浏览器也使用这种技术,在浏览器的新实例中加载页面将花费相当长的时间。

于 2012-08-27T10:20:48.733 回答
2

只是两个想法:

  1. 您是否已验证浏览器与 facebook 没有持久连接?浏览器没有缓存 DNS 查找(您可以尝试将 graph.facebook.net 添加到您的主机文件以排除 DNS)

  2. 您当然是从与浏览器相同的系统/环境中运行 php 代码(不是来自 vm,而不是来自另一台主机?另外,该 php 运行的调度优先级与您的浏览器相同?(相同的好级别等))

于 2012-08-28T16:03:03.850 回答
1

使 Graph API 调用“慢”的最大因素是——HTTP 连接。

通过调整一些参数或获得具有更好连接的服务器,可能会有一些改进。

但这很可能不会产生太大的影响,因为 HTTP 通常被认为是“慢”的,对此几乎没有什么可以做的。

当我需要检查一堆 id 的数据时,这算得很慢。

当然,要加快速度,最好的办法就是减少 HTTP 请求的数量。

如果您必须连续执行多个 Graph API 调用,请尝试将它们作为批处理请求来执行。这允许您查询数据的多个部分,同时只发出一个HTTP 请求。

于 2012-08-23T15:45:24.887 回答
0

这纯粹是一种猜测,但原因可能是 Facebook 使用了 SPDY 协议(不确定 API 是否属实)。PHP 无法使用 SPDY 协议加载页面。

于 2012-08-29T08:46:50.723 回答