Download the PHP package monolyth/reroute without Composer
On this page you can find all versions of the php package monolyth/reroute. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Informations about the package reroute
Reroute
Flexible PHP5 HTTP router, with support for various types of URL matching, URL arguments, custom state handling and URL generation. Reroute is designed to be usable in any type of project or framework.
Installation
Composer (recommended)
Manual installation
- Get the code;
- Clone the repository, e.g. from GitHub;
- Download the ZIP (e.g. from Github) and extract.
- Make your project recognize Reroute:
- Register
/path/to/reroute/src
for the namespaceMonolyth\\Reroute\\
in your PSR-4 autoloader (recommended); - Alternatively, manually
include
the files you need.
- Register
Basic Usage
Responding to requested URLs
Since the Reroute router responds to HTTP requests, we use the when
method to
define a valid URL:
when
returns a new State
as a response to the specified URL, optionally
identified by the given name. You must then define the HTTP verbs to which
that state will respond, and with what:
The HTTP verb methods currently supported are get
, post
, put
, delete
,
head
and options
. There is also the special any
method which covers them
all with one single reponse.
A response must, eventually, be an instance of
Psr\Http\Message\ResponseInterface
. However, for convenience there are also
other things you might define as a response:
- If it is a callable, it is called (with the arguments extracted from the URL) until it is no longer callable.
- If it is a string and a class exists by that name, it is an instance of that class.
- If the class is callable it is invoked and the result is used.
- Otherwise the class itself must implement
Psr\Http\Message\ResponseInterface
.
Hence, the following forms are equivalent:
Named states
The second parameter to when
is the (hopefully unique!) name of the state.
This can be used later on when generating routes (see below). If no name is
required it may be null
(also, the default). You can also use Router::get
to
retrieve a particalar state by name later on (e.g. maybe your routing is
insanely complex and split over multiple files).
Resolving a request
After routes are defined, somewhere in your front controller you'll want to
actually resolve the request. The ResponseInterface
object can then be
emitted, e.g. using Zend Diactoros:
Routers must be invoked with the current request as argument. Note that prior to invocation, it will not be possible to generate routes. If this is something you need to do (e.g. in CRON jobs to send out emails) you may invoke the router manually.
Invoking the router starts a pipeline.
By calling the router's pipe
method you can add middleware to the stack.
If a valid state was found for the current URL, its return value is returned by
the pipeline. Otherwise, it will resolve to null
.
To emulate a different request type than the actual one, simply change
$_SERVER['REQUEST_METHOD']
.
Passing parameters
Your URLs are actually regexes, so you can match variables to pass into the callback:
Variables can be named (in which case the order you pass them to your callback doesn't matter - Reroute does reflection on the callable to determine the best fit) or anonymous (in which case they'll be passed in order).
Shorthand placeholders
For simpler URLs, you can also use a few shorthand placeholders. The following three statements are identical:
When using placeholders, note that one has less control over parameter types.
Using regexes is more powerful since you can force e.g. "/(?'id'\d+)/"
to
match an integer and even type-hint it in the callable.
Inspecting the current request
By type hinting a parameter as an instance of
Psr\Http\Message\RequestInterface
, you can inject the original request object
and inspect the used method (or anything else of course):
Referring to other callbacks
A parameter typehinted as callable
matching a defined action (in uppercase)
can be used to "chain" to another action. So the following pattern is common for
URLs requiring special handling on e.g. a POST
:
Note there is no need to re-pass any URL parameters to the callable; they are
injected automatically. Hence, calls to get
and post
etc. may
accept/recognize different parameters in different orders.
Custom verb callbacks do not "bubble up" the routing chain. Hence, specifically disabling
POST
on/foo/
does not affect the default behaviour for/foo/bar/
.
If the injected action is not available for this state, a 405 error is returned instead.
Grouping
The optional third argument to when
is a callable, which expects a single
parameter: a new (sub) router. All routes defined using when
on the subrouter
will inherit the parent router's URL:
The result of a grouped when
call is itself a state, which may be piped and/or
resolved. For convenience, this state can also be defined inside the callback
using ->when('/', ...)
. So, instead of this (which is itself perfectly valid):
...you may also write the (more readable):
Pipelining middleware
Since states are pipelined, you can at any point add one or more calls to the
pipe
method to add middleware:
You can call pipe
as often as you want. Subrouters won't be executed if the
pipeline is short-circuited anywhere.
When using named parameters, the pipelined callable can optionally specify which parameters it also wants to use:
This is similar to the state resolving callable, except that there is always
a first parameter $payload
, and injecting the $request
isn't possible.
One common use of this is defining a pipe for a first $language
parameter in
a group of routes, and setting some environment variable to its value for all
underlying routes.
$payload
is, by definition, an instance of
Psr\Http\Message\RequestInterface
. As soon as any pipe returns an instance of
Psr\Http\Message\ResponseInterface
, everything is halted and it is designated
as the chosen response for this route in its current state. One common use for
this is to redirect users if they are trying to access page A, but need to do
something on page B first (e.g. login).
Generating URLs
To generate a URL for a defined named state, use the generate
method:
The optional third parameter to generate is a boolean telling generate
if it
should prefer a route without scheme/host if the user is already on the current
host. It defaults to true. The above example might output
http://localhost/foo/bar/
if called with false
as the third parameter. This
is useful if the generated routes are to be used outside your application, e.g.
in an email sent out.
Generation is only possible for named states, since anonymous ones obviously could only be retrieved by their actual URL (in which case you might as well hardcode it...). Use named states if your URLs are likely to change over time!
Cascading arguments
When generating a route in a subrouter, all named arguments set in the parent router are automagically injected into the passed arguments.
An example:
Of course, you could also inject string $langauge
as a parameter in the
sub-route, but this gets tiresome.
Note that arguments passed in the
generate
call's second argument receive precedence over previously matched ones. This means you could explicitly redirect/en/home/
to/nl/
in the above example by doing:$router->generate('home', ['language' => 'nl']);
.
Handling 404s and other errors
The result of $router()
will be null
if no match was found, so that means
you need to show a 404 error page. Beste practice is to wrap that call in a
try/catch
block and throw exceptions on errors. That way you can show a
generic 500 error page in the catch
block (and maybe do some logging).
Routes with default arguments
In some situations it comes in handy to be able to specify a "default argument"
in your callback. E.g., when a call to /user/
should show the currently
logged in user's profile, and a call to /user/:id/
that of the specified user.
This is possible in Reroute by making the argument optional in the URL and giving a default value in the callback. For the above example, one could e.g. do:
The shorthand URL matching style can be made optional by postfixing the placeholder with a question mark:
Note that any argument found ending in a slash has this stripped, since normally slashes are reserved for argument separation. Also, consequetive slashes are automatically collapsed.
Supported HTTP methods
Reroute supports GET, POST, PUT, DELETE and OPTIONS HTTP methods. Each has a
correspondingly named method on the State
object you can use to define a
response. If no response was defined, Reroute will return an instance of
Laminas\Diactoros\Response\EmptyResponse
with a 405 status code.
There are, however, two special cases. If a GET response was defined, but no POST response was explicitly defined, the GET response will be used to respond to a POST action. Generally you should respond to a POST by actually doing something and then redirecting somewhere to prevent double posts, but this way at least your site won't break.
The other exception is the HTTP HEAD method. This is supported automatically by
taking the GET response, stripping the body, adding a Content-Lenth header and
returning a Laminas\Diactoros\Response\EmptyResponse
with status 200. This
does obviously imply a GET response was defined; otherwise a 405 empty response
will be returned.
All versions of reroute with dependencies
jakeasmith/http_build_url Version ^1.0.0
league/pipeline Version ^0.1.0
psr/http-message Version ^1.0