我正在用PHP开发一个Facebook应用程序,该应用程序获取用户朋友的大量位置信息。随着用户朋友数量的增加,应用程序变得越来越慢。但是我检索到的朋友信息越多,结果就越准确。
我尝试使用以下方法来加快查询速度:
$facebook->api('/locations?ids=uid1,uid2,uid3,...')
我将其与批处理请求一起使用:
$batched_request = array(
array('method' => 'GET', 'relative_url' => '/locations?ids=uid1,uid2,uid3,...'),
array('method' => 'GET', 'relative_url' => '/locations?ids=uid11,uid12,uid13,...'),
array('method' => 'GET', 'relative_url' => '/locations?ids=uid21,uid22,uid23,...'),
...
);
$batch = $facebook->api('/?batch='.json_encode($batched_request), 'POST');
但是,从用户的 100 个随机好友中获取位置信息仍然至少需要 20 秒。
实际使用的代码
这部分很好。只需几秒钟即可完成。
$number_of_friends = "100"; // Set the maximum number of friends from which their location information is retrieved
$number_of_friends_per_request = 10; // Set the number of friends per request in the batch
$access_token = $facebook->getAccessToken();
// This is the excerpt of another batched request to get the friend ids
$request = '[{"method":"POST","relative_url":"method/fql.query?query=SELECT+uid,+name+FROM+user+WHERE+uid+IN(SELECT+uid2+FROM+friend+WHERE+uid1+=+me()+order+by+rand()+limit+'.$number_of_friends.')"}]';
$post_url = "https://graph.facebook.com/" . "?batch=" . urlencode($request) . "&access_token=" . $access_token . "&method=post";
$post = file_get_contents($post_url);
$decoded_response = json_decode($post, true);
$friends_json = $decoded_response[0]['body'];
$friends_data = json_decode($friends_json, true);
if (is_array($friends_data)) {
foreach ($friends_data as $friend) {
$selected_friend_ids[] = number_format($friend["uid"], 0, '.', ''); // Since there are exceptionally large id numbers
}
}
但这是有问题的。收到Facebook的回复需要太长时间。
// Retrieve the locations of the user's friends using batched request
$i = 0;
$batched_request = array();
while ($i < ($number_of_friends/$number_of_friends_per_request)) {
$i++;
$friend_ids_variable_name = 'friend_ids_part_'.$i;
$$friend_ids_variable_name = array_slice($selected_friend_ids, ($i-1)*$number_of_friends_per_request, $number_of_friends_per_request);
if (!empty($$friend_ids_variable_name)) {
$api_string_ids_variable_name = 'api_string_ids_'.$i;
$$api_string_ids_variable_name = implode(',', $$friend_ids_variable_name);
$batched_request[] = array('method' => 'GET', 'relative_url' => '/locations?ids='.$$api_string_ids_variable_name);
}
}
$batch = $facebook->api('/?batch='.json_encode($batched_request), 'POST');
foreach ($batch as $batch_item) {
$body = $batch_item["body"];
$partial_friends_locations = json_decode($body, true);
foreach ($partial_friends_locations as $friend_id => $friend_locations_data) {
$friend_locations = $friend_locations_data["data"];
foreach ($friend_locations as $friend_location) {
// Process location information...
}
}
}
}
有没有办法使上述请求更快?我放置了一些代码来检查请求的响应时间,它非常慢。
- 对于 100 个朋友,平均需要> 20 秒。
- 对于 200 个朋友,平均需要> 40 秒。
- 对于 400 个朋友,平均需要> 80 秒,我有时会收到一条错误消息:"错误代码:1 条消息:发生未知错误"
为了使事情更快,这意味着:
- 在更短的时间内获得相同数量的信息,或者
- 在相同的时间内获取更多信息。
为什么要为批处理请求而烦恼?可以使用单个 FQL 多查询实现所有功能:
{
"my_friends":
"SELECT uid, name FROM user WHERE uid IN
(SELECT uid2 FROM friend WHERE uid1 = me() ORDER BY rand() LIMIT 100)",
"their_locations":
"SELECT page_id, tagged_uids FROM location_post WHERE tagged_uids IN
(SELECT uid FROM #my_friends)",
"those_places":
"SELECT page_id, name, location FROM page WHERE page_id IN
(SELECT page_id FROM #their_locations"
}
在 API 资源管理器中,这对我来说在 800-1200 毫秒范围内运行。
另一个问题:为什么你安装了 PHP SDK,但没有使用它来进行这些查询?
我也
注意到Facebook的API响应时间很慢。 我实际上还没有开发过Facebook应用程序,但也许我在处理Facebook方面的一些经验(如按钮和评论/分享按钮)将帮助您:
我的建议是通过javascript将你的页面与异步api调用捆绑在一起,以获取数据。 这样,页面可以为您的用户快速加载,然后在后台加载Facebook数据。 你可以使用像jquery这样的库相对容易地完成此操作。 从本质上讲,您将断开运行以将数据处理到另一个文件中的代码块,然后使用 jquery 调用运行该文件。
这是第一部分。 第二部分可能又是一个小技巧,允许用户感知更快的应用程序加载时间。 始终先加载前 100 个好友并显示结果数据,然后再次查询(再次使用异步调用),以完成对其余用户好友的查询。
同样,这是从更一般的角度来看的,但希望它会有所帮助!