A free and open-source book on ZF3 for beginners


5.10. Generating URLs from Route

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.

5.10.1. Generating URLs in View Templates

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 the RouteMatch object and calls the Literal 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>

5.10.1.1. Passing Parameters

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>

5.10.1.2. Generating Absolute URLs

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>

5.10.1.3. Specifying Query Part

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.

5.10.2. Generating URLs in Controllers

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 the Url view helper's ones. So, you can generate absolute or relative URLs the same way you did in your view templates.

5.10.3. URL Encoding

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.


Top