Using the Facebook PHP SDK with CodeIgniter

the CodeIgniter logo

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:

[sourcecode language=”php”]
<?php if ( ! defined(‘BASEPATH’)) exit(‘No direct script access allowed’);
$config = array(
‘appId’ => getenv(‘FACEBOOK_APP_ID’),
‘secret’ => getenv(‘FACEBOOK_SECRET’),
);
[/sourcecode]

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:

[sourcecode language=”php”]
$this->load->library(‘Facebook’);
[/sourcecode]

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

[sourcecode language=”php”]
$autoload[‘libraries’] = array(‘session’,’facebook’);
[/sourcecode]

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

[sourcecode language=”php”]
// See if there is a user from a cookie
$user = $this->facebook->getUser();
[/sourcecode]

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

[sourcecode language=”php”]
<?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 */
[/sourcecode]

View

[sourcecode language=”php” htmlscript=”true”]
<!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>
[/sourcecode]

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.

22 comments

    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.

      1. 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

  1. 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 šŸ™

    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.

  2. 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)

  3. 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 ?

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: