Modules

Route
extends Kohana_Route

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 will be translated to a regular expression using a default regular expression pattern. You can override the default pattern by providing a pattern for the key:

// This route will only match when <id> is a digit
Route::set('user', 'user/<action>/<id>', ['id' => '\d+']);

// This route will match when <path> is anything
Route::set('file', '<path>', ['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>)', ['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.

package
Kohana
category
Base
author
Kohana Team
copyright
© 2008-2012 Kohana Team
license
https://kohana.top/license

Class declared in SYSPATH/classes/Route.php on line 3.

Constants

REGEX_GROUP

string(26) "\(((?:(?>[^()]+)|(?R))*)\)"

REGEX_KEY

string(18) "<([a-zA-Z0-9_]++)>"

REGEX_SEGMENT

string(12) "[^/.,;?\n]++"

REGEX_ESCAPE

string(17) "[.\+*?[^\]${}=!|]"

Properties

public static bool $cache

Indicates whether routes are cached

bool FALSE

public static string $default_action

default action for all routes

string(5) "index"

public static string $default_protocol

default protocol for all routes

string(7) "http://"

public static array $localhosts

list of valid localhost entries

array(4) (
    0 => bool FALSE
    1 => string(0) ""
    2 => string(5) "local"
    3 => string(9) "localhost"
)

protected array $_defaults

Default value:
array(2) (
    "action" => string(5) "index"
    "host" => bool FALSE
)

protected array $_filters

route filters

Default value:
array(0) 

protected array $_regex

Default value:
array(0) 

protected string $_route_regex

Default value:
NULL

protected static array $_routes

array(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"
    }
)

protected string $_uri

route URI

Default value:
string(0) ""

Methods

public __construct( [ string $uri = NULL , array $regex = NULL ] ) (defined in Kohana_Route)

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.

Parameters

  • string $uri = NULL - Route URI pattern
  • array $regex = NULL - Key patterns

Tags

Return Values

  • void

Source Code

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);
}

public static all( ) (defined in Kohana_Route)

Retrieves all named routes.

$routes = Route::all();

Return Values

  • array - Routes by name

Source Code

public static function all()
{
    return Route::$_routes;
}

public static cache( [ boolean $save = bool FALSE , boolean $append = bool FALSE ] ) (defined in Kohana_Route)

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);
}

Parameters

  • boolean $save = bool FALSE - Cache the current routes
  • boolean $append = bool FALSE - Append, rather than replace, cached routes when loading

Tags

Return Values

  • void - When saving routes
  • boolean - When loading routes

Source Code

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)', [
            ':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;
        }
    }
}

public static compile( ) (defined in Kohana_Route)

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>))', [
      'controller' => '[a-z]+',
      'id' => '\d+',
    ]
);

Tags

Return Values

  • string

Source Code

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(['(', ')'], ['(?:', ')?'], $expression);
    }

    // Insert default regex for keys
    $expression = str_replace(['<', '>'], ['(?P<', '>' . Route::REGEX_SEGMENT . ')'], $expression);

    if ($regex) {
        $search = $replace = [];
        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';
}

public defaults( [ array $defaults = NULL ] ) (defined in Kohana_Route)

Provides default values for keys when they are not present. The default action will always be "index" unless it is overloaded here.

$route->defaults([
    'controller' => 'welcome',
    'action' => 'index'
]);

If no parameter is passed, this method will act as a getter.

Parameters

  • array $defaults = NULL - Key values

Return Values

  • $this - Or array

Source Code

public function defaults(array $defaults = null)
{
    if ($defaults === null) {
        return $this->_defaults;
    }

    $this->_defaults = $defaults;

    return $this;
}

public filter( array $callback ) (defined in Kohana_Route)

Filters to be run before route parameters are returned:

$route->filter(function(Route $route, $params, Request $request) {
    // This route only matches POST requests
    if ($request->method() !== HTTP_Request::POST) {
        return false;
    }
    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!

Parameters

  • array $callback required - Callback string, array, or closure

Tags

Return Values

  • $this

Source Code

public function filter($callback)
{
    if (!is_callable($callback)) {
        throw new Kohana_Exception('Invalid Route::callback specified');
    }

    $this->_filters[] = $callback;

    return $this;
}

public static get( string $name ) (defined in Kohana_Route)

Retrieves a named route.

$route = Route::get('default');

Parameters

  • string $name required - Route name

Tags

Return Values

  • Route

Source Code

public static function get($name)
{
    if (!isset(Route::$_routes[$name])) {
        throw new Kohana_Exception('The requested route does not exist: :route', [':route' => $name]);
    }

    return Route::$_routes[$name];
}

public is_external( ) (defined in Kohana_Route)

Returns whether this route is an external route to a remote controller.

Return Values

  • boolean

Source Code

public function is_external()
{
    return !in_array(Arr::get($this->_defaults, 'host', false), Route::$localhosts);
}

public matches( Request $request ) (defined in Kohana_Route)

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
}

Parameters

  • Request $request required - Request object to match

Return Values

  • array - On success
  • false - On failure

Source Code

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 = [];
    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;
}

public static name( Route $route ) (defined in Kohana_Route)

Get the name of a route.

$name = Route::name($route)

Parameters

  • Route $route required - Instance

Return Values

  • string

Source Code

public static function name(Route $route)
{
    return array_search($route, Route::$_routes);
}

public static set( string $name [, string $uri = NULL , array $regex = NULL ] ) (defined in Kohana_Route)

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([
        'controller' => 'welcome',
    ]);

Parameters

  • string $name required - Route name
  • string $uri = NULL - URI pattern
  • array $regex = NULL - Regex patterns for route keys

Return Values

  • Route

Source Code

public static function set($name, $uri = null, $regex = null)
{
    return Route::$_routes[$name] = new Route($uri, $regex);
}

public uri( [ array $params = NULL ] ) (defined in Kohana_Route)

Generates a URI for the current route based on the parameters given.

// Using the "default" route: "users/profile/10"
$route->uri([
    'controller' => 'users',
    'action' => 'profile',
    'id' => '10'
]);

Parameters

  • array $params = NULL - URI parameters

Tags

Return Values

  • string

Source Code

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(['%2F', '%5C'], ['/', '\\'], $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 = [];

        $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', [':param' => reset($missing)]);
        }

        return [$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;
}

public static url( string $name [, array $params = NULL , mixed $protocol = NULL ] ) (defined in Kohana_Route)

Create a URL from a route name. This is a shortcut for:

echo URL::site(Route::get($name)->uri($params), $protocol);

Parameters

  • string $name required - Route name
  • array $params = NULL - URI parameters
  • mixed $protocol = NULL - Protocol string or boolean, adds protocol and domain

Tags

Return Values

  • string

Source Code

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);
}