Fitzgerald: a Sinatra clone in PHP

Posted November 21st, 2008; 9 comments.

Two weeks ago I had a tiny client website that suddenly needed a login section to provide some downloads to approved users. Initially I reached for Sinatra, which I have grown to love in recent months, but sadly the client’s server had no opportunity to run Ruby. A sad day for sure, but the world moves on and I decided to revisit my old friend PHP and see what could be done.

I spent about ten minutes looking through various PHP frameworks, but quickly decided that it would be faster to write the code the tiny site would need than learn the ins and outs of a full framework. I wanted something tiny anyway (preferably a single file), and most of what I found online were various fully fledged MVC Rails clones. Not going to work.

I knew I wanted a solution that would get me as close to possible to Sinatra’s syntax, while making the best of the confines of PHP. Here’s the final syntax I came up with:

<?php
    include('lib/fitzgerald.php');

    class Application extends Fitzgerald {

        // Basic get request
        public function get_index() {
            return $this->render('index');
        }
    }

    $app = new Application();

    $app->get('/', 'get_index');

    $app->run();
?>

The basic concept is to subclass Fitzgerald with controller methods, and then map them to urls using get() and post() calls on an instantiated application object.

I added some Merb-style argument passing to the mix using PHP5’s Reflection API:

<?php
    include('lib/fitzgerald.php');

    class Application extends Fitzgerald {

        // $page will be one of 'about', 'contact', or 'faq' thanks to our URL mapping below
        public function get_page($page) {
            return $this->render($page);
        }
    }

    $app = new Application();

    // :page is a placeholder- it will match anything by default, or a regex to match can
    // be passed in using an optional third argument to get() or post()
    $app->get('/:page', 'get_page', array('page' => 'about|contact|faq'));

    $app->run();
?>

Like Sinatra, the return value of a method is what is returned to the browser. Fitzgerald has built in methods to render a template or redirect the browser:

<?php
    class Application extends Fitzgerald {

        // Renders a php file in '../views/', making variables provided to compact
        // available as local variables in the template
        public function get_page($page) {
            $var1 = 'Value to use in template';
            $var2 = 'Another value to use in template';
            return $this->render($page, compact('var1', 'var2'));
        }

        // You can also send redirect headers
        public function get_redirect {
            return $this->redirect('/url/to/redirect/to');
        }
    }
?>

You can also specify a layout with an options array passed to the application initialization:

<?php
  // This will capture the output of any render calls into a local variable $content,
  // and then render the layout provided here
  $app = new ApplicationWithLogin(array('layout' => 'shell'));
?>

And that’s Fitzgerald. There is a more advanced example that shows how to build a simple authentication system in the repo on Github- look at example.php.

9 Responses to “Fitzgerald: a Sinatra clone in PHP”

  1. Aw Jim, that’s cute. It’s so little. It’s like a puppy that makes websites.

    If you want a full MVC that’s simple and non-restrictive, look at CodeIgniter.

    Also, puns.

  2. And for the inverse, here is a PHP inspired ruby framework: http://github.com/jcapote/joke

  3. http://limonade.sofa-design.net/

    Someone is doing another version of this. Good ideas get around.

  4. Limonade looks nice.

    Now that PHP 5.3 is out, it’s possible to get even closer to Sinatra’s syntax by using anonymous functions. I might work on that at some point if I find the time.

  5. Hello, i am Limonade’s author. If you like Limonade and wait for something more “Sinatra like”, I’ve planned to allow closures in dispatch_* functions for the next release (0.5). I hope i’ll publish it in the next month. If you have suggestions, let me know ;-)

  6. rockjock replied on November 14th, 2009 at 01:09 PM:

    The F3::Fat-Free Framework looks similar to this too. But it works only on PHP5.3+

    http://fatfree.sourceforge.net/

  7. Hallison Batista replied on January 21st, 2010 at 06:46 AM:

    Wow! Awesome! Very useful. I looking for something like the Ruby Sinatra DSL. Thanks, man!

  8. I can’t believe this was posted in 2008 and it’s now 2010 and I’m just now finding this. You might consider Chinchilla. It’s a RESTful php library used to build 6d. I’ve changed alot in it but the current version is pretty basic and follows a RESTful architecture.

  9. if anyone needs it, the .htaccess code for this could be:

    RewriteEngine on

    RewriteCond $1 !^(index.php|images|css|js|swf|xml|robots.txt|favicon.ico) RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*) /index.php [L]

Leave a Reply