-
Notifications
You must be signed in to change notification settings - Fork 4
Routes
Routing is where all of Tessera’s power comes from. Routes basically define what URL patterns are mapped to which methods in your application class. You can use two types of routes: named params and splats, or raw regular expressions.
The simplest way to route is with named parameters and splats. Named parameters are denoted by a $ in front of their name, and are available in the $this->params
variable by name or position. Splats act as wildcards, and aren’t named. They’re only available by position, but a convience variable $this->splats
is also available. A regular splat is denoted by an asterisk, and will match anything up to a forward slash. A double-asterisk splat is greedy, and will even match forward slashes.
require 'tessera.php';
class ArguableApp extends Tessera {
function foo() {
echo "Bar is {$this->params['bar']}, and that's that";
}
}
$basic = new ArguableApp(array(
'/foo/$bar' => 'foo'
));
For the rest of this writeup, assume that the code is saved as arguable.php on your domain, tesseratic.com.
In the ArguableApp application, only one route is defined. The route /foo/$bar is mapped to the ArguableApp::foo
method. The $bar part of the route is a variable, meaning that any call to /foo/* will be matched, and the matched text will be passed as a parameter to the ArguableApp::foo
method. For example, tesseratic.com/arguable.php?/foo/xyzzy will match, and $this->params['bar']
inside of ArguableApp::foo
will equal "xyzzy"
.
Internally, routes are compiled to regular expressions, and parameter variables are compiled to (\w+), so keep that in mind when naming them. Routes can also be considerably more complex. If you add a new route to the application like this:
$basic = new ArguableApp(array(
'/foo/$bar' => 'foo',
'/bar/$baz/zip/$zap' => 'bar'
));
And the associated method:
function bar($baz, $zip) {
echo "Now we're getting nutty with {$baz} and {$zip}.";
}
Requests to tesseratic.com/arguable.php?/bar/squirtle/zip/charmander will match, and $baz
will equal "squirtle"
and $zip
will equal "charmander"
. This example also demonstrates that you can provide the names of parameters as functions to methods as a small convenience.
NOTE: PHP doesn’t support named arguments, its function arguments are purely positional. If I have /bar/$baz/$zip mapped to a function defined as bar($zip, $baz)
, $zip
is actually going to be the value from $baz and $baz
will be the value from $zip.
Splats are here to help route corner cases without having to resort to regular expressions. A simple example:
class App extends Tessera {
function foo() {
echo "Splat value: {$this->splat[0]}";
}
}
$app = new App(array(
'/foo/*' => 'foo';
));
You can also use a double asterisk to match splats that can contain a forward slash.
Maybe you have a corner case that you can’t accomplish with params and splats, and you need the full power of regular expressions. If you begin a route with a circumflex (^), the router will leave it as-is when matching URLs against it.
class App extends Tessera {
function foo() {
echo "Capture value: {$this->params[0]}";
}
}
$app = new App(array(
'^/foo/(\w+)' => 'foo';
));
Captures are still available in $this->params
, but only by position, and starting from zero.
While reading this, you probably noticed and wondered: “Why are all my routes in the query string? That’s terribly ugly.” That’s because I want the distribution to be server-agnostic. It would be trivial to add some rewrite rules to your server to hide away the .php extensions and query string marker. In fact, it’s all on the deployment page.