Routes are used to determine the controller and action for a requested URI. Every route generates a regular expression which is used to match a URI and a route. Routes may also contain keys which can be used to set the controller, action, and parameters.
Each
// This route will only match when <id> is a digit
Route::set('user', 'user/<action>/<id>', array('id' => '\d+'));
// This route will match when <path> is anything
Route::set('file', '<path>', array('path' => '.*'));
It is also possible to create optional segments by using parentheses in the URI definition:
// This is the standard default route, and no keys are required
Route::set('default', '(<controller>(/<action>(/<id>)))');
// This route only requires the <file> key
Route::set('file', '(<path>/)<file>(.<format>)', array('path' => '.*', 'format' => '\w+'));
Routes also provide a way to generate URIs (called "reverse routing"), which makes them an extremely powerful and flexible way to generate internal links.
Class declared in SYSPATH/classes/route.php on line 3.
string(18) "<([a-zA-Z0-9_]++)>"
string(12) "[^/.,;?\n]++"
string(17) "[.\+*?[^\]${}=!|]"
bool
$cacheIndicates whether routes are cached
bool FALSE
string
$default_actiondefault action for all routes
string(5) "index"
string
$default_protocoldefault protocol for all routes
string(7) "http://"
array
$localhostslist of valid localhost entries
array(4) ( 0 => bool FALSE 1 => string(0) "" 2 => string(5) "local" 3 => string(9) "localhost" )
callback
$_callbackThe callback method for routes
array
$_defaultsarray
$_regexstring
$_route_regexarray
$_routesarray(5) ( "codebench" => object Route(5){ protected _callback => NULL protected _uri => string(19) "codebench(/<class>)" protected _regex => array(0) protected _defaults => array(3) ( "controller" => string(9) "codebench" "action" => string(5) "index" "class" => NULL ) protected _route_regex => string(44) "#^codebench(?:/(?P<class>[^/.,;?\n]++))?$#uD" }
"docs/media" => object Route(5){ protected _callback => NULL protected _uri => string(20) "guide/media(/<file>)" protected _regex => array(1) ( "file" => string(2) ".+" ) protected _defaults => array(3) ( "controller" => string(9) "userguide" "action" => string(5) "media" "file" => NULL ) protected _route_regex => string(35) "#^guide/media(?:/(?P<file>.+))?$#uD" }
"docs/api" => object Route(5){ protected _callback => NULL protected _uri => string(19) "guide/api(/<class>)" protected _regex => array(1) ( "class" => string(13) "[a-zA-Z0-9_]+" ) protected _defaults => array(3) ( "controller" => string(9) "userguide" "action" => string(3) "api" "class" => NULL ) protected _route_regex => string(45) "#^guide/api(?:/(?P<class>[a-zA-Z0-9_]+))?$#uD" }
"docs/guide" => object Route(5){ protected _callback => NULL protected _uri => string(25) "guide(/<module>(/<page>))" protected _regex => array(1) ( "page" => string(2) ".+" ) protected _defaults => array(3) ( "controller" => string(9) "userguide" "action" => string(4) "docs" "module" => string(0) "" ) protected _route_regex => string(59) "#^guide(?:/(?P<module>[^/.,;?\n]++)(?:/(?P<page>.+))?)?$#uD" }
"default" => object Route(5){ protected _callback => NULL protected _uri => string(32) "(<controller>(/<action>(/<id>)))" protected _regex => array(0) protected _defaults => array(2) ( "controller" => string(7) "welcome" "action" => string(5) "index" ) protected _route_regex => string(95) "#^(?:(?P<controller>[^/.,;?\n]++)(?:/(?P<action>[^/.,;?\n]++)(?:/(?P<id>[^/.,;?\n]++))?)?)?$#uD" }
)
string
$_uriroute URI
Creates a new route. Sets the URI and regular expressions for keys. Routes should always be created with Route::set or they will not be properly stored.
$route = new Route($uri, $regex);
The $uri parameter can either be a string for basic regex matching or it can be a valid callback or anonymous function (php 5.3+). If you use a callback or anonymous function, your method should return an array containing the proper keys for the route. If you want the route to be "reversable", you need pass the route string as the third parameter.
$route = new Route(function($uri)
{
if (list($controller, $action, $param) = explode('/', $uri) AND $controller == 'foo' AND $action == 'bar')
{
return array(
'controller' => 'foobar',
'action' => $action,
'id' => $param,
);
},
'foo/bar/<id>'
});
mixed
$uri
= NULL - Route URI pattern or lambda/callback functionarray
$regex
= NULL - Key patternsvoid
public function __construct($uri = NULL, $regex = NULL)
{
if ($uri === NULL)
{
// Assume the route is from cache
return;
}
if ( ! is_string($uri) AND is_callable($uri))
{
$this->_callback = $uri;
$this->_uri = $regex;
$regex = NULL;
}
elseif ( ! empty($uri))
{
$this->_uri = $uri;
}
if ( ! empty($regex))
{
$this->_regex = $regex;
}
// Store the compiled regex locally
$this->_route_regex = Route::compile($uri, $regex);
}
Retrieves all named routes.
$routes = Route::all();
array
- Routes by namepublic static function all()
{
return Route::$_routes;
}
Saves or loads the route cache. If your routes will remain the same for a long period of time, use this to reload the routes from the cache rather than redefining them on every page load.
if ( ! Route::cache())
{
// Set routes here
Route::cache(TRUE);
}
boolean
$save
= bool FALSE - Cache the current routesvoid
- When saving routesboolean
- When loading routespublic static function cache($save = FALSE)
{
if ($save === TRUE)
{
// Cache all defined routes
Kohana::cache('Route::cache()', Route::$_routes);
}
else
{
if ($routes = Kohana::cache('Route::cache()'))
{
Route::$_routes = $routes;
// Routes were cached
return Route::$cache = TRUE;
}
else
{
// Routes were not cached
return Route::$cache = FALSE;
}
}
}
Returns the compiled regular expression for the route. This translates keys and optional groups to a proper PCRE regular expression.
$compiled = Route::compile(
'<controller>(/<action>(/<id>))',
array(
'controller' => '[a-z]+',
'id' => '\d+',
)
);
string
public static function compile($uri, array $regex = NULL)
{
if ( ! is_string($uri))
return;
// The URI should be considered literal except for keys and optional parts
// Escape everything preg_quote would escape except for : ( ) < >
$expression = preg_replace('#'.Route::REGEX_ESCAPE.'#', '\\\\$0', $uri);
if (strpos($expression, '(') !== FALSE)
{
// Make optional parts of the URI non-capturing and optional
$expression = str_replace(array('(', ')'), array('(?:', ')?'), $expression);
}
// Insert default regex for keys
$expression = str_replace(array('<', '>'), array('(?P<', '>'.Route::REGEX_SEGMENT.')'), $expression);
if ($regex)
{
$search = $replace = array();
foreach ($regex as $key => $value)
{
$search[] = "<$key>".Route::REGEX_SEGMENT;
$replace[] = "<$key>$value";
}
// Replace the default regex with the user-specified regex
$expression = str_replace($search, $replace, $expression);
}
return '#^'.$expression.'$#uD';
}
Provides default values for keys when they are not present. The default action will always be "index" unless it is overloaded here.
$route->defaults(array(
'controller' => 'welcome',
'action' => 'index'
));
array
$defaults
= NULL - Key values$this
public function defaults(array $defaults = NULL)
{
$this->_defaults = $defaults;
return $this;
}
Retrieves a named route.
$route = Route::get('default');
string
$name
required - Route nameRoute
public static function get($name)
{
if ( ! isset(Route::$_routes[$name]))
{
throw new Kohana_Exception('The requested route does not exist: :route',
array(':route' => $name));
}
return Route::$_routes[$name];
}
Returns whether this route is an external route to a remote controller.
boolean
public function is_external()
{
return ! in_array(Arr::get($this->_defaults, 'host', FALSE), Route::$localhosts);
}
Tests if the route matches a given URI. A successful match will return all of the routed parameters as an array. A failed match will return boolean FALSE.
// Params: controller = users, action = edit, id = 10
$params = $route->matches('users/edit/10');
This method should almost always be used within an if/else block:
if ($params = $route->matches($uri))
{
// Parse the parameters
}
string
$uri
required - URI to matcharray
- On successFALSE
- On failurepublic function matches($uri)
{
if ($this->_callback)
{
$closure = $this->_callback;
$params = call_user_func($closure, $uri);
if ( ! is_array($params))
return FALSE;
}
else
{
if ( ! preg_match($this->_route_regex, $uri, $matches))
return FALSE;
$params = array();
foreach ($matches as $key => $value)
{
if (is_int($key))
{
// Skip all unnamed keys
continue;
}
// Set the value for all matched keys
$params[$key] = $value;
}
}
foreach ($this->_defaults as $key => $value)
{
if ( ! isset($params[$key]) OR $params[$key] === '')
{
// Set default values for any key that was not matched
$params[$key] = $value;
}
}
return $params;
}
Get the name of a route.
$name = Route::name($route)
Route
$route
required - Instancestring
public static function name(Route $route)
{
return array_search($route, Route::$_routes);
}
Stores a named route and returns it. The "action" will always be set to "index" if it is not defined.
Route::set('default', '(<controller>(/<action>(/<id>)))')
->defaults(array(
'controller' => 'welcome',
));
string
$name
required - Route namestring
$uri_callback
= NULL - URI patternarray
$regex
= NULL - Regex patterns for route keysRoute
public static function set($name, $uri_callback = NULL, $regex = NULL)
{
return Route::$_routes[$name] = new Route($uri_callback, $regex);
}
Generates a URI for the current route based on the parameters given.
// Using the "default" route: "users/profile/10"
$route->uri(array(
'controller' => 'users',
'action' => 'profile',
'id' => '10'
));
array
$params
= NULL - URI parametersstring
public function uri(array $params = NULL)
{
// Start with the routed URI
$uri = $this->_uri;
if (strpos($uri, '<') === FALSE AND strpos($uri, '(') === FALSE)
{
// This is a static route, no need to replace anything
if ( ! $this->is_external())
return $uri;
// If the localhost setting does not have a protocol
if (strpos($this->_defaults['host'], '://') === FALSE)
{
// Use the default defined protocol
$params['host'] = Route::$default_protocol.$this->_defaults['host'];
}
else
{
// Use the supplied host with protocol
$params['host'] = $this->_defaults['host'];
}
// Compile the final uri and return it
return rtrim($params['host'], '/').'/'.$uri;
}
while (preg_match('#\([^()]++\)#', $uri, $match))
{
// Search for the matched value
$search = $match[0];
// Remove the parenthesis from the match as the replace
$replace = substr($match[0], 1, -1);
while (preg_match('#'.Route::REGEX_KEY.'#', $replace, $match))
{
list($key, $param) = $match;
if (isset($params[$param]))
{
// Replace the key with the parameter value
$replace = str_replace($key, $params[$param], $replace);
}
else
{
// This group has missing parameters
$replace = '';
break;
}
}
// Replace the group in the URI
$uri = str_replace($search, $replace, $uri);
}
while (preg_match('#'.Route::REGEX_KEY.'#', $uri, $match))
{
list($key, $param) = $match;
if ( ! isset($params[$param]))
{
// Look for a default
if (isset($this->_defaults[$param]))
{
$params[$param] = $this->_defaults[$param];
}
else
{
// Ungrouped parameters are required
throw new Kohana_Exception('Required route parameter not passed: :param', array(
':param' => $param,
));
}
}
$uri = str_replace($key, $params[$param], $uri);
}
// Trim all extra slashes from the URI
$uri = preg_replace('#//+#', '/', rtrim($uri, '/'));
if ($this->is_external())
{
// Need to add the host to the URI
$host = $this->_defaults['host'];
if (strpos($host, '://') === FALSE)
{
// Use the default defined protocol
$host = Route::$default_protocol.$host;
}
// Clean up the host and prepend it to the URI
$uri = rtrim($host, '/').'/'.$uri;
}
return $uri;
}
Create a URL from a route name. This is a shortcut for:
echo URL::site(Route::get($name)->uri($params), $protocol);
string
$name
required - Route namearray
$params
= NULL - URI parametersmixed
$protocol
= NULL - Protocol string or boolean, adds protocol and domainstring
public static function url($name, array $params = NULL, $protocol = NULL)
{
$route = Route::get($name);
// Create a URI with the route and convert it to a URL
if ($route->is_external())
return Route::get($name)->uri($params);
else
return URL::site(Route::get($name)->uri($params), $protocol);
}