Using the Facebook PHP SDK with CodeIgniter

the CodeIgniter logoMost of my small personal projects tend to get built with CodeIgniter (CI), which is a simple to use, fast, lightweight PHP5 MVC framework.

the Facebook logoFor a while now I’ve had an itch to build something fun against the Facebook API so I can start learning how Open Graph works, and as a primer to building a “proper” Facebook integrated application. I also realised I hadn’t actually tried using CodeIgniter 2.x since it was released (quite some time ago). With an abundance of free time this weekend it seemed like the perfect time to get hacking!

Before I could build anything I would need to know one thing: just how do you connect a CodeIgniter app to Facebook?

The answer is surprisingly simple. You will need:

Start by extracting both downloads to their own directories. Next, copy the two PHP files from facebook_SDK_path/src/ to CodeIgniter_path/application/library/. To stick to the CI conventions you should capitalise the filename of facebook.php, so it becomes Facebook.php.

The Facebook class expects some configuration details to be passed to it on initialisation. To make this seamless with CodeIgniter’s $this->load->library() method we need to create a custom config file. Create the file  CodeIgniter_path/application/config/Facebook.php (note the capital letter), with the following contents:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
$config = array(
 			'appId'  => getenv('FACEBOOK_APP_ID'),
  			'secret' => getenv('FACEBOOK_SECRET'),
		  );

You’ll notice I’m using getenv() to access my Application’s ID and Secret. That’s because I have them stored in my Virtual Host config, but you can just as easily specify the values directly in this file.

Right, so far, so good. The SDK files are in place, and the config file is setup. This allows us to simply use the following to load our SDK into our controller:

$this->load->library('Facebook');

Alternatively you can add ‘facebook’ to your libraries array in the autoload.php file.

$autoload['libraries'] = array('session','facebook');

Once loaded, making API calls is as simple as this:

// See if there is a user from a cookie
$user = $this->facebook->getUser();

Sample Usage

Below I have replicated the with_js_sdk.php example file in the Facebook SDK, as a CodeIgniter controller action/view (replacing the default CI welcome message)

Controller

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Welcome extends CI_Controller {
	private $data = array();
	/**
	 * Index Page for this controller.
	 *
	 * Maps to the following URL
	 * 		http://example.com/index.php/welcome
	 *	- or -
	 * 		http://example.com/index.php/welcome/index
	 *	- or -
	 * Since this controller is set as the default controller in
	 * config/routes.php, it's displayed at http://example.com/
	 *
	 * So any other public methods not prefixed with an underscore will
	 * map to /index.php/welcome/
	 * @see http://codeigniter.com/user_guide/general/urls.html
	 */

	public function index()
	{
		$this->load->library('facebook');
		$user = null;
	    $user_profile = null;

		// See if there is a user from a cookie
		$user = $this->facebook->getUser();

		if ($user) {
		  try {
		    // Proceed knowing you have a logged in user who's authenticated.
		    $user_profile = $this->facebook->api('/me');
		  } catch (FacebookApiException $e) {
		    show_error(print_r($e, TRUE), 500);
		  }
		}

		$this->data['facebook'] = $this->facebook;
		$this->data['user'] = $user;
		$this->data['user_profile'] = $user_profile;

		$this->load->view('welcome_message', $this->data);
	}

}

/* End of file welcome.php */
/* Location: ./application/controllers/welcome.php */

View

<!DOCTYPE html>
<html xmlns:fb="http://www.facebook.com/2008/fbml">
  <body>
    <?php if ($user) { ?>
      Your user profile is
      <pre>
        <?php print htmlspecialchars(print_r($user_profile, true)) ?>
      </pre>
      <?php echo anchor($facebook->getLogoutUrl(), 'Logout'); ?>
    <?php } else { ?>
      <fb:login-button></fb:login-button>
    <?php } ?>
    <div id="fb-root"></div>
    <script>
      window.fbAsyncInit = function() {
        FB.init({
          appId: '<?php echo $facebook->getAppID() ?>',
          cookie: true,
          xfbml: true,
          oauth: true
        });
        FB.Event.subscribe('auth.login', function(response) {
          window.location.reload();
        });
        FB.Event.subscribe('auth.logout', function(response) {
          window.location.reload();
        });
      };
      (function() {
        var e = document.createElement('script'); e.async = true;
        e.src = document.location.protocol +
          '//connect.facebook.net/en_US/all.js';
        document.getElementById('fb-root').appendChild(e);
      }());
    </script>
  </body>
</html>

