Facebook Connect with PHP SDK v4

Since my last post about Facebook connect back in 2012, Facebook still remains the top user registration source, well at-least in my imagination! And recently they have released PHP SDK version 4 with significant changes. So, today we are going to talk about it a bit and try and create a working Facebook Sign-Up page using their SDK v4. The Facebook SDK 4 version requires PHP 5.4 or greater, so if you are still on prior PHP versions, you might face problems with this SDK, this is mostly because of new Autoloader in PHP Library utilized by all PHP packages these days. So either you have to upgrade your PHP or use earlier SDK version for time being.

Connect to Facebook

Despite all the changes in the SDK, the process of implementation is still same and easy. You can download Facebook SDK 4.0 here, extract the package anywhere within your project folder, and include autoload.php in your project, take a look at a working example below :
PHP
12345678910111213141516171819202122232425262728293031323334353637383940414243
<?php
session_start(); //Session should be active

$app_id				= '453598374';  //Facebook App ID
$app_secret 		= '934729857443983230943'; //Facebook App Secret
$required_scope 	= 'public_profile, publish_actions, email'; //Permissions required
$redirect_url 		= 'http://localhost/facebook-connect/'; //FB redirects to this page with a code

//include autoload.php from SDK folder, just point to the file like this:
require_once __DIR__ . "/facebook-php-sdk-v4-4.0-dev/autoload.php";

//import required class to the current scope
use Facebook\FacebookSession;
use Facebook\FacebookRequest;
use Facebook\GraphUser;
use Facebook\FacebookRedirectLoginHelper;

FacebookSession::setDefaultApplication($app_id , $app_secret);
$helper = new FacebookRedirectLoginHelper($redirect_url);

//try to get current user session
try {
  $session = $helper->getSessionFromRedirect();
} catch(FacebookRequestException $ex) {
	die(" Error : " . $ex->getMessage());
} catch(\Exception $ex) {
	die(" Error : " . $ex->getMessage());
}

if ($session){ //if we have the FB session
	$user_profile = (new FacebookRequest($session, 'GET', '/me'))->execute()->getGraphObject(GraphUser::className());
	//do stuff below, save user info to database etc.
	
	echo '<pre>';
	print_r($user_profile); //Or just print all user details
	echo '</pre>';
	
}else{ 

	//display login url 
	$login_url = $helper->getLoginUrl( array( 'scope' => $required_scope ) );
	echo '<a href="'.$login_url.'">Login with Facebook</a>'; 
}
This code basically connects to Facebook using their PHP SDK 4, and prints available details about the user on the browser. It asks for three user permissions: public_profile, publish_actions and email. You can guess what first one is, the second one publish_actions permission is required to publish texts or upload images on user wall, but you can remove it if not required by your application, third one is email permission which is required by most site. More info about user permissions can be found here.

Fetch User Details

Once the user details are available in $user_profile variable, you should know what to do next with that information. But the user data is enclosed in a protected GraphUser object, and if you try to access it usual way, you will encounter Cannot access protected property Facebook\GraphUser error. Here’s a sample of GraphUser object for the current user.
123456789101112131415161718192021222324
Facebook\GraphUser Object
(
    [backingData:protected] => Array
        (
            [id] => 102417138XXXX
            [birthday] => 03/04/1990
            [first_name] => Fred
            [email] => [email protected]
            [gender] => male
            [last_name] => TestMan
            [link] => http://www.facebook.com/102417138XXXX
            [location] => stdClass Object
                (
                    [id] => 102417138XXXX
                    [name] => Middle Earth, Maryland
                )

            [locale] => en_US
            [name] => Fred TestMan
            [timezone] => 5.0
            [updated_time] => 2013-01-26T20:22:46+0000
            [verified] => 1
        )
)
To access this data, you can use getProperty() method and selecting the desired key, for example :
PHP
12345678
if ($session){ //if we have the FB session
	$user_profile = (new FacebookRequest($session, 'GET', '/me'))->execute()->getGraphObject(GraphUser::className());
	
	echo $user_profile->getProperty('id'); 
	echo $user_profile->getProperty('name'); 
	echo $user_profile->getProperty('first_name'); 
	echo $user_profile->getProperty('last_name'); 	
}
The data you can access depends on the permissions a user has granted to your app along with the data a user has chosen to share with apps. If user does not share info such as email, it will come-out empty, so make sure to check any empty values before deploying. The most commonly used terms such as ID, name, first_name etc. can also be accessed directly like so:
PHP
123456789101112
if ($session){ //if we have the FB session
	$user_profile = (new FacebookRequest($session, 'GET', '/me'))->execute()->getGraphObject(GraphUser::className());
	
	echo $user_profile->getId(); 
	echo $user_profile->getName(); 
	echo $user_profile->getFirstName(); 
	echo $user_profile->getMiddleName(); 
	echo $user_profile->getLastName();
	echo $user_profile->getLink();
	echo $user_profile->getBirthday();
	echo $user_profile->getLocation();
}
If you want to convert these objects and access them as associative array, without protected property error, just add asArray() method. Something like this:
PHP
12345678
if ($session){ //if we have the FB session
	$user_profile = (new FacebookRequest($session, 'GET', '/me'))->execute()->getGraphObject(GraphUser::className())->asArray();
	
	echo $user_profile["id"]; 
	echo $user_profile["name"]; 
	echo $user_profile["first_name"];
	echo $user_profile["last_name"];
}

Upload an image on User Wall

