Facebook PHP SDK — a simple guide!

53 Comments

Join the Conversation

Facebook PHP SDK App Integration

Now that we’ve installed the Facebook PHP SDK, let’s integrate it into a application. Once integrated, we’ll be able to use Facebook login and make requests like retrieving profile info, pictures and more.

Facebook Login Example

Although it’s common to see examples of Facebook Login being implemented in one PHP script, is best to use two separate PHP scripts for more separation and more control over the responses.

In this example, the PHP script that generates the login link is called /login.php. The callback URL that Facebook redirects the user to after login dialog is called /fb-callback.php.

Step 1: Initialize the PHP Facebook SDK

In your project’s root, create a file named login.php.

/login.php
<?php
// Pass session data over. Only needed if not already passed by another script like WordPress.
session_start();

// Include the required dependencies.
require_once( 'vendor/autoload.php' );

// Initialize the Facebook PHP SDK v5.
$fb = new Facebook\Facebook([
  'app_id'                => '{app-id}',
  'app_secret'            => '{app-secret}',
  'default_graph_version' => 'v2.10',
]);

$helper = $fb->getRedirectLoginHelper();

$permissions = ['email']; // Optional permissions
$loginUrl = $helper->getLoginUrl('https://example.com/fb-callback.php', $permissions);

echo '<a href="' . $loginUrl . '">Log in with Facebook!</a>';

Replace {app-id} and {app-secret} with the Facebook credentials provided when you created the your Facebook app.

Application Permissions

It’s important that you think about what permissions you’ll need for your site before your users start using it. If you ever need to update them, users will have to re-authorize the app. Once you have a list of permissions, pass them to the getLoginURL method as an array:

// Requested permissions - optional
$permissions = array(
    'email',
    'user_location',
    'user_birthday'
);

// Get login URL
$loginUrl = $helper->getLoginUrl($callback, $permissions);

If no permissions are provided, it’ll use Facebook’s default public_profile permission. Here’s a list of some common permissions:

User permissionDescription
public_profileGives access to a subset of a person’s public profile:

  • id
  • name
  • first_name
  • last_name
  • link
  • gender
  • locale
  • age_range
emailProvides access to the user’s primary email address in the email property on the user object.
user_locationProvides access to the user’s current city as the location property.
user_birthdayProvides access to the birthday.

See the full list of available permissions.

Step 2: Authenticate

Now that we have the login link, we need to build the script that handles the functionality of the login process (the page Facebook redirects after a user successfully logins to their Facebook account after click the login link above).

/fb-callback.php
<?php
// Pass session data over. Only needed if not already passed by another script like WordPress.
session_start();

// Include the required dependencies.
require_once( 'vendor/autoload.php' );

$fb = new Facebook\Facebook([
  'app_id' => '{app-id}',
  'app_secret' => '{app-secret}',
  'default_graph_version' => 'v2.10',
]);

$helper = $fb->getRedirectLoginHelper();

try {
  $accessToken = $helper->getAccessToken();
} catch(Facebook\Exceptions\FacebookResponseException $e) {
  // When Graph returns an error
  echo 'Graph returned an error: ' . $e->getMessage();
  exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
  // When validation fails or other local issues
  echo 'Facebook SDK returned an error: ' . $e->getMessage();
  exit;
}

if (! isset($accessToken)) {
  if ($helper->getError()) {
    header('HTTP/1.0 401 Unauthorized');
    echo "Error: " . $helper->getError() . "\n";
    echo "Error Code: " . $helper->getErrorCode() . "\n";
    echo "Error Reason: " . $helper->getErrorReason() . "\n";
    echo "Error Description: " . $helper->getErrorDescription() . "\n";
  } else {
    header('HTTP/1.0 400 Bad Request');
    echo 'Bad request';
  }
  exit;
}

// Logged in
echo '<h3>Access Token</h3>';
var_dump($accessToken->getValue());

// The OAuth 2.0 client handler helps us manage access tokens
$oAuth2Client = $fb->getOAuth2Client();

// Get the access token metadata from /debug_token
$tokenMetadata = $oAuth2Client->debugToken($accessToken);
echo '<h3>Metadata</h3>';
var_dump($tokenMetadata);

