phpf/routes

Phpf Routes package

dev-master 2015-02-08 20:14 UTC

This package is not auto-updated.

Last update: 2024-04-27 13:37:18 UTC


README

Request routing component.

###Dependencies

  • PHP 5.3+
  • Phpf\Util
  • Phpf\Http
  • Phpf\Event

Basic Usage

The router's constructor takes one parameter, a Phpf\Event\Container object. Events are triggered before and after the dispatch process, and are also used for errors.

use Phpf\Routes\Router;
$events = new Phpf\Event\Container;
$router = new Router($events);

There are two ways to define routes:

  1. The "normal" way - pass an array to the addRoute() method and a route is created.
  2. Under endpoints (or route namespaces) - endpoint routes are created and parsed only if the request matches the endpoint. This reduces the required parsing (and therefore, time) considerably.

####Normal

// Add a route at '/login/' that calls App\UserController::login() for GET and POST requests
$router->addRoute('login', array(
	'callback' => array('App\UserController', 'login'), 
	'methods' => array('GET', 'POST')
));

####Endpoints Endpoints contain a closure that is executed when the request matches the given endpoint path. The closure should return an array of the endpoint's routes.

In this example, for any request that begins with admin/, the router will execute the closure and attempt to match the returned routes. Note that $router is passed by the router itself.

$router->endpoint('admin', function ($router) {
	
	return array(
		'users' => array(
			'callback' => array('App\AdminController', 'users')
		),
		'pages' => array(
			'callback' => array('App\AdminController', 'pages')
		),
		'options' => array(
			'callback' => array('App\AdminController', 'options')
		),
	);
});

This would register the routes admin/users, admin/pages, and admin/options.

That was a bit repetitive - to simplify, you can set a controller to use for all routes under an endpoint:

$router->endpoint('admin', function ($router) {
	
	$router->setController('App\AdminController');
	
	return array(
		'users' => array(
			'action' => 'users'
		),
		'pages' => array(
			'action' => 'pages'
		),
		'options' => array(
			'action' => 'options'
		),
	);
});

Or even simpler:

$router->endpoint('admin', function ($router) {
	
	$router->setController('App\AdminController');
	
	return array(
		'users' => 'users',
		'pages' => 'pages',
		'options' => 'options',
	);
});

Note, however, you can't change the HTTP methods using this last way.

###Controllers not called statically We have defined our route callbacks using strings for the class. However, they are not called statically; if the matched route callback uses a string as the first element, the router will attempt to instantiate this class before calling the method. This way, controller callbacks are run in an object context, but the objects do not have to be instantiated unless needed.

Dispatching

To route/dispatch the request, pass the Phpf\Http\Request and Phpf\Http\Response objects to the router's dispatch() method:

use Phpf\Http\Request;
use Phpf\Http\Response;
$request = new Request;
$router->dispatch($request, new Response($request));

##Route Parameters

Route parameters can be defined two ways:

  1. Inline - Simply add the regex inside your route like so:
$router->addRoute('users/<user_id:[\d]{1,4}>', array(
	// ...
));
  1. Pre-registered - Register the variable name and regex, then use in routes:
$router->addVar('user_id', '[\d]{1,4}');

$router->addRoute('users/<user_id>', array(
	// ...
));

There are a few pre-registered parameters which can also be used or renamed for use in your routes:

$router->addRoute('users/<user_id:int>', array(
	// ...
));
$router->addRoute('page/<anything:segment>', array( // 'segment' matches everything up to a slash
	// ...
));

##Callbacks

After the route has been matched, the controller method will be called using the route parameters. Routes and callback functions must use the same parameter name. This means that if your route contains a parameter called user_id, then the corresponding callback method must accept a parameter called user_id.

For example:

$router->addRoute('users/<user_id:int>/posts/<year:[\d]{4}>', array(
	'callback' => array('App\UserController', 'getYearPosts'),
));

// In App\UserController class:

public function getYearPosts($year, $user_id) {
	// ...
}

The order of the parameters does not matter - the Reflection API is used to order the parameters correctly before calling the method.