Getting Started


Smoothly connect structured URLs to a simple request-response cycle.

Floe supports several styles of controller and servlet bindings, including support for REST conventions and slowly growing coverage of standard HTTP idioms. It's fast, clean, and easy to understand.

The Membrane Wrapper

In Floe, the concept of a server is simply that of a run-time procedural dispatcher that responds to incoming requests. In an object-oriented context, this architecture is naturally represented by interacting Request and Response objects. Floe enables this interaction by the use of a 'wrapping space' which we call a Membrane. The Membrane is an outer layer that encapsulates the entire run-time flow control sequence and triggers the final HTTP and content response to be pushed to output.

What does a cell membrane look like?

Membrane structures are the fundamental mediators of communication between cellular processes (source unknown).

Actual application routines are invoked using the concept of Receptor binding. Servlet style classes that implement the Receptor interface are attached to the runtime membrane and are responsible for interpreting the Request and appending results to the Response buffer. This code is usually located in the index.php reciever file - Apache should be configured to pass through all dynamic requests to this PHP reciever using mod_rewrite.

require 'config.php';
require 'floe/server/Membrane.php';
require 'floe/server/IdentityDispatcher.php'
 
$server = new Membrane();
$server->attach(new IdentityDispatcher());
$server->run();  

By default, receptors are chained in a FIFO sequence, as determined by the procedural order of their attachment to the Membrane. This design makes it simple to implement different styles of resource dispatching and share them between multiple apps.

Default Receptors Provided

IdentityDispatcher Binds to a controller method based on the named identity segment of a URL GET /books binds to BooksController->index
ResourceDispatcher Binds to a named controller based on the HTTP method verb of the request GET /books binds to BooksController->get

Implementing Concrete Controllers

Floe expects controllers to be in the /app/controllers folder on the server. Controllers must have an exact naming match between filename and class definition or else they won't dispatch correctly.

  • index.controller.php => IndexController
  • sub/name.controller.php => NameController

A basic example of a controller to be invoked with identity would look like:

class IndexController extends BaseController {
    function index() {
        $this->response->write('<h1>Hello World</h1>');
    }
}

A controller that wraps a REST style resource would look like:

class BooksController extends BaseController {
    function get() {
        $this->response->write('Accessed with HTTP GET');
    }
    function post() {
        $this->response->write('Accessed with HTTP POST');
    }
    function put() {
        $this->response->write('Accessed with HTTP PUT');
    }
    function delete() {
        $this->response->write('Accessed with HTTP DELETE');
    }
    function head() {
        $this->response->write('Accessed with HTTP HEAD');
    }
}

Mapping the URI Path

The Request object is a read-only reference during the normal flow of an application. It provides various helper methods and attributes for accessing useful properties of the HTTP request message, including the UriPath object bound as $request->uri, which represents the conceptual segments of the currently requested URL.

The best usage reference for the UriPath is currently the UriPathReaderTest.

Rendering PHP Templates

The Response object acts as a buffer for the HTTP headers and content body returned to the browser that initiated the request. Examples above demonstrated use of the Response->write method, which isn't anything more than just echoing plain strings back. More useful, is the ability to render dynamic templates with assigned variables substituted:

class SeussController extends IdentityController {
    function options() {
        $this->response->assign('breakfast', array('green','eggs','ham'));
        $this->response->render('options');
    }
}

This controller would bind to the URL path /seuss/options and render the following template at /app/templates/seuss/options.php:

<div>
  <h3>What's for Breakfast?</h3>
  <ul>
  <?php foreach($breakfast as $item) : ?>
    <li><?php print $item; ?></li>
  <?php endforeach; ?>
  </ul>
</div>

Related Documentation