lithium\net\http\Router::match()
Attempts to match an array of route parameters (i.e. 'controller'
, 'action'
, etc.)
against a connected Route
object. For example, given the following route:
Router::connect('/login', ['controller' => 'users', 'action' => 'login']);
This will match:
$url = Router::match(['controller' => 'users', 'action' => 'login']);
// returns /login
For URLs templates with no insert parameters (i.e. elements like {:id}
that are replaced
with a value), all parameters must match exactly as they appear in the route parameters.
Alternatively to using a full array, you can specify routes using a more compact syntax. The above example can be written as:
$url = Router::match('Users::login'); // still returns /login
You can combine this with more complicated routes; for example:
Router::connect('/posts/{:id:\d+}', ['controller' => 'posts', 'action' => 'view']);
This will match:
$url = Router::match(['controller' => 'posts', 'action' => 'view', 'id' => '1138']);
// returns /posts/1138
Again, you can specify the same URL with a more compact syntax, as in the following:
$url = Router::match(['Posts::view', 'id' => '1138']);
// again, returns /posts/1138
You can use either syntax anywhere an URL is accepted, i.e. when redirecting
or creating links using the Html
helper.
Parameters
-
array|string
$url
An array of parameters to match, or paremeters in their shorthand form (i.e.
'Posts::view'
). Also takes non-routed, manually generated URL strings. -
\lithium\action\Request
$context
This supplies the context for any persistent parameters, as well as the base URL for the application.
-
array
$options
Options for the generation of the matched URL. Currently accepted values are:
'absolute'
boolean: Indicates whether or not the returned URL should be an absolute path (i.e. including scheme and host name).'host'
string: If'absolute'
istrue
, sets the host name to be used, or overrides the one provided in$context
.'scheme'
string: If'absolute'
istrue
, sets the URL scheme to be used, or overrides the one provided in$context
.'scope'
string: Optionnal scope name.
Returns
stringReturns a generated URL, based on the URL template of the matched route, and prefixed with the base URL of the application.
Source
public static function match($url = [], $context = null, array $options = []) {
$options = static::_matchOptions($url, $context, $options);
if (is_string($url = static::_prepareParams($url, $context, $options))) {
return $url;
}
$base = $options['base'];
$url += ['action' => 'index'];
$stack = [];
$suffix = isset($url['#']) ? "#{$url['#']}" : null;
unset($url['#']);
$scope = $options['scope'];
if (isset(static::$_configurations[$scope])) {
foreach (static::$_configurations[$scope] as $route) {
if (!$match = $route->match($url + ['scope' => static::attached($scope)], $context)) {
continue;
}
if ($route->canContinue()) {
$stack[] = $match;
$export = $route->export();
$keys = $export['match'] + $export['keys'] + $export['defaults'];
unset($keys['args']);
$url = array_diff_key($url, $keys);
continue;
}
if ($stack) {
$stack[] = $match;
$match = static::_compileStack($stack);
}
$path = rtrim("{$base}{$match}{$suffix}", '/') ?: '/';
$path = ($options) ? static::_prefix($path, $context, $options) : $path;
return $path ?: '/';
}
}
$url = static::_formatError($url);
$message = "No parameter match found for URL `{$url}`";
$message .= $scope ? " in `{$scope}` scope." : '.';
throw new RoutingException($message);
}