Download the PHP package jitsu/app without Composer
On this page you can find all versions of the php package jitsu/app. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Package app
Short Description Extensible routing and configuration mechanisms
License MIT
Informations about the package app
jitsu/app
This package implements a simple but powerful architecture for developing modular, testable web applications in PHP. It consists primarily of an HTTP request router, several built-in request handler types, and a general-purpose configuration mechanism which is used to drive some of the router's behavior.
Using the routing mechanism implemented here gives you complete control over
URL routing (it is possible to hide the .php
suffix from URLs) and an easy
way to propagate configuration settings from configuration files to request
handlers.
Moreover, where traditional PHP scripts access HTTP request data through global
variables such as $_GET
, $_COOKIE
, etc., an instance of Application
is
fed objects which represent the HTTP request and response. It is through these
objects that the application interacts with the outside world, making it
possible to stub them out during unit testing.
This module is thus designed to solve two problems: the need for a less primitive way of routing HTTP requests, and the need to design applications in a way that is amenable to configuration and testing.
This package is part of Jitsu.
Installation
Install this package with Composer:
About
You're probably familiar with the usual URL routing mechanism in PHP: a URL
ending in .php
is mapped to a PHP script on the server of the same name.
While this is fine for beginner projects or private tools, or whenever you're
just not self-conscious about using URLs ending in .php
, using this default
setting has a number of problems:
- Using separate scripts for each page requires boilerplate code in every file for common tasks, such as setting up auto-loading, including libraries, performing authentication, printing headers and footers, etc. There is no single point of entry where these basic tasks can be handled.
- While you can use an
.htaccess
file to customize the URLs a bit, it is not straightforward to actually erase the.php
-style URLs. - It makes the layout of the project's source code visible to outsiders, which may not be desirable.
- There are many other interesting properties of a request besides its URL
which might inform routing, such as its method or its
Accept
header.
This package implements an alternative routing mechanism which can be used in
place of URL rewriting. Given a request, the router dispatches it by querying a
list of handlers and handing off control to the first one which claims
responsibility. By configuring your web server to direct all requests to a
single PHP script which invokes this router (which can be achieved with a simple
command in an .htaccess
file), you can use this package to get
rid of the unsightly .php
suffix which normally appears on all URLs.
An imporant design feature of the router is that it interacts with the HTTP request and response through an abstract, object-oriented interface, making it possible to stub out these objects when testing your application. Using dependency injection, you can send a simulated HTTP request to your application and capture its response in test, provided it is designed around these object-oriented interfaces. The request and response interfaces are found in jitsu/http.
Another integral feature of the router is its use of a configuration mechanism which allows routes to be hosted at an arbitrary external mount point. For example, by setting
in a configuration file, all requests will be routed relative to the external
path api/
. So if your domain is www.example.com/
, a request to
http://www.example.com/api/test/path
will map to the test/path
route.
All handlers accept a single $data
argument, which is an instance of
stdObject
that can be used to pass data from handler to handler. Through
this object, handlers can access the request and response objects via
$data->request
and $data->response
, as well as the configuration object
through $data->config
. Handlers can assign properties to $data
in order to
communicate with downstream handlers. Similarly, you can set any additional
properties you like in your configuration file in order to inform the behavior
of your handlers.
This package also includes an executable script, jitsu-config-template
, which
can be used to inject configuration settings into file templates written in
PHP. This tool can be used to generate an .htaccess
, robots.txt
, etc. file
during a pre-processing step using properties defined in your site's
configuration files. The script simply enables you to execute PHP files with the
variable $config
set to the configuration settings loaded from files listed
on the command line. You can write these template files without any boilerplate
code for including the configuration files or including your project's
vendor/autoload.php
Composer script.
Namespace
All classes are defined under the namespace Jitsu\App
.
Usage
For the following examples, let's assume we have the following configuration file:
config.php
Or, equivalently,
This file is just a normal PHP script which sets properties on a pre-defined
$config
variable.
Now, let's write an .htaccess
file which will direct all incoming requests to
the file index.php
, for those using Apache.
.htaccess
Pretty simple. We could improve on this in a couple of ways, by telling Apache to go ahead and treat CSS, JavaScript, etc. as static assets, and also by preventing Apache from listing directory contents. Let's do that now.
This directs requests to index.php
, except when Apache has matched the URL
to a file on the filesystem, and that file ends in .css
or .js
, is named
favicon.ico
or robots.txt
, or is under the assets/
directory.
Wouldn't it be nice if /var/www/example
weren't hard-coded? We could write
our .htaccess
as a template to do just that:
htaccess.php
In fact, this will allow us to host multiple builds of the site simultaneously at different document roots.
We could check this PHP file into version control and generate the real
.htaccess
file with the command
Now, let's move on to defining the router. We define an application class which
inherits from Jitsu\App\Application
. Then, we override the initialize
method to add routes and handlers.
MyApplication.php
The routes defined with get
respond to GET
requests at their respective
URLs. The notFound
handler is triggered as a fallback when the request fails
to match any of the routes above. Finally, the error
handler is entered into
a separate callback queue which is executed whenever a handler throws an
exception.
Note that URLs are specified as Rails-style patterns, allowing certain path segments to be captured. The supported pattern syntax is as follows:
:name
is a variable which captures everything except for a/
and associates the captured text with a parameter calledname
. URL-encoded slashes can still get through.1 Example:users/:id
matchesusers/42
and assignsid
=42
, but it does not matchusers/a/b/c
.*name
is a glob which captures everything, including slashes, and associates the captured text with a parameter calledname
. Example:assets/*path
matchesassets/path/to/img.jpg
and assignspath
=path/to/img.jpg
.- A pair of
()
encloses an optional section. Example:users/(index.html)
matchesusers/
andusers/index.html
.
Patterns are tested in order, so they should be listed in decreasing order of specificity.
All parameters are collected in $data->parameters
, an ordered array whose
keys are the parameter names. All values are automatically URL-decoded.
To invoke the router, instantiate your application and pass it a request, response, and configuration object.
index.php
If you are not stubbing out the HTTP request and response objects, you can use the following shorthand:
1 The router itself allows forward slashes to be encoded in path components, but some server configurations may disallow this. For example, Apache might be configured, by default, to re-encode encoded forward slashes in incoming URLs, or to refuse such requests with 404 Not Found. This is a security measure to prevent those with ill intent from gaining access to paths on the filesystem through unsanitized inputs. You can allow encoded slashes by adding the following directive to the virtual host in your Apache configuration file:
API
class Jitsu\App\Application
Extends Router
.
An extensible top-level HTTP request router.
new Application()
Automatically adds a configuration handler.
class Jitsu\App\SubRouter
Extends Router
.
An extensible sub-router which can be mounted in another router.
new SubRouter()
class Jitsu\App\Router
Extends BasicRouter
.
An extensible HTTP request router.
Like BasicRouter
but with fancy shortcut methods.
abstract protected function initialize()
Override this method to configure routes and handlers on this router.
$router->respond($request, $response, $config)
Dispatch a request to this router.
Type | Description | |
---|---|---|
$request |
\Jitsu\Http\RequestBase |
The HTTP request object. This will be made available to handlers via $data->request . |
$response |
\Jitsu\Http\ResponseBase |
The HTTP response object with which the application code will interact. This will be made available to handlers via $data->response . |
$config |
\Jitsu\App\SiteConfig |
Configuration settings for the router. This will be made available to handlers via $data->config . |
Router::main($config)
Shorthand for respond
which invokes the router with the current
HTTP request and response.
Type | Description | |
---|---|---|
$config |
\Jitsu\App\SiteConfig |
Configuration settings for the router. |
$router->callback($callback)
Add a callback to the request handler queue.
The callback will receive a single stdObject
argument ($data
)
which has been passed through earlier handlers. The handler may read
properties from this object to access data from earlier handlers and
assign properties to pass data to later handlers. The router
initially adds the properties request
, response
, and config
.
The handler should return true
if routing should cease with this
handler (indicating a match) or false
if the router should
continue to attempt to match later routes. A handler can perform
some action or add to $data
without returning true
, so that it
merely serves to communicate with later handlers.
Callbacks are executed in the same order they are added.
Type | Description | |
---|---|---|
$callback |
callable |
A callback which accepts a single stdObject argument and returns a bool to indicate whether it has handled the request and the router should stop dispatching. |
$router->setNamespace($value)
Set the namespace which will be automatically prefixed to the names of callbacks passed to all handler functions.
Function names are accepted as callbacks in all of the callback registration methods here. If all of your callbacks are under one namespace, this can be used to avoid repeating the namespace in all function names.
Type | |
---|---|
$value |
string |
$router->route($route, $callback)
Handle all requests to a certain path.
The path is specified as a pattern which may contain named parameters. The following syntax is supported:
:name
, which captures a portion of a path segment calledname
. This will not match slash (/
) characters.*name
, which captures a portion of text calledname
which can span multiple path segments. This will match any character.(optional)
, where the portion enclosed by()
characters may optionally be present. Any pattern syntax may appear inside the optional portion.
Any named parameters will automatically be URL-decoded and stored in
$data->parameters
, an array mapping parameter names to captured
values. The key-value pairs will occur in the same order as the
parameters were specified.
Type | Description | |
---|---|---|
$route |
string |
A path pattern. |
$callback |
callable |
$router->endpoint($method, $route, $callback)
Handle all requests to a certain combination of method and path.
Type | Description | |
---|---|---|
$method |
string |
The method (GET , POST , etc.). |
$route |
string |
A path pattern. |
$callback |
callable |
$router->get($route, $callback)
Handle a GET request to a certain path.
Type | Description | |
---|---|---|
$route |
string |
A path pattern. |
$callback |
callable |
$router->post($route, $callback)
Handle a POST request to a certain path.
Type | Description | |
---|---|---|
$route |
string |
A path pattern. |
$callback |
callable |
$router->put($route, $callback)
Handle a PUT request to a certain path.
Type | Description | |
---|---|---|
$route |
string |
A path pattern. |
$callback |
callable |
$router->delete($route, $callback)
Handle a DELETE request to a certain path.
Type | Description | |
---|---|---|
$route |
string |
A path pattern. |
$callback |
callable |
$router->mount($route, $router)
Mount a sub-router at a certain path.
Stops routing if and only if the sub-router matches. Routing continues if the sub-router does not match, even if the mount point matched.
Type | Description | |
---|---|---|
$route |
string |
A path pattern indicating where the sub-router will be mounted. |
$router |
\Jitsu\App\Router |
$router->badMethod($callback)
Handles any request whose URL was matched in an earlier handler but was not handled because the method did not match.
The property $data->matched_methods
will contain the list of
allowed methods for this URL.
Type | |
---|---|
$callback |
callable |
$router->notFound($callback)
Handles any request which was not matched in an earlier handler.
Type | |
---|---|
$callback |
callable |
$router->error($callback)
Handles any exceptions thrown by request handlers.
The property $data->exception
will be set to the exception thrown.
Type | Description | |
---|---|---|
$callback |
callable |
A callback which accepts a single stdObject argument. |
class Jitsu\App\BasicRouter
Basic router class.
The router consists of two queues: the normal request handler queue, and
the error handler queue. The router calls request handlers in the same
order they were registered until one of them returns true
. If a handler
throws an exception, control passes irreversibly to the error handler queue,
which behaves in the same way but has no rescue strategy for exceptions.
new BasicRouter()
$basic_router->handler($handler)
Add a handler to the request handler queue.
Type | |
---|---|
$handler |
\Jitsu\App\Handler |
$basic_router->errorHandler($handler)
Add a handler to the error handler queue.
The $data
argument to the handler will have the property
exception
set to the exception that was thrown.
Type | |
---|---|
$handler |
\Jitsu\App\Handler |
$basic_router->run($data)
Invoke the router with some datum to be passed from handler to handler.
Type | Description | |
---|---|---|
$data |
object |
Some datum to be passed from handler to handler. |
returns | bool |
Whether the invocation was handled, meaning that routing ended when some request handler or error handler returned true . |
throws | \Exception |
Any exception thrown by a request handler that was not handled in the error handler queue, or any exception thrown from an error handler. |
interface Jitsu\App\Handler
A route handler interface.
$handler->handle($data)
React to a request.
Type | Description | |
---|---|---|
$data |
object |
Some datum which is passed from handler to handler. |
returns | bool |
Whether this handler has matched the route and the router should stop routing. |
class Jitsu\App\SiteConfig
Extends Config
.
A subclass of Config
specialized for websites.
Adds the following properties:
base_url
: The external URL at which the router is mounted. Tied to the propertiesscheme
,host
, andpath
.scheme
: The scheme or protocol used by the site (http
orhttps
).host
: The host name of the site (such asexample.com
).path
: The path section of thebase_url
.base_path
: Likepath
, but formatted so that it always begins and ends with a slash.locale
: The locale of the currently running PHP script. When setting, use an array of values to indicate a series of fallbacks.
$site_config->set_base_url($url)
Set the base URL of the site.
If the scheme
, host
, or path
can be parsed from the new value,
they are set accordingly.
Type | |
---|---|
$url |
string |
$site_config->get_base_url()
Get the base URL.
Consists of <scheme>://<host>/<path>
.
Type | |
---|---|
returns | string |
$site_config->get_base_path()
Get the path
, formatted so that it always begins and ends with a
slash.
Type | |
---|---|
returns | string |
$site_config->makePath($rel_path)
Given a relative path, append it to the path
to form an absolute
path.
This has the exception that if both are the empty string, it returns the empty string.
Type | |
---|---|
$rel_path |
string |
returns | string |
$site_config->removePath($abs_path)
Strip off the path
from an absolute path, or return null
if the
path does not match.
Type | |
---|---|
$abs_path |
string |
returns | string|null |
$site_config->makeUrl($rel_path)
Given a relative path, append it to the base_url
to form an
absolute URL.
A small, special case: if the configured path
is set to the empty
string, then an empty $rel_path
will produce a URL consisting of
the domain with no trailing slash (e.g. http://www.example.com
).
This is unlike setting path
to /
, which will always produce a
URL with a trailing slash, even when $rel_path
is empty (e.g.
http://www.example.com/
). The former is techinically malformed,
although it may be desired, and browsers will generally still accept
it as a hyperlink.
Type | |
---|---|
$rel_path |
string |
returns | string |
$site_config->set_locale($value)
Set the locale.
If the value is an array of strings, each string serves as a fallback for the preceding ones in case they are not available.
Type | |
---|---|
$value |
string|string[] |
$site_config->get_locale()
Get the locale.
Type | |
---|---|
returns | string |
class Jitsu\App\Config
An object whose properties store configuration settings.
Usage is very simple. It behaves just like an stdObject
, where properties
can be set and accessed at will.
$config = new Config(['a' => 1]);
$config->b = 2;
echo $config->a, ' ', $config->b, "\n";
Sub-classes may add dynamic getter and setter functions for specific
properties by defining methods prefixed with get_
and set_
, followed by
the name of the simulated property.
Configuration settings may be read from any PHP file which assigns properties
to a pre-defined variable called $config
. For example:
config.php
$config->a = 1;
$config->b = 2;
To read the file:
$config = new Config('config.php');
new Config($args,...)
Initialize with the name of a PHP file or an array
of properties.
Type | |
---|---|
$args,... |
string|array |
$config->read($filename)
Read settings from a PHP file.
This simply evaluates a PHP file with this object assigned to
$config
.
Type | |
---|---|
$filename |
string |
returns | $this |
$config->set($name, $value = null)
Set/add a property.
Type | Description | |
---|---|---|
$name |
string|array |
The name of the property to set. Alternatively, pass a single array to set multiple properties. |
$value |
mixed |
|
returns | $this |
$config->merge($arg)
Set/add multiple properties.
Type | Description | |
---|---|---|
$arg |
string|array |
The name of a file to read or an array of properties to set. |
$config->__set($name, $value)
$config->get($name, $default = null)
Get a property.
Type | Description | |
---|---|---|
$name |
string |
The name of the property. |
$default |
mixed |
Default value to get if the property does not exist. |
$config->__get($name)
$config->has($name)
Tell whether a certain property exists.
Type | |
---|---|
$name |
string |
returns | bool |
$config->__isset($name)
All versions of app with dependencies
jitsu/error Version ^0.2.0
jitsu/http Version ^0.2.1
jitsu/string Version ^0.1.1
jitsu/util Version ^0.1.2