// Validation (these will throw FacebookSDKException's when they fail)
$tokenMetadata->validateAppId($config['app_id']);
// If you know the user ID this access token belongs to, you can validate it here
//$tokenMetadata->validateUserId('123');
$tokenMetadata->validateExpiration();

if (! $accessToken->isLongLived()) {
  // Exchanges a short-lived access token for a long-lived one
  try {
    $accessToken = $oAuth2Client->getLongLivedAccessToken($accessToken);
  } catch (Facebook\Exceptions\FacebookSDKException $e) {
    echo "<p>Error getting long-lived access token: " . $e->getMessage() . "</p>\n\n";
    exit;
  }

  echo '<h3>Long-lived</h3>';
  var_dump($accessToken->getValue());
}

$_SESSION['fb_access_token'] = (string) $accessToken;

// User is logged in with a long-lived access token.
// You can redirect them to a members-only page.
//header('Location: https://example.com/members.php');

Step 3: Making Requests

Once we’ve successfully logged in, we can begin making calls to the Graph API. The Graph API only supports the GET, POST and DELETE HTTP verbs. In v5, each of these verbs get their own corresponding method.

// GET request.
$res = $fb->get('/me', '{access-token}');

// POST request.
$res = $fb->post('/me/feed', $data, '{access-token}');

// DELETE request.
$res = $fb->delete('/123', $data, '{access-token}');

If you don’t want to have to send in '{access-token}' with every method call in v5, you can use the setDefaultAccessToken() method.

$fb->setDefaultAccessToken('{access-token}');

# These will fall back to the default access token
$res = $fb->get('/me');
$res = $fb->post('/me/feed', $data);
$res = $fb->delete('/123', $data);

The responses from the get(), post() & delete() methods return a FacebookResponse entity which is an object that represents an HTTP response from the Graph API.

If all you want is a plain-old PHP array, you call the getDecodedBody() method on the FacebookResponse entity.

// Response example.
$res = $fb->get('/me');

var_dump($res->getDecodedBody());

// array(10) { ...

v5 can return the response data as a collection which can be really handy for performing actions on the response data.

I won’t get into too much detail with this, but the collections come in the form of GraphObjects and they can be obtained from the FacebookResponse entity using the getGraphObject() method.

// Response example.
$res = $fb->get('/me');

$node = $res->getGraphObject();

var_dump($node->getProperty('id'));
// string(3) "123"

// Functional-style!
$node->map(function($value, $key) {
  // . . .
});
Handling Exceptions

Sometimes the Graph API will return an error response. Sad face. In v5 a FacebookSDKException will be thrown if something goes wrong.

try {
  $res = $fb->get('/123');
} catch (Facebook\Exceptions\FacebookSDKException $e) {
  echo $e->getMessage();
  exit;
}

There are more than just the base FacebookSDKException in v5 but I won’t get into too much detail on the other types of exceptions. But know that the other exceptions extend from FacebookSDKException so you can be assured that whenever you catch FacebookSDKException, you’re catching any of the extended exceptions as well.

The FacebookSDKException is not limited to error responses from the Graph API. There are other instances when a base FacebookSDKException might be thrown in v5. Some examples include a signed request fails to validate, a file you want to upload cannot be found and so on.


Facebook PHP SDK Examples

Once you have a session, you’ll have access to the all-powerful API. You can use this API to retrieve user’s information, implement one-click registrations, logins, publish to profiles and more.
Check out the examples below to get the Facebook SDK PHP library (v5.x) integrated quickly.

Log a User Out

It’s usually not a common practice to make use of the log out feature within the PHP SDK as this will log a user out of Facebook completely, not just your app. So unless you’ve got a specific edge case where you need to do this, it’s not recommended that you use it.

That said, you can log a user out of Facebook in v5 using the getLogoutUrl() method on the FacebookRedirectLoginHelper.

$fb = new Facebook\Facebook([/* */]);

$helper = $fb->getRedirectLoginHelper();

$logoutUrl = $helper->getLogoutUrl('{access-token}', 'http://example.com');
echo '<a href="' . $logoutUrl . '">Logout of Facebook!</a>';

Where http://example.com is the URL the user should be redirected to after logging out.

Retrieve User’s Profile Information

<?php
# Facebook PHP SDK v5: Retrieve User's Profile Information

