# Class HttpSoft\Router\RouteCollection

Collection of routes that implements HttpSoft\Router\RouteCollectionInterface.

Source code on GitHub.

use HttpSoft\Message\Uri;
use HttpSoft\Router\Route;
use HttpSoft\Router\RouteCollection;

/**
 * @var mixed $handler
 * @var Psr\Http\Message\ServerRequestInterface $request
 */

$route = (new Route('post', '/post/{id}', $handler))
    ->tokens(['id' => '\d+'])
;

$routes = new RouteCollection();
$routes->set($route);

$routes->match($request->withUri(new Uri('/post/11'))); // $route
$routes->match($request->withUri(new Uri('/post/slug'))); // null

$routes->path('post', ['id' => 11]); // '/post/11'
$routes->url('post', ['id' => 11]); // '/post/11'

$routes->url('post', ['id' => 11], 'example.com'); // '//example.com/post/11'
$routes->url('post', ['id' => '1'], 'example.com', true); // 'https://example.com/post/1'
$routes->url('post', ['id' => '1'], 'example.com', false); // 'http://example.com/post/1'

$routes->get('post'); // $route
$routes->has('post'); // true

$routes->remove('post'); // $route
$routes->has('post'); // false

$routes->clear();
$routes->getAll(); // []

# Public methods

See the original detailed description of the methods in the HttpSoft\Router\RouteCollectionInterface.

# set

Sets a route.

public function set(HttpSoft\Router\Route $route): void;

If the route already exists, the HttpSoft\Router\Exception\RouteAlreadyExistsException exception will be thrown.

# get

Gets the route with the specified name.

public function get(string $name): Route;

If the route does not exist, the HttpSoft\Router\Exception\RouteNotFoundException exception will be thrown.

# getAll

Gets all routes, or an empty array if no routes exist.

/**
 * @return HttpSoft\Router\Route[]
 */
public function getAll(): array;

# getIterator

Gets an external iterator with routes.

public function getIterator(): ArrayIterator;

# has

Checks whether a route with the specified name exists.

public function has(string $name): bool;

# remove

Removes and returns the removed route.

public function remove(string $name): Route;

If the route does not exist, the HttpSoft\Router\Exception\RouteNotFoundException exception will be thrown.

# clear

Removes all routes.

public function clear(): void;

# count

Returns the number of routes.

public function count(): int;

# match

Matches the request against known routes.

/**
 * @param Psr\Http\Message\ServerRequestInterface $request a server request instance that implements PSR-7.
 * @param bool $checkAllowedMethods whether to check if the request method matches the allowed route methods.
 * @return Psr\Http\Message\ResponseInterface matched route or null if the request does not match the routes.
 */
public function match(
    ServerRequestInterface $request, 
    bool $checkAllowedMethods = true
): ?Route;

The URI of the request with each route is matched, as well as the request method with the allowed route methods if $checkAllowedMethods === true.

use HttpSoft\Message\Uri;
use HttpSoft\Router\Route;

/**
 * @var mixed $handler
 * @var HttpSoft\Router\RouteCollection $routes
 * @var Psr\Http\Message\ServerRequestInterface $request
 */

$routeAction = (new Route('post.action', '/post/{action}/{id}', $handler, ['GET', 'POST']))
    ->tokens(['action' => '[\w-]+', 'id' => '\d+'])
;
$routeDelete = (new Route('post.delete', '/post/delete/{id}', $handler, ['DELETE']))
    ->tokens(['id' => '\d+'])
;

$routes->set($routeDelete);
$routes->set($routeAction);

$request = $request->withUri(new Uri('/post/create/11'));
$routes->match($request->withMethod('GET')); // $routeAction
$routes->match($request->withMethod('POST')); // $routeAction
$routes->match($request->withMethod('DELETE'), false); // $routeAction
$routes->match($request->withMethod('DELETE')); // null

$request = $request->withUri(new Uri('/post/delete/11'));
$routes->match($request->withMethod('GET')); // null
$routes->match($request->withMethod('POST')); // null
$routes->match($request->withMethod('DELETE')); // $routeDelete
$routes->match($request->withMethod('POST'), false); // $routeDelete

$request = $request->withUri(new Uri('/post/delete'));
$routes->match($request->withMethod('GET')); // null
$routes->match($request->withMethod('POST')); // null
$routes->match($request->withMethod('DELETE')); // null
$routes->match($request->withMethod('DELETE'), false); // null

Matching a request to routes is done in a loop, so priority routes must be established before general routes.

