jmhobbs

Skunk: A stinky PHP microframework

Six months ago I wrote a little PHP framework as an exercise. I'd been down this path before with the now abandoned Xoket - but this time I decided to go small, and throw away.

Hence Skunk was born.

Skunk is a single file, very lightweight API. Really, it's just a borrowed router with some sugar wrapped around it.

I was after a Sinatra or Bottle feel, and I think I got something rather nice out of it.

Skunk uses anonymous functions extensively, so use PHP 5.3+ to save yourself the pain of create_function.

Example

Here is a super simple Skunk application:

// Initialize
$s = new Skunk();

// Add a route
$s->get(
  '/hi(/)',
  function ( &$s, $name = null ) {
    $s->body = 'Hello' . ( ( is_null( $name ) ) ? '' : " $name" ) . '!';
  }
);

// Run it!
$s->run();

Let's tear that apart.

$s = new Skunk();

Everything in Skunk revolves around the Skunk object, so we need to set one up.

While it is possible to have multiple Skunk objects, there really isn't a good use case I can think of. But we won't restrict your cleverness with a singleton.

$s->get(

The two most important functions for Skunk are get and post.

These functions take a route and a function to apply when that route is matched, in a GET request and a POST request respectively.

  '/hi(/)',

In this chunk we are setting up a GET request, with the route /hi(/<name>), so that will match /hi, /hi/John, etc.

Note the identifier <name> in the route. This named match will be captured and sent as an argument to the function.

  function ( &$s, $name = null ) {
    $s->body = 'Hello' . ( ( is_null( $name ) ) ? '' : " $name" ) . '!';
  }
);

Skunk route functions always need to take a reference to the Skunk object as their first argument. Following that are any other arguments that might be pulled from the route itself.

In this case we are just setting the body of the Skunk response.

$s->run();

This kicks off the request process and also renders the response.

Other Tricks

Skunk has some other features too.

You can raise a variety of errors inside of a request:

$s->get(
  '/error/500',
  function ( &$s ) {
    return $s->HTTP_500();
  }
);

You can set headers:

$s->get(
  '/example.json',
  function ( &$s ) {
    $s->header( 'Content-Type', 'application/json' );
    $s->body = json_encode( array( "Example" => TRUE ) );
  }
);

There is even a little hook system, so you can do middleware-ish stuff:

$s->hook(
  'send_head', 
  function ( &$s ) { 
    $s->header( 'X-Stinky-By', 'Skunk' );
  }
);

Summary

So that is Skunk.

It could use some love, but it's workable. We've run Number Laundry on it with no problems for four months with no problems yet.

For an example of Skunk in action, check out Number Laundry's source at github.