Modules

Kohana_Route

This class is a transparent base class for Route and should not be accessed directly.

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>', 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.

package
Kohana
category
Base
author
Kohana Team
copyright
© 2008-2012 Kohana Team
license
http://kohanaframework.org/license

Class declared in SYSPATH/classes/Kohana/Route.php on line 36.

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

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>))',
    array(
      '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(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';
}

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(array(
    '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)
    {
        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!

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',
			array(':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 = 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;
}

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(array(
        '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(array(
    '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(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;
}

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