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(26) "\(((?:(?>[^()]+)|(?R))*)\)"
string(18) "<([a-zA-Z0-9_]++)>"
string(12) "[^/.,;?\n]++"
string(17) "[.\+*?[^\]${}=!|]"
bool
$cachelink to thisIndicates whether routes are cached
bool FALSE
string
$default_actionlink to thisdefault action for all routes
string(5) "index"
string
$default_protocollink to thisdefault protocol for all routes
string(7) "http://"
array
$localhostslink to thislist of valid localhost entries
array(4) ( 0 => bool FALSE 1 => string(0) "" 2 => string(5) "local" 3 => string(9) "localhost" )
array
$_defaultslink to thisarray(2) ( "action" => string(5) "index" "host" => bool FALSE )
array
$_filterslink to thisroute filters
array(0)
array
$_regexlink to thisarray(0)
string
$_route_regexlink to thisNULL
array
$_routeslink to thisarray(5) ( "codebench" => object Route(5){ protected _filters => array(0) 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 _filters => array(0) 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 _filters => array(0) 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 _filters => array(0) 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 _filters => array(0) 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
$_urilink to thisroute URI
string(0) ""
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 should be a string for basic regex matching.
string
$uri
= NULL - Route URI patternarray
$regex
= NULL - Key patternsvoid
public
function
__construct(
$uri
= NULL,
$regex
= NULL)
{
if
(
$uri
=== NULL)
{
// Assume the route is from cache
return
;
}
if
( !
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 name
public
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 routesboolean
$append
= bool FALSE - Append, rather than replace, cached routes when loadingvoid
- When saving routesboolean
- When loading routes
public
static
function
cache(
$save
= FALSE,
$append
= FALSE)
{
if
(
$save
=== TRUE)
{
try
{
// Cache all defined routes
Kohana::cache(
'Route::cache()'
, Route::
$_routes
);
}
catch
(Exception
$e
)
{
// We most likely have a lambda in a route, which cannot be cached
throw
new
Kohana_Exception(
'One or more routes could not be cached (:message)'
,
array
(
':message'
=>
$e
->getMessage(),
), 0,
$e
);
}
}
else
{
if
(
$routes
= Kohana::cache(
'Route::cache()'
))
{
if
(
$append
)
{
// Append cached routes
Route::
$_routes
+=
$routes
;
}
else
{
// Replace existing routes
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)
{
// 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'
));
If no parameter is passed, this method will act as a getter.
array
$defaults
= NULL - Key values$this
- Or array
public
function
defaults(
array
$defaults
= NULL)
{
if
(
$defaults
=== NULL)
{
return
$this
->_defaults;
}
$this
->_defaults =
$defaults
;
return
$this
;
}
Filters to be run before route parameters are returned:
$route
->filter(
function
(Route
$route
,
$params
, Request
$request
)
{
if
(
$request
->method() !== HTTP_Request::POST)
{
return
FALSE;
// This route only matches POST requests
}
if
(
$params
AND
$params
[
'controller'
] ===
'welcome'
)
{
$params
[
'controller'
] =
'home'
;
}
return
$params
;
}
);
To prevent a route from matching, return FALSE
. To replace the route
parameters, return an array.
Default parameters are added before filters are called!
array
$callback
required - Callback string, array, or closure$this
public
function
filter(
$callback
)
{
if
( !
is_callable
(
$callback
))
{
throw
new
Kohana_Exception(
'Invalid Route::callback specified'
);
}
$this
->_filters[] =
$callback
;
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 Request. 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(Request::factory(
'users/edit/10'
));
This method should almost always be used within an if/else block:
if
(
$params
=
$route
->matches(
$request
))
{
// Parse the parameters
}
Request
$request
required - Request object to matcharray
- On successFALSE
- On failure
public
function
matches(Request
$request
)
{
// Get the URI from the Request
$uri
= trim(
$request
->uri(),
'/'
);
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
;
}
}
if
( !
empty
(
$params
[
'controller'
]))
{
// PSR-0: Replace underscores with spaces, run ucwords, then replace underscore
$params
[
'controller'
] =
str_replace
(
' '
,
'_'
, ucwords(
str_replace
(
'_'
,
' '
,
$params
[
'controller'
])));
}
if
( !
empty
(
$params
[
'directory'
]))
{
// PSR-0: Replace underscores with spaces, run ucwords, then replace underscore
$params
[
'directory'
] =
str_replace
(
' '
,
'_'
, ucwords(
str_replace
(
'_'
,
' '
,
$params
[
'directory'
])));
}
if
(
$this
->_filters)
{
foreach
(
$this
->_filters
as
$callback
)
{
// Execute the filter giving it the route, params, and request
$return
= call_user_func(
$callback
,
$this
,
$params
,
$request
);
if
(
$return
=== FALSE)
{
// Filter has aborted the match
return
FALSE;
}
elseif
(
is_array
(
$return
))
{
// Filter has modified the parameters
$params
=
$return
;
}
}
}
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
= NULL - URI patternarray
$regex
= NULL - Regex patterns for route keysRoute
public
static
function
set(
$name
,
$uri
= NULL,
$regex
= NULL)
{
return
Route::
$_routes
[
$name
] =
new
Route(
$uri
,
$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)
{
if
(
$params
)
{
// @issue #4079 rawurlencode parameters
$params
=
array_map
(
'rawurlencode'
,
$params
);
// decode slashes back, see Apache docs about AllowEncodedSlashes and AcceptPathInfo
$params
=
str_replace
(
array
(
'%2F'
,
'%5C'
),
array
(
'/'
,
'\\'
),
$params
);
}
$defaults
=
$this
->_defaults;
/**
* Recursively compiles a portion of a URI specification by replacing
* the specified parameters and any optional parameters that are needed.
*
* @param string $portion Part of the URI specification
* @param boolean $required Whether or not parameters are required (initially)
* @return array Tuple of the compiled portion and whether or not it contained specified parameters
*/
$compile
=
function
(
$portion
,
$required
)
use
(&
$compile
,
$defaults
,
$params
)
{
$missing
=
array
();
$pattern
=
'#(?:'
.Route::REGEX_KEY.
'|'
.Route::REGEX_GROUP.
')#'
;
$result
= preg_replace_callback(
$pattern
,
function
(
$matches
)
use
(&
$compile
,
$defaults
, &
$missing
,
$params
, &
$required
)
{
if
(
$matches
[0][0] ===
'<'
)
{
// Parameter, unwrapped
$param
=
$matches
[1];
if
(isset(
$params
[
$param
]))
{
// This portion is required when a specified
// parameter does not match the default
$required
= (
$required
OR ! isset(
$defaults
[
$param
]) OR
$params
[
$param
] !==
$defaults
[
$param
]);
// Add specified parameter to this result
return
$params
[
$param
];
}
// Add default parameter to this result
if
(isset(
$defaults
[
$param
]))
return
$defaults
[
$param
];
// This portion is missing a parameter
$missing
[] =
$param
;
}
else
{
// Group, unwrapped
$result
=
$compile
(
$matches
[2], FALSE);
if
(
$result
[1])
{
// This portion is required when it contains a group
// that is required
$required
= TRUE;
// Add required groups to this result
return
$result
[0];
}
// Do not add optional groups to this result
}
},
$portion
);
if
(
$required
AND
$missing
)
{
throw
new
Kohana_Exception(
'Required route parameter not passed: :param'
,
array
(
':param'
=> reset(
$missing
))
);
}
return
array
(
$result
,
$required
);
};
list(
$uri
) =
$compile
(
$this
->_uri, TRUE);
// 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
->uri(
$params
);
else
return
URL::site(
$route
->uri(
$params
),
$protocol
);
}