The main task of any route class is to determine whether this given route matches the HTTP request, and on match return the set of parameters by which a controller and action can be determined. An opposite task a route class allows to generate a URL by parameters. This feature can be used in your controller action methods for generating URLs, for example, for redirecting a user to another page. It can also be used inside view templates for generating hyperlinks.
Your web pages usually contain hyperlinks to other pages. These links may point either
to a page internal to your site or to a page on another site. A hyperlink is represented by <a>
HTML tag
having href
attribute specifying the URL of the destination page. Below, an example of a hyperlink
pointing to an external page is presented:
<a href="http://example.com/path/to/page">A link to another site page</a>
When you generate a hyperlink to a resource internal to your site, you typically use relative URL (without host name):
<a href="/path/to/internal/page">A link to internal page</a>
To generate URLs in your view templates (.phtml files), you can use the Url
view helper class,
which takes the route name as an input argument:
<!-- A hyperlink to Home page -->
<a href="<?= $this->url('home'); ?>">Home page</a>
<!-- A hyperlink to About page -->
<a href="<?= $this->url('about'); ?>">About page</a>
In the lines above, we generate two relative URLs. In line 2, we call the Url
view helper
and pass the "home" route name as its parameter. In line 5, we pass the "about" route name as
an argument for the Url
view helper.
In the example above, the
Url
view helper internally uses theRouteMatch
object and calls theLiteral
route to assemble the URL string by route name.
After the PhpRenderer
class executes the view template's
code, the output HTML markup will be the following:
<!-- A hyperlink to Home page -->
<a href="/">Home page</a>
<!-- A hyperlink to About page -->
<a href="/about">About page</a>
If a route uses some variable parameters, you should pass them to the Url
view helper
as the second argument:
<!-- A hyperlink to About page -->
<a href="<?= $this->url('application', ['action' => 'about']); ?>" >
About page
</a>
<!-- A hyperlink to Barcode image -->
<a href="<?= $this->url('application', ['action' => 'barcode',
'type' => 'code39', 'text' => 'HELLO-WORLD']); ?>" >
Barcode image </a>
In the example above, we use Url
view helper to generate the two
URLs by route name and parameters. We pass the "application"
route name as the first argument, and an array of parameters
as the second argument.
In line 2, we pass the "action" parameter to tell the Segment route class that it should substitute the corresponding wildcard in the route string with the "about" string.
After the PhpRenderer
class executes the view template's
code, the output HTML markup will be the following:
<!-- A hyperlink to About page -->
<a href="/application/about" > About page </a>
<!-- A hyperlink to Barcode image -->
<a href="/application/barcode/code39/HELLO-WORLD" > Barcode image </a>
As another example, let's try to generate a URL for our Regex route (the one which serves our "static" pages):
<!-- A hyperlink to Introduction page -->
<a href="<?= $this->url('doc', ['page'=>'introduction']); ?>">
Introduction </a>
This will generate the following HTML markup:
<!-- A hyperlink to Introduction page -->
<a href="/doc/introduction.html"> Introduction </a>
If you need to generate an absolute URL (having the scheme and host name),
you can specify the third parameter for the Url
view helper. The third parameter
should be an array containing one or several options. For assembling the absolute
URL, pass the force_canonical
option, as in the example below:
<!-- A hyperlink to Home page -->
<a href="<?= $this->url('home', [], ['force_canonical' => true]); ?>" >
Home page </a>
<!-- A hyperlink to About page -->
<a href="<?php echo $this->url('application', ['action' => 'about'],
['force_canonical' => true]); ?>" > About page </a>
In line 2 of the example above, we pass the "home" route name as the first
argument, empty array as the second argument, and an array containing force_canonical
option as the third argument. In lines 6-7, we also pass the force_canonical
option
as the third argument for generating the URL of the About page.
The resulting HTML markup of the code above will be as follows:
<!-- A hyperlink to Home page -->
<a href="http://localhost/" > Home page </a>
<!-- A hyperlink to About page -->
<a href="http://localhost/application/index/about" > About page </a>
If you want your URL to have a query part, you can specify the query
option in
the third argument of the Url
view helper. For example, assume you have the "search"
action in some controller (and a route mapped to this action), and you want to pass it search query string and count of output results
per page. The URL for this action would be like this: "http://localhost/search?q=topic&count=10".
To generate such a URL, you can use the following code:
<a href="<?= $this->url('search', [], ['force_canonical' => true,
'query'=>['q'=>'topic', 'count'=>10]]); ?>" >
Search </a>
In the code above, we specified the query
option, which is the array containing name=>value
pairs of the query parameters.
You can generate URLs inside your controller's action methods using the Url
controller
plugin. To generate a URL, you call the Url
controller plugin's fromRoute()
method, as in the example
below:
// An example action method
public function someAction()
{
// Generate a URL pointing to the Home page ('/')
$url1 = $this->url()->fromRoute('home');
// Generate an absolute URL pointing to the About page
// ('http://localhost/application/about')
$url2 = $this->url()->fromRoute('application',
['action'=>'about'], ['force_canonical'=>true]);
}
The arguments the
Url
plugin takes and their meaning are identical to theUrl
view helper's ones. So, you can generate absolute or relative URLs the same way you did in your view templates.
When generating URLs either with the Url
view helper or with the Url
controller plugin,
you should remember that URLs may only contain "safe" characters from ASCII character set. Thus,
if you pass the parameter containing unsafe characters, these characters will be replaced with
the sequence of the percentage character and two digits.
For example, let's try to generate a URL for our Regex route and pass it the "page" parameter with the value "/chapter1/introduction".
<!-- A hyperlink to Introduction page -->
<a href="<?= $this->url('doc', ['page'=>'chapter1/introduction']); ?>">
Introduction </a>
We could assume it generates the URL like "/doc/chapter1/introduction.html". But because the slash ('/') character is unsafe, it will be replaced with the "%2F" characters for security reasons, and we will have the following HTML code:
<!-- A hyperlink to Introduction page -->
<a href="/doc/chapter1%2Fintroduction.html"> Introduction </a>
Unfortunately, this hyperlink is unusable, because it won't match our Regex route.