If you run this code you will get a lovely print-out of the JSON data representing your Facebook account,  as returned by the Graph API. I added in the logout link so you can test the normal user process of logging in.

There’s a few things I’m going to clean up in the above. Namely I’m not too keen on passing our instance of the Facebook() class to the view. I’d rather create a helper file and move the stuff we need to access (AppID, logout url, etc) into a couple of functions within that… but it’s simple enough to do this. The point of the above code was simply to replicate one of the official samples within CodeIgniter.

What Next?

It strikes me that most of the uses of the SDK (i.e. to get information about the visiting user), would fit best into the Model part of the CI application. To this end I’ll probably start implementing it and see how it turns out. If it’s successful I’ll post the code here sometime over the weekend.

  1. […] Using the Facebook PHP SDK with CodeIgniter (chrismcleod.me) […]

    Like

  2. Any luck on implementing some of your code into a model and a helper file as you had suggested you might do?

    Like

    1. No. In the end I didn’t have the time, and haven’t gone back to the project. Thinking about it though, I’m not sure how useful a CI Model would be… you wouldn’t really want to hard-code the properties of the model (the values the API returns for each object), as Facebook might change the API at any time, and you’d have to write a class for each object type (person, comment, photo, etc). The object retrieval methods you can just leave to the API itself, unless you have a reason to abstract it out.

      Like

      1. Saika Andlip Mar 12 2013 at 8:50 AM

        this is saika working in an IT company as i’m a fresher i’m very new to this technology i’d like to know the process of getting the posts to a new webpage when ever any user updates or adds any item into her webpage just like the functioning of facebook home page but i need it for my website

        Like

  3. loading the Facebook library is not working. the construct is not called!!! what should I do. I’ve tried everything possible

    Like

    1. Did you create the custom config file, and capitalise the file names?

      Like

  4. How to give scope for this i also want profile picture, friends list etc

    Like

    1. On the PHP side, take a look at the documentation for getLoginUrl():

      http://developers.facebook.com/docs/reference/php/facebook-getLoginUrl/

      The JS SDK will have similar methods or config; take a look at the rest of the Facebook developers site from the above link.

      Like

  5. […] to set scope for facebook php sdk in codeigniter? I have used https://chrismcleod.me/2011/11/25/using-the-facebook-php-sdk-with-codeigniter/ library for facebook connect but how do i pass the scope, this just gives me basic info i want […]

    Like

  6. How to give custom image to the facebook login button

    gives me the default image i want to have a custom image how to do this???

    Like

    1. You need to write some JavaScript to wrap the login function and apply it to another element. This StackOverflow question gives a good example:

      Facebook OpenGraph: Customize FB:Login button

      Like

  7. none of this shit works Chris.

    Like

    1. Thanks for the insightful comment. If you have any corrections, please feel free to share, so everyone can benefit.

      Like

  8. Great tutorial! The tips on naming the library properly helped a lot – I had a spelling mistake in there and it had me stumped as errors were turned off on my live server which my app was referencing :(

    Like

    1. Yeah, the naming threw me off at first, and it took me a little banging my head against a wall to figure it out! Like you I wasn’t able to get any error messages to appear, even on my dev box. I’ll try to dig out the tip I found for resolving that, and post it as an entry.

      Like

  9. When I called the fb module from controller everything fine, but when I autoload it from autoload.php $this->facebook->getUser() always returns 0 although the user is authenticated (I checked with firebug the javascript response return the correct fb_uid)

    Like

    1. how do i redirect to my web page after the facebook login?

      Like

  10. rami zaklit Feb 7 2013 at 8:53 AM

    Hello man, all goes success in my project except one problem
    A PHP Error was encountered

    Severity: Notice

    Message: Undefined variable: _SESSION

    Filename: libraries/Facebook.php

    Line Number: 130

    how can i fix this ?

    Like

  11. Brian Hawver Feb 14 2013 at 2:59 PM

    Same issue as Rami above. This happens when we try to logout of our website.

    Like

  12. I have the same problem as Arie Agung. The function $ this-> facebook-> getUser () always returns 0. Why?

    Thanks!

    Like

  13. […] An earlier example, from before I was entirely away from development: I wanted to see what was different in CodeIgniter 2, so I made a very small app. My curiosity then extended into “how does Heroku work?” – so I deployed to Heroku. I couldn’t pay for a database I knew how to work with, so I tried out a little bit of MongoDB. Then it was the Graph API from Facebook… so again, I extended the application, this time with the Facebook SDK. […]

    Like

Comments are closed.

%d bloggers like this: