Build a Facebook application with Zend Framework

I’ve just finished a Facebook game, so here a quick tutorial on how to use Zend Framework to build a Facebook Application.

Facebook basics

You can integrate your application with facebook in two way: with an IFRAME (using XFBML) or with FBML.
(If you are already familiar with how a Facebook application work you can skip this step)

You can embed your content in a Facebook page through FBML or use an IFRAME
You can embed your content in a Facebook page through FBML or use an IFRAME

Build your website using FBML tags

Facebook will be a proxy between your server and the user’s browser: it will load a page form your own server like a normal browser, parse it, “enhance” it with his components and then embed it in a Facebook page. You will use standard HTML tags plus FBML tags.

Pros:

  • You can use almost standard HTML, but with some other tags like: <fb:comments ... />, <fb:wall ... />
  • Feature rich: with a simple tag integrate wall, comments, tabs, dashboard and many others components (Complete list of facebook tags)
  • The url in the browser follow the navigation
  • Faster when you need data from facebook database (groups, friends, etc.)

Cons:

  • Slower page load times: restart the facebook chat at every request
  • Can’t use standard JavaScript, only FBJS that’s almost equals but your existing scripts and libraries won’t work
  • Its losing ground: Facebook is trying to take IFRAME/XFBML on par

Embed using an IFRAME

Use an iframe: just build a standard web site and let FB embeds it in an iframe

Pros:

  • Better ajax support: you can use standard javascript, html and css
  • Easy to debug, its just a standard web site
  • Faster page load times

Cons:

  • Less features than with FBML (but XFBML is rapidly improving)
  • Slower when you need data from facebook database (eg: user’s friends, groups, etc.)
  • The url in the browser doesn’t follow the navigation
  • A bit more complex

We’ll start with FBML since its easier to use and to find help about on the forums.
However take a look at XFBML in the future, since the Facebook team has really improved it recently and they are trying to push them on par.

See facebook wiki for further details on the differences between FMBL and IFRAME.

Integration

First of all, setup your FBML app and write down your api key and secret key.

Just follow the onscreen instructions or the wiki, but care attention to the Canvas Page URL:
it is something like: http://apps.facebook.com/*APPLICATION_NAME* and it is the url through the user can reach your app.

While the Canvas Callback URL (for example: http://www.yourserver.com/fbapp) its the address of your own web server, where you’ll deploy your application.
With a dynamic dns service like dyndns you can create a domain name that map to the public address of your development machine, so that you can host your app on your dev machine while allowing Facebook to reach it.

Facebook will map every canvas url: http://apps.facebook.com/*APPLICATION_NAME*/foo to your callback url: http://www.yourserver.com/fbapp/foo

After you have done with the setup, you can use the official PHP client to interact with Facebook.

First, set up an empty Zend Framework project: you can use the Zend Studio for Eclipse wizard or the new Zend_Tool command line.

Use Zend Studio wizard to create an empty Zend Framewrok project
Use Zend Studio wizard to create an empty Zend Framewrok project

Then, download the client and copy the files in the php folder of the archive to the library/facebook folder of you Zend Framework project.

Now you can start using the client.

The Controller

To start, write in your controllers/IndexController.php:

require_once 'Zend/Controller/Action.php';

$err = error_reporting(E_ERROR);
require_once 'facebook/facebook.php';
error_reporting($err);
 
class IndexController extends Zend_Controller_Action {
  public $apiKey = "22c...s05";
  public $apiSecret = "df6...fb5";

  function indexAction()   {
    $facebook = new Facebook($this->apiKey, $this->apiSecret);
    $facebook->require_login();
  }
}

The line: $err = error_reporting(E_ERROR); is needed to hide some strange php notices from the facebook.php file.
In the line 12 we instantiate our client with the api key and secret taken during the application set up.
With the require_login method you can require the user to “add” your application.
Notice that many api features are available only if the user has added the application.

Then in your Zend actions you can call every standard method of the api with the
$facebook->api_client variable, for example:

$facebook->api_client->notifications_send(...); //Send a notify to a user
$facebook->api_client->friends_getAppUsers(); //Get the friends of the current user that use your app
//etc...

See the complete list of methods on the wiki and try them with the API console tool.

The View

Now that you know how to interact with Facebook, you can show a simple page containing the “Comments box” component.

In your layouts/main.phtml file write:

<?php echo $this->headScript() ?>
<?php echo $this->headStyle() ?>
<?php echo $this->layout()->nav ?>

<fb:title><?php echo $this->placeholder('title') ?></fb:title>

<?php echo $this->layout()->content ?> 

As you can see we don’t have to put the standard html opening tags in your layout (<html><head>...) since Facebook will load the page from your server and embed it in his own HTML canvas page.
We had also used our first FBML tag: <fb:title> to set the page title in the browser titlebar (we can’t use the ZF headTitle() method here).

Now create a view script for your index action of the index controller views/scripts/index/index.phtml:

<?php $this->placeholder('title')->set('My First Facebook App!'); ?>

Hello <fb:profile-pic uid='<?php echo $this->fbUserId ?>' linked="true"/>!<br /> <br />

Something to say?
<fb:comments xid="myCommentsBox" canpost="true" candelete="false" returnurl="http://apps.facebook.com/*APPLICATION_NAME*">
  <fb:title>My first comment Box</fb:title>
</fb:comments>

This will place a comment box in your page. Notice that the returnurl property need to point to your canvas url and not your callback url. (substitute *APPLICATION_NAME* with your canvas url)

To experiment with the various <fb:* > tags use the FBML console.

Now you can go to your canvas url to see the result:

Your first Facebook app with Zend Framework
Your first Facebook app with Zend Framework

In the HTML source of the canvas page you can see the original FBML used to generate the page and sometimes some errors/warnings.

Javascript and CSS

You can embed JavaScript in your FBML like in HTML, but only a special flavour of JavaScript: FBJS.
It is almost like the standard one, but there are some differences and your existing scripts and libraries won’t work.

If you want to embed an external .js file, you’ll have to specify the absolute path. Not only: Facebook will keep a copy of your script, even if you modify it, so you’ll have to put a timestamp in the url to force a cache refresh.

For example, if you want to embed a script in your index.phtml:

<?php $this->headScript()->appendFile('http://www.yourserver.com/fbapp/scripts/js.js?v=' . filemtime('scripts/js.js')) ?>

In this way Facebook will load the script from the url: http://www.yourserver.com/fbapp/scripts/js.js?v=1231707071.
When you’ll edit the file, the number will change and FB will reload it.

The same apply to CSS:

<?php $this->headStyle()->appendFile('http://www.yourserver.com/fbapp/styles/fbstyle.css?v=' . filemtime('scripts/js.js')) ?>

CSS in FB is almost standard, but use absolute urls.
Also be sure to write clean CSS, otherwise the Facebook parser will sometimes hang without and explanation.

Make things easier

We can use a base controller class.
In library/FacebookController.php write:

$err = error_reporting(E_ERROR);
require_once 'facebook/facebook.php';
error_reporting($err);

class FacebookController extends Zend_Controller_Action {
  public $simulateFb = false;
  public $useTestApplication = true;
  
  public $apiKey = "28c...b05";
  public $apiSecret = "df6...fb5";
  public $canvasUrl = "http://apps.facebook.com/myfbapp";
 
  public $testApiKey = '28c...b05';
  public $testApiSecret = 'df6...3fb5';
  public $testCanvasUrl = "http://apps.facebook.com/myfbapptest";

  public $fbUserId = "1234567";
	
  /**
   * Facebook api
   * @var Facebook
   */
  protected $facebook;
	
	public function init() {	
		if($this->simulateFb) {
			Zend_Session::start();
			parent::init();	
		}
		else {
			if($this->useTestApplication) {
				$this->apiKey = $this->testApiKey;
				$this->apiSecret = $this->testApiSecret;
				$this->canvasUrl = $this->testCanvasUrl;
			}

			$this->facebook = new Facebook($this->apiKey, $this->apiSecret);
			$session_key = md5($this->facebook->api_client->session_key);
			if(!Zend_Session::isStarted())  {
				Zend_Session::setId($session_key);
				Zend_Session::start();
			}
			parent::init();	
		}
	}
	
	protected function requireLogin() {
		if(!$this->simulateFb) {
			$this->fbUserId = $this->facebook->require_login();
		}
	}
	
	protected function _redirect($url, array $options = array()) {
	 	if(!$this->simulateFb) {
	 		$this->facebook->redirect($this->canvasUrl . $url);
	 	}
	 	else {
	 		parent::_redirect($url, $options);
	 	}
	}
}

header( 'Content-Type: text/html; charset=UTF-8' );

In this way, our IndexController can be rewritten in this simplier way:

require_once 'Zend/Controller/Action.php';
 
class IndexController extends FacebookController  {

  function indexAction()   {
    $this->requireLogin();
    $this->view->fbUserId = $this->fbUserId;
  }
}

We had made IndexController inherit from FacebookController, and used its method requireLogin, without requiring to set up the Facebook client.

Not only:
with the $simulateFb variable set to true you can preview your site outside the Facebook canvas page without requiring the login (but you’ll not see the FBML components).

With $useTestApplication you can use a different pair of api key and secret for the development, while keeping your main application safe. (you need to set up another app to obtain the keys)

Also the FacebookController will allow the standard Zend Framework _redirect method to work and will bind Zend session to the one of Facebook.

Finally in the last line we set up the charset encoding to be sure it will be the same of the Facebook canvas page.

Thats all:
now download the tutorial sources and start building your own Facebook app.

5 thoughts on “Build a Facebook application with Zend Framework

  1. Pingback: popurls.com // popular today

  2. Pingback: pligg.com

  3. Madarco says:

    @Chris: I haven’t tried to use Zend_Rest_Client with the Facebook api, however I think the official fb php client has some features that the Zend_Rest_Client doesn’t have, like the session_key and facebook authentication management or the requireLogin method.

Comments are closed.