$res = $fb->get( '/me' );

$user = $res->getGraphObject();

echo $user->getProperty( 'id' );
// 123
Note: Fields that aren’t set to public must be be requested with an access token with the relevant ‘Extended Profile‘ permissions.

For more information and a full list of possible fields returned, see https://developers.facebook.com/docs/graph-api/reference/v2.0/user.

Get User’s Profile Picture

<?php
# Facebook PHP SDK v5: Get User's Profile Picture

$res = $fb->get( '/me/picture?type=large&amp;amp;redirect=false' );

$picture = $res->getGraphObject();

var_dump( $picture );

You can use a list of modifiers to specify the type (e.g. square, small, normal, large), size and whether to send as a JSON array or output as an image. See a list of the available modifiers below:

Modifiers
NameDescriptionType
redirectThe picture edge is a special case, as when requested, it will by default return the picture itself and not a JSON response. To return a JSON response, you need to set redirect=false as a request attribute. This is how to return the fields below.bool
typeYou use this to get a pre-specified size of picture.enum{square,small,normal,large}
heightRestrict the picture height to this size in pixels.int
widthRestrict the picture width to this size in pixels. When height and width are both used, the image will be scaled as close to the dimensions as possible and then cropped down.int

For more information and a full list of possible fields returned, see https://developers.facebook.com/docs/graph-api/reference/v2.3/user/picture

Publish to User’s Timeline

A user access token with publish_actions permission can be used to publish new posts.

<?php
# Facebook PHP SDK v5: Publish to User's Timeline

$res = $fb->post( '/me/feed', array(
  'message' => 'I love articles on benmarshall.me!'
));

$post = $res->getGraphObject();

var_dump( $post );

For more information and a full list of additional parameters, see https://developers.facebook.com/docs/graph-api/reference/v2.3/user/feed

Retrieve User’s Timeline

A user access token with read_stream permission is required and only posts whose authors have also granted read_stream permission to the app will be shown.

<?php
# Facebook PHP SDK v5: Retrieve User's Timeline

$res = $fb->get( '/me/feed' );

$feed = $res->getGraphObject();

var_dump( $feed );

There are other edges which provide filtered versions of this edge:

  • /{user-id}/links shows only the links that were published by this person.
  • /{user-id}/posts shows only the posts that were published by this person.
  • /{user-id}/statuses shows only the status update posts that were published by this person.
  • /{user-id}/tagged shows only the posts that this person was tagged in.

All of these derivative edges share the exact same reading structure, however /feed should be used for all publishing purposes.

For more information, see https://developers.facebook.com/docs/graph-api/reference/v2.3/user/feed.

Upload a File

$fb = new Facebook\Facebook([/* . . . */]);

$data = [
  'source' => $fb->fileToUpload('/path/to/photo.jpg'),
  'message' => 'My file!',
  ];

$response = $fb->post('/me/photos', $data, '{access-token}');

Upload a Video

If you’re uploading a video, that requires using the videoToUpload() method.

$fb = new Facebook\Facebook([/* . . . */]);

$data = [
  'source'      => $fb->videoToUpload('/path/to/video.mp4'),
  'title'       => 'My video',
  'description' => 'My amazing video!',
  ];

$response = $fb->post('/me/videos', $data, '{access-token}');

For more information, see https://developers.facebook.com/docs/graph-api/reference/video.


About Access Tokens

Access tokens are represented with an AccessToken entity. There are two ways to get the access token as a plain-old string.

// These statements are equivalent
echo (string) $accessToken;
echo $accessToken->getValue();

Having AccessToken entities gives us some more power when handling access tokens. For example, you can do a strict check to ensure that you definitely have an access token.

if ($accessToken instanceof Facebook\Authentication\AccessToken) {
  // Logged in.
}

You can also typehint function & method arguments that take an access token.

function (Facebook\Authentication\AccessToken $token) {
  // . . .
}

There are also a number of handy methods on the AccessToken entity.

// Returns expiration as a DateTime entity
$expiresAt = $accessToken->getExpiresAt();

// Returns boolean
$expired = $accessToken->isExpired();

// Returns boolean
$isLong = $accessToken->isLongLived();

// Returns boolean
$isAppToken = $accessToken->isAppAccessToken();

