8
votes

Designing my first app against the Graph API, using version 2.1.2 of the Facebook supplied PHP library. Trying to maximize performance, etc out of the box and want to batch a few calls together into one call, but can't find anything in the documentation... I am sure I must be missing something simple, but am stumped.

I'd like to turn these calls (just an example) into a single batched call:

$me     = $facebook->api('/me', $params);
$groups = $facebook->api('/me/groups', $params);
5

5 Answers

2
votes

Facebook recommends using FQL for this; http://developers.facebook.com/docs/guides/performance by combining your requests in a (nested) query.

Their own example:

$friends_locations = $facebook->api_client->fql_query(
    'SELECT hometown_location from user where uid in ' .
    '(SELECT uid2 from friend where uid1=' . $user_id . ')');

If your requests aren't dependant on eachother you can use fql.multiquery

50
votes

Just an update for the new graph Batch API: You can also execute that as follows:

// Save your method calls into an array
$queries = array(
    array('method' => 'GET', 'relative_url' => '/me'),
    array('method' => 'GET', 'relative_url' => '/me/groups')
);
// POST your queries to the batch endpoint on the graph.
$batchResponse = $facebook->api('?batch='.json_encode($queries), 'POST');

// Return values are indexed in order of the original array, content is in ['body'] as a JSON
// string. Decode for use as a PHP array.

$user_profile = json_decode($batchResponse[0]['body'], true);
$user_groups = json_decode($batchResponse[1]['body'], true);

That should do the trick.

2
votes

I have given example for batch calls of fql queries. It might help someone.

//$current_user=facebook id

 $query1="SELECT uid, name FROM user WHERE is_app_user=1 AND uid IN (SELECT uid2 FROM friend WHERE uid1 = $current_user)";
 $query2="SELECT uid, name, work_history FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1 = $current_user )";
 $query3="SELECT uid, name, work, education FROM user WHERE uid = $current_user";
 $queries = array(
           array('method'=>'GET', 'relative_url'=>'method/fql.query?query='.str_replace(' ','+',$query1)),
           array('method'=>'GET', 'relative_url'=>'method/fql.query?query='.str_replace(' ','+',$query2)),
           array('method'=>'GET', 'relative_url'=>'method/fql.query?query='.str_replace(' ','+',$query3))
            );

            $objs = $facebook->api('/?batch='.json_encode($queries), 'POST');

$objs gets json array of whole result of thre queries.

And it is saving time a lot. This 3 queries individually takes total 9 seconds. With multiquery it takes 7 seconds. And with batch request it takes 3.6 seconds.

0
votes

I added a null check to mine:

$friends_locations = $facebook->api_client->fql_query('SELECT name,birthday_date, pic_square FROM user WHERE uid in (SELECT uid2 from friend where uid1='. $user_id .') and birthday_date > 0');
0
votes

For Batch API, you could use the Facebook Batch PHP class.

Here is the code you would use:

<?php

// Facebook Batch Requests PHP Class
// by Gokhan Ozturk <gokhanozturk at gmail dot com> @ Nov 17, 2011
// Original Article: http://blog.pclabs.com.tr/gokhanozturk/2011/11/17/facebook-batch-requests-php-class/

class facebook_batch {
protected $requests = array();
protected $responses = null;
protected $cur = 1;
protected $map = array();

const MAX_NUMBER_OF_REQUESTS = 20;

public function add($path, $method = 'GET', $params = array(), $extra = array()) {
if(count($this->requests) > self::MAX_NUMBER_OF_REQUESTS) return false;

$path = trim($path, '/ ');

$body = http_build_query($params);
$body = urldecode($body);

if(strtolower($method) == 'get') {
if(count($params) > 0) {
$path .= "?" . $body;
$body = "";
}
}

$key = $this->cur++;
$this->requests[$key] = array_merge(array('relative_url' => $path, 'method' => $method, 'body' => $body), $extra);

return intval($key);
}

public function remove($key) {
unset($this->requests[$key]);
}

public function execute() {
global $facebook;

$i = 0;
foreach($this->requests as $k => $r) {
$this->map[$k] = $i++;
}

$batch = json_encode(array_values($this->requests));
$params = array('batch' => $batch);

$this->responses = $facebook->api('/', 'POST', $params);
}

public function response($key) {
if(! $this->responses) $this->execute();

$rkey = $this->map[intval($key)];
$resp = $this->responses[intval($rkey)];

if($resp['code'] != 200) return false;
return json_decode($resp['body'], true);
}

public function getRequests() {
return $this->requests;
}
}

?>