You don’t always want to get user data from Facebook, sometimes you also want to post pictures on user wall. Once you acquire the user session, this posting image is pretty easy, but you must have requested the publish_actions permission when logging in the user for this to work.
PHP
1234567
if ($session){ //if we have the FB session
	
	$image = "/home/images/image_name.jpg";
	$post_data = array('source' => '@'.$image, 'message' => 'This is test Message');
	$response = (new FacebookRequest( $session, 'POST', '/me/photos', $post_data ))->execute()->getGraphObject();

}

Post link on user Wall

Posting link work similar way, publish_actions scope is required here too.
PHP
12345
if ($session){ //if we have the FB session		
	$post_data = array( 'link' => 'www.example.com', 'message' => 'This is test Message' );
	$response = (new FacebookRequest( $session, 'POST', '/me/feed', $post_data ))->execute()->getGraphObject();

}

Check Granted Permission

Sometimes you want to check particular permission before performing a task. For example before posting an image you might want to check whether a user has granted “publish_action” permission, because without this permission your application will run into nasty error. So, in that case you can use something like this:
PHP
123456789101112131415
if ($session){ //if we have the FB session		
	$user_permissions = (new FacebookRequest($session, 'GET', '/me/permissions'))->execute()->getGraphObject(GraphUser::className())->asArray();

	//check publish stream permission
	$found_permission = false;
	foreach($user_permissions as $key => $val){			
		if($val->permission == 'publish_actions'){
			$found_permission = true;
		}
	}
	
	if($found_permission){
		//do your stuff
	}
}
Facebook graph has an endpoint “GET/{user-id}/permissions” to retrieve a list of granted permissions from user as JSON string, we can just loop through the list to check whether user has granted the permission we need.

Conclusion

That’s it! For the sake of my old post, I’ve tried to cover most common aspects about the new Facebook PHP SDK v4, I hope this article could shed some light, even though their online documentation is fairly elaborated. Don’t forget to checkout the Demo and downloadable file, which already contains Facebook SDK v4 package. All the best! Download Demo
  • 47 Comments

    Add Comment
    • Arvind kumar yadav
      thank's so much it is very useful.
    • TheRitz
      I get a problem when a Facebook user who uses yahoo email address, user data is successfully able to but can not enter into the database. different from Facebok users that use gmail email. please give a solution
    • Lsoltero
      any chance you could update the example for version 5.1? https://github.com/facebook/facebook-php-sdk-v4/releases
    • Bharati bane
      [06-Sep-2015 06:51:47 Etc/GMT] PHP Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 1550439321 bytes) in /home/bspunmlu/public_html/muslimshadi.info/index.html/index.html/fb/facebook/autoload.php on line 70 i have above error while using this code what i do..?
    • Felipe
      !======= E-MAIL DOES NOT APPEAR ON THE RESULT [SOLVED] =========! hey everyone, I'll just start saying that I've used this tutorial and from far it was THE BEST on the web about it! I had a problem with the e-mail, at first I had only the name and facebook_id, but then I've replaced: This: $user_profile = (new FacebookRequest($session, 'GET', '/me'))->execute()->getGraphObject(GraphUser::className()); For this: $user_profile = (new FacebookRequest($session, 'GET', '/me?fields=id,email,first_name,gender,last_name,link,locale,name,timezone,updated_time,verified'))->execute()->getGraphObject(GraphUser::className()); But then I had all the info but not the e-mail =(( So I've noticed that on the top of the tutorial it was this code: $required_scope = 'public_profile, publish_actions,email'; //Permissions required And realized that on the Download Material there is not the e-mail , so just add the e-mail and it is done :D Bye bye and congrats for the tutorial!
    • Sven
      If you ONLY get ID and NAME. You must edit "/me": "the new Facebook API v2.4 changed the way the response is being sent. Now you need to specify in the request url which fields you want the API to return so /me becomes /me?fields=email,name,etc..." working example: $user_profile = (new FacebookRequest($session, 'GET', '/me?fields=id,email,first_name,gender,last_name,link,locale,name,timezone,updated_time,verified'))->execute()->getGraphObject(GraphUser::className());
      • Kumar Sven
        Sven, you are the saviour. With 2.4 we need need to specify the fields while creating request. I will never understand what facebook wont just send developers a simple email stating the changes. Dumba$$ product managers.
      • Elaidomino Sven
        Thanks @Sven! I'll check it later and post the result here. For future reference and a help for others, too!
    • Seven
      Thanks, works great :))
    • Elaidomino
      Why can I get the email and other public details but NULL when I uploaded the script in Live Server. Mine only displays just 2 details :/
      12345
      Array
      (
          [name] => myName
          [id] => 101
      )
      • Elaidomino Elaidomino
        May I have a sample of your index file? I'll try to run it here. 1. Have you added email in your permission? 2. Can you try to delete the app in your fb profile? and run the code again.
      • Felipe Elaidomino
        I've changed what you said, everything is shown now, but the email still does not appear =/ I'm using this: $user_profile = (new FacebookRequest($session, 'GET', '/me?fields=email,id,first_name,gender,last_name,link,locale,name,timezone,updated_time,verified'))->execute()->getGraphObject(GraphUser::className()); Someone with this problem?
      • Elaidomino Elaidomino
        Yo Felipe, Kindly check @Sven's answer. That solved mine :) Change the /me to /me?fields=email,name,id in your index file.
      • Felipe Elaidomino
        Someone help here! Mine too, the response only show this: Hi Felipe Santos you are logged in! [ log-out ] Array ( [name] => Felipe Santos [id] => 926587970738640 ) Thank you a lot!
    • Harsh
      Error : Failed to connect to 2a03:2880:2110:df07:face:b00c:0:1: Network is unreachable I am getting this error ?Can you point me to some useful links ?