Skip to content
RESTful PHP library/framework http://peej.github.com/tonic/
Find file
Pull request Compare This branch is 307 commits behind peej:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
docroot
examples
features
lib
tests
LICENSE
README.markdown
phpdoctor.ini

README.markdown

PHP library/framework for building Web apps while respecting the 5 principles of RESTful design.

  • Give every "thing" an ID (aka URIs)
  • Link things together (HATEOAS)
  • Use standard methods (aka the standard interface)
  • Resources with multiple representations (aka standard document formats)
  • Communicate statelessly

See the Tonic site for more info.

How it works

Everything is a resource, and a resource is defined as a PHP class. An annotation wires a URI (or a collection of URIs) to the resource, and methods that match the HTTP methods by name allow interaction with it.

/**
 * This class defines an example resource that is wired into the URI /example
 * @uri /example
 */
class ExampleResource extends Resource { }

The incoming HTTP request is turned into a list of negotiated URIs based on the accept request headers which can then be used to pick the best representation for the response.

/**
 * This class defines an example resource that is wired into the URI /example
 * @uri /example
 */
class ExampleResource extends Resource {

    function get($request) {

        $response = new Response($request);

        $response->code = Response::OK;
        $response->body = 'Example response';

        return $response;

    }

}

How to get started

The best place to get started is to get the hello world example running on your system, to do this you will need a web server running PHP4+.

Place all of the Tonic files into your PHP include path so that other scripts can find it. By default on Windows this will probably be in "c:\php\includes\tonic" or on Linux/Unix it will be "/usr/share/php/tonic"

Copy "docroot/dispatch.php" into your servers document root and edit it so that the require_once statement paths point to the Tonic library and the examples.

Finally you need to route all incoming requests to dispatch.php. How you do this depends on your web server. If you are using Apache, the simplest way is to copy the .htaccess file from "docroot/.htaccess" into your Apache document root.

Features

Request URI

The URI that is processed for the request when you create the Tonic Request object is gather by default from the REQUEST_URI Apache variable. If you need to gather the URI from another $_SERVER variable or somewhere else then you can pass it into the Request objects constructor as a configuration option:

$request = new Request(array(
    'uri' => $_SERVER['PATH_INFO']
));

Base URI

If you want to put your Tonic dispatcher at a URL that isn't the root of a domain then you'll need to let the Request object know so that the @uri annotations ignore it:

$request = new Request(array(
    'baseUri' => '/some/base/uri'
));

Don't put a trailing slash on the end.

URI annotations

Resources are attached to their URL by their @uri annotation:

/**
 * @uri /example
 */
class ExampleResource extends Resource { }

As well as a straight forward URI string, you can also use a regular expression so that a resource is tied to a range of URIs:

/**
 * @uri /example/([a-z]+)
 */
class ExampleResource extends Resource {
    function get($request, $parameter) {
        ...
    }
}

URL template and Rails route style @uri annotations are also supported:

/**
 * @uri /users/{username}
 */
class ExampleResource extends Resource {
    function get($request, $username) {
        ...
    }
}

/**
 * @uri /users/:username
 */
class ExampleResource extends Resource {
    function get($request, $username) {
        ...
    }
}

It is also possible for multiple resource to match the same URI, so you can prioritise which resource should be used by specifying a priority level as part of the annotation:

/**
 * @uri /example/([a-z]+)
 */
class ExampleResource extends Resource { }

/**
 * @uri /example/apple 2
 */
class ExampleResource extends Resource { }

By postfixing the @uri annotation with a number, of all the matching resources, the one with the highest postfixed number will be used.

Mimetypes

To handle content negotiation via filename style extensions to URLs as well the HTTP Accept header, a mapping between extensions and mimetypes can be provided. By default this list contains a number of common mappings, if you need to add one or more of your own, pass them into the constructor as an array:

$request = new Request(array(
    'mimetypes' => array(
        'ogv' => 'video/ogg'
    )
));

Mount points

To make resources more portable, it is possible to "mount" them into your URL-space by providing a namespace name to URL-space mapping. Every resource within that namespace will in effect have the URL-space prefixed to their @uri annotation.

$request = new Request(array(
    'mount' => array(
        'namespaceName' => '/some/mounted/uri'
    )
));

Again, don't put a trailing slash on the end, and if you aren't using PHP5.3 and namespaces, you can use the @namespace annotation.

For more information, read the code. Start with the dispatcher "docroot/dispatch.php" and then the examples in the "examples" directory.

Something went wrong with that request. Please try again.