// Returns the app secret proof as a string
// This is used to sign requests to the Graph API
// All requests made using the PHP SDK are
// signed automatically for you
$proof = $accessToken->getAppSecretProof('{app-secret}');

Getting a Long-Lived (Extended) Access Token

You can exchange a short-lived access token for a long-lived access token by generating an instance of the OAuth2Client() by using the getOAuth2Client() method on the Facebook super service.

$cilent = $fb->getOAuth2Client();

try {
  // Returns a long-lived access token
  $accessToken = $cilent->getLongLivedAccessToken('{short-lived-token}');
} catch(Facebook\Exceptions\FacebookSDKException $e) {
  // There was an error communicating with Graph
  echo $e->getMessage();
  exit;
}

The OAuth2Client has a number of cool features like a debugToken() method that returns an AccessTokenMetadata entity with information about the access token to be used to validate against or debug.

try {
  $metaData = $cilent->debugToken('{access-token}');
} catch(Facebook\Exceptions\FacebookSDKException $e) {
  // There was an error communicating with Graph
  echo $e->getMessage();
  exit;
}

var_dump($metaData->getAppId());
var_dump($metaData->getApplication());
var_dump($metaData->isError());
var_dump($metaData->getIssuedAt());

// These all throw a FacebookSDKException
$metaData->validateAppId('{app-id}');
$metaData->validateUserId('{user-id}');
$metaData->validateExpiration();

Access Tokens from the JavaScript SDK

The JavaScript SDK has a really great UI for Facebook Login. It is a better user experience to use the JavaScript SDK to authenticate a user into your app than it is to use the PHP SDK’s OAuth 2.0 flow with the FacebookRedirectLoginHelper.

By default the JavaScript SDK won’t store any info about the user on your domain unless you explicitly tell it to. So in your FB.init() method, you’ll need to enable the cookie option with {cookie:true}. This tells the JavaScript SDK to set a cookie on your domain that contains a signed request with information about the authenticated user.

FB.init({
  appId   : '{app-id}',
  cookie  : true,
  version : 'v2.3'
});

If an access token exists in the signed request that was set by the JavaScript SDK, it can be obtained using the FacebookJavaScriptHelper. An instance of this helper can be generated from the Facebook super service by using the getJavaScriptHelper() method.

$fb = new Facebook\Facebook([/* . . . */]);

$helper = $fb->getJavaScriptHelper();
try {
  $accessToken = $helper->getAccessToken();
} catch(Facebook\Exceptions\FacebookSDKException $e) {
  // There was an error communicating with Graph
  // Or there was a problem validating the signed request
  echo $e->getMessage();
  exit;
}

if ($accessToken) {
  echo 'Successfully logged in!';
}

For more information on the Graph API, see https://developers.facebook.com/docs/graph-api/reference/v2.0/. This has a full list of root nodes of the Graph API, with links to the reference docs for each.

If you have any questions or problems, post your comments below. I’ll try to keep this post updated with the latest information and add more API calls later on. Have fun coding!


  • Update (March 9, 2018): Minor updates and more simplified instructions provided for the latest version of the Facebook PHP SDK.
  • Update (April 29, 2015): Facebook PHP SDK 5.x? What happened to 4.1 you ask? The Facebook PHP SDK will start following SemVer starting with v5.0. Before the decision to adopt SemVer, the official Facebook PHP SDK was going to be released as v4.1. But now v4.1 is just an alias to v5.0.0. So any references to 4.1 can be safely aliased to v5.0.0. For more information, see F8 2015 Facebook Developer Conference and the new PHP SDK.

Comments

  1. Hussein
    at 10:46 pm

    got this error “Undefined variable: config fb-callback.php”
    after doing search and found this
    The variable $config[‘app_id’] is undefined, use the app id directly:

    $tokenMetadata->validateAppId(YOU_APP_ID);

    now the error doesnt appear.
    Hope it might usefull to anyone

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

All comments are held for moderation. I'll publish all comments that are on topic and not rude. You'll even get little stars if you do an extra good job.

You may write comments in Markdown. This is the best way to post any code, inline like `<div>this</div>` or multiline blocks within triple backtick fences (```) with double new lines before and after.

Want to tell me something privately, like pointing out a typo or stuff like that? Contact Me.

%d bloggers like this: