A free and open-source book on ZF3 for beginners


5.10. Генерация URL из маршрута

Главная задача любого класса маршрута - определить, соответствует ли этот маршрут HTTP-запроса, и при удачном сопоставлении вернуть набор параметров, по которым могут быть определены контроллер и действие. В то же время, обратная задача позволяет генерировать URL с использованием этих параметров. Это может использоваться в методах действия контроллера для генерации URL: например, для перенаправления пользователя на другую страницу. Также это можно использовать в шаблонах представления для генерации гиперссылок.

5.10.1. Генерация URL в шаблонах представлений

Веб-страницы обычно содержат гиперссылки на другие страницы. Эти ссылки могут указывать как на страницу вашего сайта, так и на другой сайт. Для определения гиперссылки используется HTML-тег <a>, который имеет атрибут href, определяющий URL страницы, на которую надо перейти. Ниже представлен образец гиперссылки, указывающей на внешнюю страницу:

<a href="http://example.com/path/to/page">A link to another site page</a>

При генерации гиперссылки на внутренний ресурс сайта, как правило, используется относительный URL (без имени хоста):

<a href="/path/to/internal/page">A link to internal page</a>

Чтобы сгенерировать URL в шаблонах представления (файлы .phtml), можно использовать класс помощника вида Url, который принимает в качестве аргумента имя маршрута:

<!-- Гиперссылка на страницу Home -->
<a href="<?= $this->url('home'); ?>">Home page</a>

<!-- Гиперссылка на страницу About  -->
<a href="<?= $this->url('about'); ?>">About page</a>

Здесь мы генерируем два относительных URL. В строке 2 мы вызываем помощник вида Url и передаем в качестве параметра имя маршрута "home". В строке 5 мы передаем имя маршрута "about" в качестве аргумента для помощника вида Url.

В примере выше помощник вида Url внутренне использует объект RouteMatch и вызывает маршрут типа Literal, чтобы собрать строку URL с помощью имени маршрута.

После выполнения классом PhpRenderer кода шаблона представления, HTML-разметка будет выглядеть следующим образом:

<!-- Гиперссылка на страницу Home -->
<a href="/">Home page</a>

<!-- Гиперссылка на страницу About -->
<a href="/about">About page</a>

5.10.1.1. Передача параметров

Если среди параметров, используемых маршрутом, есть переменные, их следует передать помощнику вида Url в качестве второго аргумента:

<!-- Гиперссылка на страницу About -->
<a href="<?= $this->url('application', ['action' => 'about']); ?>" >
  About page 
</a>

<!-- Гиперссылка на изображение штрих-кода -->
<a href="<?= $this->url('application', ['action' => 'barcode',
  'type' => 'code39', 'text' => 'HELLO-WORLD']); ?>" >
  Barcode image </a>

В этом примере мы используем помощник вида Url для генерации двух URL с помощью имени маршрута и его параметров. Мы передаем имя маршрута "application" в качестве первого аргумента и массив параметров в качестве второго.

В строке 2 мы передаем параметр "action", чтобы сообщить классу маршрута типа Segment, что ему нужно заменить соответствующий шаблон в строке маршрута на строку "about".

После выполнения классом PhpRenderer кода шаблона представления, HTML-разметка будет выглядеть следующим образом:

<!-- Гиперссылка на страницу About -->
<a href="/application/about" > About page </a>

<!-- Гиперссылка на изображение штрих-кода -->
<a href="/application/barcode/code39/HELLO-WORLD" > Barcode image </a>

В качестве другого примера, давайте сгенерируем URL для маршрута типа Regex (который обслуживает "статические" страницы):

<!-- Гиперссылка на страницу Introduction -->
<a href="<?= $this->url('doc', ['page'=>'introduction']); ?>">
 Introduction </a>			  

Таким образом, мы сгенерируем следующую HTML-разметку:

<!-- Гиперссылка на страницу Introduction -->
<a href="/doc/introduction.html"> Introduction </a>

5.10.1.2. Генерация абсолютного URL

Если вам необходимо сгенерировать абсолютный URL (содержащий схему и имя хоста), вы можете указать третий параметр для помощника вида Url. Третий параметр должен быть массивом, содержащим одну или несколько опций. Чтобы собрать URL, нужно передать опцию force_canonical, как показано в примере ниже:

<!-- Гиперссылка на страницу Home -->
<a href="<?= $this->url('home', [], ['force_canonical' => true]); ?>" > 
  Home page </a>
  
<!-- Гиперссылка на страницу About -->
<a href="<?php echo $this->url('application', ['action' => 'about'],
  ['force_canonical' => true]); ?>" > About page </a>

В строке 2 данного примера мы передаем имя маршрута "home" в качестве первого аргумента, пустой массив - в качестве второго и массив, содержащий опцию force_canonical - в качестве третьего. В строках 6-7 мы также передаем опцию force_canonical для генерации URL страницы About.

Получившаяся HTML-разметка будет выглядеть следующим образом:

<!-- Гиперссылка на страницу Home -->
<a href="http://localhost/" > Home page </a>
  
<!-- Гиперссылка на страницу About -->
<a href="http://localhost/application/index/about" > About page </a>

5.10.1.3. Задание запроса (Query)

Если вы хотите, чтобы ваш URL имел часть запроса (query), вы можете указать опцию query в качестве третьего аргумента для помощника вида Url. Например, предположим, что у вас есть действие "search" в некотором контроллере (и маршрут, сопоставленный с этим действием), и вы хотите передать ему строку запроса, а также количество результатов поиска на странице. URL для этого действия будет выглядеть так: "http://localhost/search?q=topic&count=10". Для генерации такого URL используйте следующий код:

<a href="<?= $this->url('search', [], ['force_canonical' => true, 
         'query'=>['q'=>'topic', 'count'=>10]]); ?>" > 
  Search </a>

В этом коде мы задали опцию option, которая является массивом, содержащим пары имя=>значение параметров запроса.

5.10.2. Генерация URL в контроллерах

Вы можете генерировать URL в методах действия вашего контроллера, используя плагин Url. Чтобы сгенерировать URL, нужно вызвать метод fromRoute() данного плагина, как показано в примере ниже:

// Образец метода действия
public function someAction() 
{
    // Генерируем URL, указывающий на страницу Home ('/')
    $url1 = $this->url()->fromRoute('home');
  
    // Генерируем абсолютный URL, указывающий на страницу About
    // ('http://localhost/application/about')
    $url2 = $this->url()->fromRoute('application', 
              ['action'=>'about'], ['force_canonical'=>true]);
}

Аргументы, принимаемые плагином Url, а также их значение, идентичны аргументам помощника вида Url[Zend\View\Helper\Url]. Таким образом, вы можете сгенерировать абсолютные или относительные URL так же, как делали это в шаблонах представлений.

5.10.3. Кодирование URL

При генерации URL как через помощник вида Url, так и через плагин контроллера Url[Zend\Mvc\Controller\Plugin\Url], следует помнить, что URL могут содержать только "безопасные" символы из таблицы ASCII. Поэтому, если вы передадите параметр содержащий небезопасные символы, эти символы будут заменены последовательностью из знака процента и двух цифр.

Попробуем, например, сгенерировать URL для нашего маршрута типа Regex и передать ему параметр "page" со значением "/chapter1/introduction".

<!-- Гиперссылка на страницу Introduction -->
<a href="<?= $this->url('doc', ['page'=>'chapter1/introduction']); ?>">
  Introduction </a>			  

Можно было бы предположить, что сгенерируется URL вида "/doc/chapter1/introduction.html". Но из-за того, что слеш ('/') считается небезопасным символом, в целях безопасности он будет заменен символами "%2F", и в результате мы получим следующий HTML-код:

<!-- Гиперссылка на страницу Introduction -->
<a href="/doc/chapter1%2Fintroduction.html"> Introduction </a>

К сожалению, эта гиперссылка бесполезна, так как она не соответствует нашему маршруту типа Regex.


Top