use HttpSoft\Message\Uri;
use HttpSoft\Router\Route;

/**
 * @var mixed $handler
 * @var HttpSoft\Router\RouteCollection $routes
 * @var Psr\Http\Message\ServerRequestInterface $request
 */

$routeAction = (new Route('post.action', '/post/{action}/{id}', $handler))
    ->tokens(['action' => '[\w-]+', 'id' => '\d+'])
;
$routeDelete = (new Route('post.delete', '/post/delete/{id}', $handler))
    ->tokens(['id' => '\d+'])
;

// Correctly:
$routes->set($routeDelete);
$routes->set($routeAction);
// matches with `$routeDelete`
$routes->match($request->withUri(new Uri('/post/delete/11')));

// Incorrectly
$routes->set($routeAction);
$routes->set($routeDelete);
// matches with `$routeAction`
$routes->match($request->withUri(new Uri('/post/delete/11')));

# path

Generates a URL path based on the route name and parameters.

/**
 * @param string $name name of the route.
 * @param array $parameters 'parameter name` => `parameter value`.
 */
public function path(string $name, array $parameters = []): string;

If the route does not exist, the HttpSoft\Router\Exception\RouteNotFoundException exception will be thrown.

If the parameter value does not match its regular expression, or the required parameter is null, the HttpSoft\Router\Exception\InvalidRouteParameterException exception will be thrown.

use HttpSoft\Router\Route;

/**
 * @var mixed $handler
 * @var HttpSoft\Router\RouteCollection $routes
 */

$routes->set((new Route('post', '/post/{tag}{[id]}', $handler))
    ->tokens(['tag' => '[\w-]+', 'id' => '\d+'])
);

$routes->path('post', ['tag' => 'tag-slug', 'id' => '11']); // '/post/tag-slug/11'
$routes->path('post', ['tag' => 'tag-slug', 'id' => null]); // '/post/tag-slug'
$routes->path('post', ['tag' => 'tag-slug']); // '/post/tag-slug'

$routes->path('post'); // throws InvalidRouteParameterException
$routes->path('post', ['tag' => null]); // throws InvalidRouteParameterException
$routes->path('post', ['id' => 11]); // throws InvalidRouteParameterException
$routes->path('post', ['tag' => 'tag-slug', 'id' => 'slug']);; // throws InvalidRouteParameterException
$routes->path('not-exist', ['tag' => 'tag-slug', 'id' => 11]); // throws RouteNotFoundException

# url

Generates a URL based on the route name and parameters.

/**
 * @param string $name name of the route.
 * @param array $parameters 'parameter name` => `parameter value`.
 * @param string|null $host host component of the URI.
 * @param bool|null $secure If `true`, then `https`. If `false`, then `http`. If `null`, then without the protocol.
 */
public function url(
    string $name,
    array $parameters = [],
    string $host = null,
    bool $secure = null
): string;

If the route does not exist, the HttpSoft\Router\Exception\RouteNotFoundException exception will be thrown.

If the host or the parameter value does not match its regular expression, or the required parameter is null, the HttpSoft\Router\Exception\InvalidRouteParameterException exception will be thrown.

use HttpSoft\Router\Route;

/**
 * @var mixed $handler
 * @var HttpSoft\Router\RouteCollection $routes
 */

$routes->set((new Route('home', '/', $handler)));
$routes->url('home', [], 'any-host.com'); // '//any-host.com'
$routes->url('home', [], 'any-host.com', true); // 'https://any-host.com'
$routes->url('home', [], 'any-host.com', false); // 'http://any-host.com'

$routes->set((new Route('post', '/post/{id}', $handler))
    ->tokens(['id' => '\d+'])
    ->host('(shop|blog).example.com')
);

$routes->url('post', ['id' => 11]); // '/post/11'
$routes->url('post', ['id' => 11], 'shop.example.com'); // '//shop.example.com/post/11'
$routes->url('post', ['id' => '1'], 'blog.example.com', true); // 'https://blog.example.com/post/1'
$routes->url('post', ['id' => '1'], 'shop.example.com', false); // 'http://shop.example.com/post/1'

$routes->url('post'); // throws InvalidRouteParameterException
$routes->url('post', ['id' => null]);; // throws InvalidRouteParameterException
$routes->url('post', ['id' => 'slug']);; // throws InvalidRouteParameterException
$routes->url('post', ['id' => 11], 'forum.example.com');; // throws InvalidRouteParameterException
$routes->url('not-exist', ['id' => 11]); // throws RouteNotFoundException

If no host has been passed, then this method will be equivalent to the path() method.