I started a project recently which involved building a fast and flexible front-end. I didn’t want to use WordPress but I did want easy routing without the bulk of a framework like Laravel. After some searching I found Flight which I’ve deemed the perfect lightweight framework. In this post I’ll show you what Flight PHP is and how you can use it to build a website or application rapidly.

What Is Flight PHP?

In short, Flight is a PHP micro-framework. It gives you a few tools to manage common tasks like routing and loading classes – thus suggesting a structure and method of coding – but leaves everything else up to you. It balances functionality with flexibility beautifully and has a style which is easy to learn and remember.

Among other things, Flight PHP allows you to:

  • handle requests through a logical routing system
  • respond to those requests in a uniform fashion
  • set variables efficiently
  • add filters to methods before and after they are called
  • register classes efficiently
  • handle views elegantly

These are exactly the things I do not want to spend time mucking about with when writing an application. Let’s take a look at some of them in more detail.

Setting Up The System

To set things up you’ll need to configure your server to route all requests through a single file. I use VVV for local development which utilizies nginx so I needed to add the following to my nginx configuration file:

server {
    location / {
        try_files $uri $uri/ /index.php;
    }
}

If you’re using apache you can use the following code in your htaccess file to achieve the same result:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]

I used Flight by cloning it from Github into a directory and then including the needed file in my index.php.

require 'flight/Flight.php';
//All code will go here
Flight::start();

All code we write will be placed (usually by including a file) before the call to Flight::start().

Routing In Flight PHP

The first thing you’ll want to do is create some routes. These are the urls your application will understand. I love the way these are written and how easily you can narrow routes down to specific methods.

Flight::route('GET /', function(){
    echo 'Our Home Page';
});
Flight::route('GET /users', function(){
    echo 'A list of users';
});
Flight::route('POST /users', function(){
    echo 'Adding a user';
});
Flight::route('/users/[0-9]+', function(){
   echo 'This is a specific user'
});

In the example above I’ve created a home route that only responds to GET requests and a users route that responds to GET and POST. The former could handle listing users, the latter could place new users in the database. This approach lends itself very well to creating RESTful APIs.

I’ve also added a route with a regular expression. Since I haven’t specified a method it will respond to any types. You can get the route object by passing true as the third parameter, like so:

Flight::route('GET /users/[0-9]', function( $route ){
    var_dump( $route->regex );
}, true);

Handling Variables And Classes in Flight PHP

One thing I hate managing is variables, classes and objects that need to be used all over the place. Flight provides a great mechanism for taking care of these nuisances. Let’s look at an arbitrary class that could be used all over our application – like a currency converter object.

Flight::register( 'currency', 'Currency' );
$currency = Flight::currency();
$amount = 160;
$converted = $currency->convert( $amount, 'USD', 'EUR' );

To use the Flight::register() function specify how you want to call this class in the first parameter and add the name of the class as the second parameter. You can then use Flight::myclass() to get a shared instance of the class anywhere. To get a new instance you must pass false as the parameter when calling the class:

$currency = Flight::currency( false );
$amount = 160;
$converted = $currency->convert( $amount, 'USD', 'EUR' );

You’ll use this extensively when communicating with your database. I used PDO in my project, here’s how:

Flight::register('db', 'PDO', array('mysql:host=localhost;dbname=' . DBNAME, DBUSER, DBPASS ));
$db = Flight::db();

You can now call $db = Flight::db(); anywhere within your application to access the shared instance.

The same sort of mechanic is applied to variables. You can set, retrieve and check for the existence of variables with built in functions:

Flight::set( 'exchange_rate', 0.1245669 );
$rate = Flight::get( 'exchange_rate' );

The reason you would want to set variables like this, as opposed to simply declaring them is that Flight PHP has built in filtering which can be applied to any built in function as well.

Filters

Filters are similar to WordPress hooks. They allow you to modify the behaviour of a function before or after it is executed.

Flight::map( 'insertUser', function( $data ){
    insertUserIntoDb( $data );
});

Flight::before( 'insertUser', function(&$params, &$output){
    $params[0]['registerTime'] = date( 'c' );
});

Flight::after( 'insertUser', function(&$params, &$output){
    mail( 'admin@app.com', 'A new user!', 'A new user with the name ' . $params[0]['name'] . ' has registered' );
});

$userdata = array( 'name' => 'Daniel' )
echo Flight::insertUser( $userdata );

The idea here is that I pass my user array to the Flight::insertUser() function which is tasked with adding my user to the database. By hooking Flight::before() into my method I can modify the parameters or the output. I utilize this to tack on the registration time to the user array. The user is then inserted into the database.

Using the Flight::after() method I send an email to the appropriate person with information about the registration. I love this because I can tack on as many additional after functions as I want. This allows me to separate out functionality and selectively enable/disable them easily.

Handling Views

When responding to a GET request you’ll probably want to generate some HTML. Flight offers the Flight::render() method which allows you to build pages efficiently using views. The basic way to get this done is something like this:

$view = array(
    'db' => Flight::db()
);
Flight::render( 'dashboard', $view );

This will load the dashboard.php file from my templates directory (this directory can be set in the config) and will pass the data from the $view variable to it. Passing the data is not essential, I could just call $db = Flight::db() from within the view. I thought it would be a good idea to pass these global classes that I would need from the outside to keep my view nice and clean.

You can also pass layouts to your view. These are useful for building modular interfaces. I was building a dashboard for an application and there were a number of common elements on every page such as the header and sidebar. These can be passed in similarly to before, here’s the full example from a route I created.

$view = array(
    'db' => Flight::db()
);

$route_info = array(
    'route_title' => 'Dashboard',
    'route_id'    => 'dashboard'
);

$page_header = array(
    'title' => 'Dashboard',
    'subtitle' => 'Some data to get you started'
);

Flight::render( 'modules/header', $route_info, 'site_header');

Flight::render( 'modules/footer', array(), 'site_footer');

Flight::render( 'modules/site-bar', array(), 'site_bar' );

Flight::render( 'modules/page-header', $page_header, 'page_header' );

Flight::render( 'dashboard', $view );

The header, footer, site-bar and page-header elements won’t be rendered automatically. They are passed to the dashboard within which you can echo them using the third parameter as the variable name: echo $site_header. Note that some of these layouts are passed data, this allows us to control the content from within the route, outside of the layout.

Learning More About Flight PHP

Flight is a simple but powerful system for building applications super-quickly. I recommend the excellent documentation which gives you all the info you need to become a power user.

Conclusion

Flight PHP is an amazing system. It’s right in the sweet spot – being lightweight but containing everything I need to get started without having to worry about the tedious “framework functions” I would need to write if I were creating something from scratch. On the other hand it doesn’t bog me down with tons of code for database migrations, pre-written login mechanisms and other fluff I don’t need on every project.