Skip to content
Toro is a PHP router for developing RESTful web applications and APIs.
PHP
Branch: master
Clone or download

Latest commit

Fetching latest commit…
Cannot retrieve the latest commit at this time.

Files

Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
examples long tags in templates Feb 9, 2013
src Made code more PSR-1 compliant Apr 8, 2015
.gitignore Adding a .gitignore. Aug 14, 2012
LICENSE Explicitly noting the MIT License. Aug 14, 2012
README.md Update README.md Apr 15, 2015
composer.json Set minimum version of PHP required to 5.3+. Dec 28, 2012

README.md

Toro

Toro is a PHP router for developing RESTful web applications and APIs. It is designed for minimalists who want to get work done.

Quick Links

Features

  • RESTful routing using strings, regular expressions, and defined types (number, string, alpha)
  • Flexible error handling and callbacks via ToroHook
  • Intuitive and self-documented core (Toro.php)
  • Tested with PHP 5.3 and above

"Hello, world"

The canonical "Hello, world" example:

<?php

class HelloHandler {
    function get() {
        echo "Hello, world";
    }
}

Toro::serve(array(
    "/" => "HelloHandler",
));

Routing Basics

Routing with Toro is simple:

<?php

Toro::serve(array(
    "/" => "SplashHandler",
    "/catalog/page/:number" => "CatalogHandler",
    "/product/:alpha" => "ProductHandler",
    "/manufacturer/:string" => "ManufacturerHandler"
));

An application's route table is expressed as an associative array (route_pattern => handler). This is closely modeled after Tornado (Python). Routes are not expressed as anonymous functions to prevent unnecessary code duplication for RESTful dispatching.

From the above example, route stubs, such as :number, :string, and :alpha can be conveniently used instead of common regular expressions. Of course, regular expressions are still welcome. The previous example could also be expressed as:

<?php

Toro::serve(array(
    "/" => "SplashHandler",
    "/catalog/page/([0-9]+)" => "CatalogHandler",
    "/product/([a-zA-Z0-9-_]+)" => "ProductHandler",
    "/manufacturer/([a-zA-Z]+)" => "ManufacturerHandler"
));

Pattern matches are passed in order as arguments to the handler's request method. In the case of ProductHandler above:

<?php

class ProductHandler {
    function get($name) {
        echo "You want to see product: $name";
    }
}

RESTful Handlers

<?php

class ExampleHandler {
    function get() {}
    function post() {}
    function get_xhr() {}
    function post_xhr() {}
}

From the above, you can see two emergent patterns.

  1. Methods named after the HTTP request method (GET, POST, PUT, DELETE) are automatically called.

  2. Appending _xhr to a handler method automatically matches JSON/XMLHTTPRequest requests. If the _xhr method is not implemented, then the given HTTP request method is called as a fallback.

ToroHook (Callbacks)

As of v2.0.0, there are a total of five Toro-specific hooks (callbacks):

<?php

// Fired for 404 errors; must be defined before Toro::serve() call
ToroHook::add("404",  function() {});

// Before/After callbacks in order
ToroHook::add("before_request", function() {});
ToroHook::add("before_handler", function() {});
ToroHook::add("after_handler", function() {});
ToroHook::add("after_request",  function() {});

before_handler and after_handler are defined within handler's constructor:

<?php

class SomeHandler {
    function __construct() {
        ToroHook::add("before_handler", function() { echo "Before"; });
        ToroHook::add("after_handler", function() { echo "After"; });
    }

    function get() {
        echo "I am some handler.";
    }
}

Hooks can also be stacked. Adding a hook pushes the provided anonymous function into an array. When a hook is fired, all of the functions are called sequentially.

Installation

Grab a copy of the repository and move Toro.php to your project root.

Using Composer

Install composer in your project:

$ curl -s https://getcomposer.org/installer | php

Caution: The above command requires you to place a lot of trust in the composer team to not get hacked and have a backdoor installed in their installer script. If secuity is a concern, consider doing the following:

$ curl -s https://getcomposer.org/installer > installer.php
$ less installer.php
$ # When you're certain it's safe...
$ php installer.php

Create a composer.json file in your project root:

{
    "require": {
        "torophp/torophp": "dev-master"
    }
}

Install via composer:

$ php composer.phar install

Server Configuration

Apache

You may need to add the following snippet in your Apache HTTP server virtual host configuration or .htaccess file.

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php)
RewriteRule ^(.*)$ /index.php/$1 [L]

Alternatively, if you’re lucky enough to be using a version of Apache greater than 2.2.15, then you can instead just use this one, single line:

FallbackResource /index.php

IIS

For IIS you will need to install URL Rewrite for IIS and then add the following rule to your web.config:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
          <rule name="Toro" stopProcessing="true">
            <match url="^(.*)$" ignoreCase="false" />
              <conditions logicalGrouping="MatchAll">
                <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
                <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
                <add input="{R:1}" pattern="^(index\.php)" ignoreCase="false" negate="true" />
              </conditions>
            <action type="Rewrite" url="/index.php/{R:1}" />
          </rule>
        </rewrite>
    </system.webServer>
</configuration>

Nginx

Under the server block of your virtual host configuration, you only need to add three lines.

location / {
  try_files $uri $uri/ /index.php?$args;
}

Contributions

Contributions to Toro are welcome via pull requests.

License

ToroPHP was created by Kunal Anand and released under the MIT License.

You can’t perform that action at this time.