# Класс HttpSoft\Router\Route
Класс, представляющий один маршрут.
use HttpSoft\Router\Route;
/**
* @var mixed $handler
*/
$route = new Route('page', '/page/{token}', $handler, ['GET', 'POST']);
$route->getName(); // 'page'
$route->getPattern(); // '/page/{token}'
$route->getHandler(); // $handler
$route->getMethods(); // ['GET', 'POST']
$route->getTokens(); // []
$route->getDefaults(); // []
$route->getHost(); // null
$route->getMatchedParameters(); // []
$route->isAllowedMethod('GET'); // true
$route->isAllowedMethod('PUT'); // false
При добавлении параметра-плейсхолдера {token}
в путь по умолчанию будет использоваться регулярное выражение [^/]+
, которое соответствует любым символам, кроме слэша, указывающего на следующий сегмент пути.
Чтобы указать пользовательские регулярные выражения для плейсхолдеров, используйте метод tokens().
$route = (new Route('post.view', '/post/{slug}{format}', $handler))
->tokens(['slug' => '[\w\-]+', 'format' => '\.[a-zA-z]{3,}'])
;
$route->path(['slug' => 'post-slug', 'format' => '.html']); // '/post/post-slug.html'
Вы можете установить для токена значение по умолчанию, используя метод defaults().
$route = (new Route('post.view', '/post/{slug}{format}', $handler))
->tokens(['slug' => '[\w\-]+', 'format' => '\.[a-zA-z]{3,}'])
->defaults(['format' => '.html'])
;
$route->path(['slug' => 'post-slug']); // '/post/post-slug.html'
Используя метод host(), вы можете указать конкретный хост для маршрута.
$route = (new Route('page', '/page', $handler))
->host('example.com')
;
$route->getHost(); // 'example.com'
Токены маршрута, заключенные в [...]
, считаются необязательными.
$route = (new Route('post.list', '/posts{[page]}', $handler))
->tokens(['page' => '\d+'])
;
$route->path(['page' => 33]); // '/posts/33'
$route->path(); // '/posts'
Необязательные параметры ДОЛЖНЫ находиться только в самом конце маршрута.
Обратите внимание, что ведущий слэш не нужно помещать перед токеном необязательного параметра.
Также можно установить значение по умолчанию для токена необязательного параметра.
$route = (new Route('post.list', '/posts{[page]}', $handler))
->tokens(['page' => '\d+'])
->defaults(['page' => '1'])
;
$route->path(); // '/posts/1'
$route->path(['page' => null]); // '/posts'
Иногда бывает полезно иметь маршрут с несколькими необязательными параметрами подряд.
// `{[year/month/day]}` эквивалентно `{[/year/month/day]}`
$route = (new Route('post.archive', '/post/archive{[year/month/day]}', $handler))
->tokens(['year' => '\d{4}', 'month' => '\d{2}', 'day' => '\d{2}'])
;
// '/post/archive'
$route->path(['year' => null, 'month' => null, 'day' => null]);
// или
$route->path();
// '/post/archive/2020/09/12'
$route->path(['year' => '2020', 'month' => '09', 'day' => '12']);
// '/post/archive/2020/09'
$route->path(['year' => '2020', 'month' => '09']);
// '/post/archive/2020'
$route->path(['year' => '2020']);
Данный класс умеет генерировать путь и URL из параметров маршрута, а также проверять совпадение с HTTP-запросом.
use HttpSoft\Message\Uri;
use HttpSoft\Router\Route;
/**
* @var mixed $handler
* @var Psr\Http\Message\ServerRequestInterface $request
*/
$route = (new Route('page', '/page/{require}{[optional]}', $handler))
->tokens(['require' => '\d+', 'optional' => '[\w-]+'])
->defaults(['require' => 1])
->host('example.com')
;
$route->match($request->withUri(new Uri('/page/slug'))); // false
$route->getMatchedParameters(); // []
$route->match($request->withUri(new Uri('/page/11'))); // true
$route->getMatchedParameters(); // ['require' => '11']
$route->match($request->withUri(new Uri('/page/25/slug'))); // true
$route->getMatchedParameters(); // ['require' => '11', 'optional' => 'slug']
$route->path(); // '/page/1'
$route->path(['require' => 11]); // '/page/11'
$route->path(['require' => 11, 'optional' => 'slug']); // '/page/11/slug'
$route->url(['require' => 11]); // '//example.com/page/11'
$route->url(['require' => '123'], true); // 'https://example.com/page/123'
$route->url(['require' => '123'], false); // 'http://example.com/page/123'
# Публичные методы
/**
* @param string $name уникальное название маршрута.
* @param string $pattern шаблон пути с параметрами.
* @param mixed $handler action, controller, callable, closure и т.д.
* @param array $methods разрешенные методы запроса для маршрута.
*/
public function __construct(string $name, string $pattern, $handler, array $methods = []);
# getName
Возвращает уникальное имя маршрута.
public function getName(): string;
# getPattern
Возвращает шаблон пути с параметрами.
public function getPattern(): string;
# getHandler
Возвращает обработчик маршрута.
/**
* @return mixed
*/
public function getHandler();
# getMethods
Возвращает разрешенные методы запроса для маршрута.
/**
* @return string[]
*/
public function getMethods(): array;
# getTokens
Возвращает токены параметров (имена параметров
=> регулярные выражения
).
/**
* @return array<string, string|null>
*/
public function getTokens(): array;
# getDefaults
Возвращает значения параметров по умолчанию (имена параметров
=> значения по умолчанию
).
/**
* @return array<string, string>
*/
public function getDefaults(): array;
# getHost
Возвращает хост маршрута или null
, если хост не был установлен.
public function getHost(): ?string;
# getMatchedParameters
Возвращает совпавшие параметры имена параметров
=> значения параметров
.
/**
* @return array<string, string>
*/
public function getMatchedParameters(): array;
Совпадающие параметры могут появиться только после успешного выполнения метода match().
# isAllowedMethod
Проверяет, разрешен ли метод запроса для текущего маршрута.
public function isAllowedMethod(string $method): bool;
Передаваемый метод является регистронезависимым.
# tokens
Добавляет токены параметров и возвращает себя.
/**
* @param array<string, mixed> $tokens `имена параметров` => `регулярные выражения`
*/
public function tokens(array $tokens): self;
Если токен параметра не является скалярным типом или null
, будет брошено исключение HttpSoft\Router\Exception\InvalidRouteParameterException.
/**
* @var mixed $handler
*/
$route = new Route('page', '/page/{id}', $handler);
$route->getTokens(); // []
$route->tokens(['id' => '\d+']);
$route->getTokens(); // ['id' => '\d+']
$route->tokens(['id' => fn() => null]); // throws InvalidRouteParameterException
# defaults
Добавляет значения параметров по умолчанию и возвращает себя.
/**
* @param array<string, mixed> $defaults `имена параметров` => `значения по умолчанию`
*/
public function defaults(array $defaults): self;
Если значение параметра по умолчанию не является скалярным типом, будет брошено исключение HttpSoft\Router\Exception\InvalidRouteParameterException.
/**
* @var mixed $handler
*/
$route = new Route('page', '/page/{id}', $handler);
$route->getDefaults(); // []
$route->defaults(['id' => 1]);
$route->getDefaults(); // ['id' => 1]
$route->path(); // '/page/1'
$route->defaults(['id' => fn() => null]); // throws InvalidRouteParameterException
# host
Устанавливает хост маршрута и возвращает себя.
/**
* @param string $host имя хоста или регулярное выражение.
*/
public function host(string $host): self;
Все начальные и конечные слэши будут удалены, а все точки в регулярном выражении будут автоматически экранированы.
/**
* @var mixed $handler
*/
$route = new Route('page', '/page/{id}', $handler);
$route->getHost(); // null
// Только для example.com
$route->host('example.com');
$route->getHost(); // 'example.com'
// Только для subdomain.example.com
$route->host('///subdomain.example.com///');
$route->getHost(); // 'subdomain.example.com'
// Для любого поддомена
$route->host('(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?).example.com');
# match
Проверяет, соответствует ли URI запроса текущему маршруту.
public function match(Psr\Http\Message\ServerRequestInterface $request): bool;
Если есть совпадение и маршрут имеет совпадающие параметры, они будут сохранены и доступны с помощью метода getMatchedParameters()
.
use HttpSoft\Message\Uri;
/**
* @var mixed $handler
* @var Psr\Http\Message\ServerRequestInterface $request
*/
$route = (new Route('page', '/page/{id}', $handler))
->tokens(['id' => '\d+'])
;
$route->match($request->withUri(new Uri('/page/11'))); // true
$route->getMatchedParameters(); // ['id' => '11']
$route->match($request->withUri(new Uri('/page/slug'))); // false
$route->getMatchedParameters(); // []
# path
Генерирует путь URL-адреса из параметров маршрута.
/**
* @param array $parameters `имя параметра` => `значение параметра`.
*/
public function path(array $parameters = []): string;
Если значение параметра не соответствует его регулярному выражению или обязательный параметр имеет значение null
, будет брошено исключение HttpSoft\Router\Exception\InvalidRouteParameterException.
/**
* @var mixed $handler
*/
$route = (new Route('post', '/post/{tag}{[id]}', $handler))
->tokens(['tag' => '[\w-]+', 'id' => '\d+'])
;
$route->path(['tag' => 'tag-slug', 'id' => '11']); // '/post/tag-slug/11'
$route->path(['tag' => 'tag-slug', 'id' => null]); // '/post/tag-slug'
$route->path(['tag' => 'tag-slug']); // '/post/tag-slug'
$route->path(); // throws InvalidRouteParameterException
$route->path(['tag' => null]); // throws InvalidRouteParameterException
$route->path(['id' => 11]); // throws InvalidRouteParameterException
$route->path(['tag' => 'tag-slug', 'id' => 'slug']); // throws InvalidRouteParameterException
# url
Генерирует URL-адрес из параметров маршрута.
/**
* @param array $parameters `имя параметра` => `значение параметра`.
* @param bool|null $secure Если `true`, то `https`. Если `false`, то `http`. Если `null`, то без протокола.
*/
public function url(array $parameters = [], bool $secure = null): string;
Если хост или значение параметра не соответствует его регулярному выражению, или обязательный параметр имеет значение null
, будет брошено исключение HttpSoft\Router\Exception\InvalidRouteParameterException.
/**
* @var mixed $handler
*/
$route = new Route('home', '/', $handler);
$route->url([], 'any-host.com'); // '//any-host.com'
$route->url([], 'any-host.com', true); // 'https://any-host.com'
$route->url([], 'any-host.com', false); // 'http://any-host.com'
$route = (new Route('post', '/post/{id}', $handler))
->tokens(['id' => '\d+'])
->host('(shop|blog).example.com')
;
$route->url(['id' => 11]); // '/post/11'
$route->url(['id' => 11], 'shop.example.com'); // '//shop.example.com/post/11'
$route->url(['id' => '1'], 'blog.example.com', true); // 'https://blog.example.com/post/1'
$route->url(['id' => '1'], 'shop.example.com', false); // 'http://shop.example.com/post/1'
$route->url(); // throws InvalidRouteParameterException
$route->url(['id' => null]);; // throws InvalidRouteParameterException
$route->url(['id' => 'slug']);; // throws InvalidRouteParameterException
$route->url(['id' => 11], 'forum.example.com');; // throws InvalidRouteParameterException
Если хост не был передан, этот метод будет эквивалентен методу path().