Spec-Zone.ru › Yii 2.0

Маршрутизация и создание URL-адресов

  1. Форматы URL-адресов
  2. Маршрутизация
  3. Создание URL-адресов
  4. Использование красивых URL-адресов
  5. Нормализация URL-адресов
  6. Соображения по производительности

Когда приложение Yii начинает обработку запрошенного URL-адреса, первым шагом является разбор URL-адреса в маршрут. Маршрут затем используется для создания соответствующего действия контроллера, которое будет обрабатывать запрос. Весь этот процесс называется маршрутизацией.

Обратный процесс маршрутизации называется созданием URL-адресов, который создаёт URL-адрес по заданному маршруту и связанным параметрам запроса. Когда созданный URL-адрес впоследствии запрашивается, процесс маршрутизации может восстановить его обратно в исходный маршрут и параметры запроса.

Центральной частью, ответственной за маршрутизацию и создание URL-адресов, является менеджер URL-адресов, который регистрируется в качестве компонента urlManager приложения. Менеджер URL-адресов предоставляет метод parseRequest() для разбора входящего запроса в маршрут и связанные параметры запроса, а также метод createUrl() для создания URL-адреса по заданному маршруту и связанным параметрам запроса.

Настроив компонент urlManager в конфигурации приложения, вы можете позволить приложению распознавать произвольные форматы URL-адресов без модификации существующего кода приложения. Например, можно использовать следующий код для создания URL-адреса для действия post/view:

use yii\helpers\Url;

// Url::to() calls UrlManager::createUrl() to create a URL
$url = Url::to(['post/view', 'id' => 100]);

В зависимости от конфигурации urlManager, созданный URL-адрес может выглядеть как один из следующих (или другого формата). И если созданный URL-адрес запрашивается позже, он по-прежнему будет разборён обратно в исходный маршрут и значение параметра запроса.

/index.php?r=post%2Fview&id=100
/index.php/post/100
/posts/100

Форматы URL-адресов

Менеджер URL-адресов поддерживает два формата URL-адресов:

  • стандартный формат URL-адреса;
  • формат красивых URL-адресов.

Стандартный формат URL-адреса использует параметр запроса с именем r для представления маршрута и обычные параметры запроса для представления параметров запроса, связанных с маршрутом. Например, URL /index.php?r=post/view&id=100 представляет маршрут post/view и параметр запроса id со значением 100. Стандартный формат URL-адреса не требует настройки менеджера URL-адресов и работает в любой настройке веб-сервера.

Формат красивых URL-адресов использует дополнительный путь после имени скрипта входа для представления маршрута и связанных параметров запроса. Например, дополнительный путь в URL /index.php/post/100 это /post/100, который может представлять маршрут post/view и параметр запроса id со значением 100 с соответствующим правилом URL-адреса. Для использования формата красивых URL-адресов необходимо разработать набор правил URL-адресов в соответствии с конкретными требованиями к внешнему виду URL-адресов.

Можно переключаться между двумя форматами URL-адресов, переключая свойство enablePrettyUrl менеджера URL-адресов без изменения другого кода приложения.

Маршрутизация

Маршрутизация включает два шага:

  • входящий запрос анализируется в маршрут и связанные с ним параметры запроса;
  • создаётся действие контроллера, соответствующее обработанному маршруту, для обработки запроса.

При использовании стандартного формата URL-адреса разбор запроса в маршрут сводится к получению значения параметра запроса с именем GET с именем r.

При использовании формата красивых URL-адресов менеджер URL-адресов проверит зарегистрированные правила URL-адресов для поиска соответствующего, которое может преобразовать запрос в маршрут. Если такое правило не найдено, будет выброшено исключение yii\web\NotFoundHttpException.

После того, как запрос был преобразован в маршрут, пришло время создать действие контроллера, определённое маршрутом. Маршрут разбивается на несколько частей с помощью косых черт. Например, site/index будет разбито на site и index. Каждая часть является идентификатором, который может ссылаться на модуль, контроллер или действие. Начиная с первой части маршрута, приложение выполняет следующие действия для создания модулей (если таковые имеются), контроллера и действия:

  1. Устанавливает приложение как текущий модуль.
  2. Проверяет, содержит ли карта контроллеров текущего модуля текущий идентификатор. Если да, объект контроллера будет создан в соответствии с конфигурацией контроллера, найденной в карте, и будет выполнен шаг 5 для обработки оставшейся части маршрута.
  3. Проверяет, относится ли идентификатор к модулю, указанному в свойстве модулей текущего модуля. Если да, модуль создаётся в соответствии с конфигурацией, найденной в списке модулей, и шаг 2 будет выполнен для обработки следующей части маршрута в контексте только что созданного модуля.
  4. Обрабатывает идентификатор как идентификатор контроллера и создаёт объект контроллера. Выполняется следующий шаг с оставшейся частью маршрута.
  5. Контроллер ищет текущий идентификатор в своей карте действий. Если найден, он создаёт действие в соответствии с конфигурацией, найденной в карте. В противном случае контроллер попытается создать встроенное действие, которое определяется методом действия, соответствующим текущему идентификатору действия.

На любом из указанных этапов, если возникает ошибка, выводится исключение yii\web\NotFoundHttpException, указывающее на сбой процесса маршрутизации.

Стандартный маршрут

Когда запрос обрабатывается в пустой маршрут, используется так называемый стандартный маршрут. По умолчанию стандартный маршрут составляет site/index, который относится к действию index контроллера site. Можно настроить его, настроив свойство defaultRoute приложения в конфигурации приложения, как показано ниже:

[
    // ...
    'defaultRoute' => 'main/index',
];

Аналогично стандартному маршруту приложения, существует также стандартный маршрут для модулей. Например, если есть модуль user и запрос обрабатывается в маршрут user, используется стандартный маршрут модуля для определения контроллера. По умолчанию имя контроллера составляет default. Если в defaultRoute не указано действие, используется свойство defaultAction контроллера для определения действия. В данном примере весь маршрут составлял бы user/default/index.

catchAll Маршрут

Иногда необходимо временно перевести веб-приложение в режим технического обслуживания и отображать одну и ту же страницу с информацией для всех запросов. Есть много способов для достижения этой цели. Однако один из самых простых способов заключается в настройке свойства yii\web\Application::$catchAll, как показано ниже, в конфигурации приложения:

[
    // ...
    'catchAll' => ['site/offline'],
];

С данной настройкой будет использоваться действие site/offline для обработки всех входящих запросов.

Свойство catchAll должно содержать массив, первая позиция которого указывает маршрут, а последующие элементы (имя-значение) указывают параметры, которые должны быть привязаны к действию.

Информация: Панель отладки в среде разработки не будет работать, когда это свойство включено.

Создание URL-адресов

Yii предоставляет вспомогательный метод yii\helpers\Url::to() для создания различных типов URL-адресов по заданным маршрутам и связанным параметрам запроса. Например,

use yii\helpers\Url;

// creates a URL to a route: /index.php?r=post%2Findex
echo Url::to(['post/index']);

// creates a URL to a route with parameters: /index.php?r=post%2Fview&id=100
echo Url::to(['post/view', 'id' => 100]);

// creates an anchored URL: /index.php?r=post%2Fview&id=100#content
echo Url::to(['post/view', 'id' => 100, '#' => 'content']);

// creates an absolute URL: http://www.example.com/index.php?r=post%2Findex
echo Url::to(['post/index'], true);

// creates an absolute URL using the https scheme: https://www.example.com/index.php?r=post%2Findex
echo Url::to(['post/index'], 'https');

Обратите внимание, что в данном примере предполагается, что используется стандартный формат URL-адреса. Если включён формат красивых URL-адресов, созданные URL-адреса будут отличаться в соответствии с правилами URL-адресов.

Маршрут, передаваемый методу yii\helpers\Url::to(), зависит от контекста. Он может быть либо относительным маршрутом, либо абсолютным маршрутом, который будет нормализован в соответствии со следующими правилами:

  • Если маршрут пустой строкой, будет использоваться текущий запрашиваемый маршрут;
  • Если маршрут вообще не содержит косых черт, он рассматривается как идентификатор действия текущего контроллера и предваряется значением uniqueId текущего контроллера;
  • Если маршрут не имеет начальной косой черты, он считается маршрутом, относительным к текущему модулю, и предваряется значением uniqueId текущего модуля.

Начиная с версии 2.0.2, можно указать маршрут в виде псевдонима. В этом случае псевдоним сначала преобразуется в фактический маршрут, который затем преобразуется в абсолютный маршрут в соответствии с вышеуказанными правилами.

Например, предположим, что текущий модуль admin и текущий контроллер post,

use yii\helpers\Url;

// currently requested route: /index.php?r=admin%2Fpost%2Findex
echo Url::to(['']);

// a relative route with action ID only: /index.php?r=admin%2Fpost%2Findex
echo Url::to(['index']);

// a relative route: /index.php?r=admin%2Fpost%2Findex
echo Url::to(['post/index']);

// an absolute route: /index.php?r=post%2Findex
echo Url::to(['/post/index']);

// using an alias "@posts", which is defined as "/post/index": /index.php?r=post%2Findex
echo Url::to(['@posts']);

Метод yii\helpers\Url::to() реализуется путём вызова методов createUrl() и createAbsoluteUrl() менеджера URL-адресов. В следующих разделах мы объясним, как настроить менеджер URL-адресов для настройки формата создаваемых URL-адресов.

Метод yii\helpers\Url::to() также поддерживает создание URL-адресов, которые не связаны с конкретными маршрутами. В этом случае вместо массива в качестве первого параметра необходимо передать строку. Например,

use yii\helpers\Url;

// currently requested URL: /index.php?r=admin%2Fpost%2Findex
echo Url::to();

// an aliased URL: http://example.com
Yii::setAlias('@example', 'http://example.com/');
echo Url::to('@example');

// an absolute URL: http://example.com/images/logo.gif
echo Url::to('/images/logo.gif', true);

Помимо метода to(), вспомогательный класс yii\helpers\Url также предоставляет несколько других удобных методов создания URL-адресов. Например,

use yii\helpers\Url;

// home page URL: /index.php?r=site%2Findex
echo Url::home();

// the base URL, useful if the application is deployed in a sub-folder of the Web root
echo Url::base();

// the canonical URL of the currently requested URL
// see https://en.wikipedia.org/wiki/Canonical_link_element
echo Url::canonical();

// remember the currently requested URL and retrieve it back in later requests
Url::remember();
echo Url::previous();

Использование красивых URL-адресов

Для использования красивых URL-адресов настройте компонент urlManager в конфигурации приложения, как показано ниже:

[
    'components' => [
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'enableStrictParsing' => false,
            'rules' => [
                // ...
            ],
        ],
    ],
]

Свойство enablePrettyUrl является обязательным, поскольку оно переключает формат красивых URL. Остальные свойства являются необязательными. Однако приведенная выше конфигурация чаще всего используется.

  • showScriptName: это свойство определяет, следует ли включать имя входного скрипта в созданные URL. Например, вместо создания URL /index.php/post/100, установив это свойство в false, будет сгенерирован URL /post/100.
  • enableStrictParsing: это свойство определяет, следует ли включить строгое разбор запросов. Если строгое разбор включено, запрашиваемый URL должен соответствовать хотя бы одному из правил, чтобы быть обработанным как допустимый запрос; в противном случае будет выброшено исключение yii\web\NotFoundHttpException. Если строгое разбор отключено, когда ни одно из правил не соответствует запрошенному URL, часть пути URL будет обработана как запрашиваемый маршрут.
  • rules: это свойство содержит список правил, определяющих, как анализировать и создавать URL. Это основное свойство, с которым вам следует работать, чтобы создавать URL, формат которых удовлетворяет требованиям вашего конкретного приложения.

Примечание: Для того чтобы скрыть имя входного скрипта в созданных URL, помимо установки showScriptName в значение false, вам также может потребоваться настроить веб-сервер таким образом, чтобы он мог правильно определить, какой скрипт PHP должен быть выполнен, когда запрашиваемый URL не указывает его явно. Если вы используете веб-сервер Apache или nginx, вы можете обратиться к рекомендуемой конфигурации, описанной в разделе Установка.

Правила URL

Правило URL — это класс, реализующий yii\web\UrlRuleInterface, обычно yii\web\UrlRule. Каждое правило URL состоит из шаблона, используемого для сопоставления части пути URL, маршрута и нескольких параметров запроса. Правило URL может использоваться для анализа запроса, если его шаблон соответствует запрошенному URL. Правило URL может использоваться для создания URL, если его маршрут и имена параметров запроса соответствуют заданным.

Когда включен формат красивых URL, менеджер URL использует правила URL, объявленные в его свойстве rules, для анализа входящих запросов и создания URL. В частности, для анализа входящего запроса менеджер URL рассматривает правила в порядке их объявления и ищет первое правило, которое соответствует запрошенному URL. Соответствующее правило затем используется для анализа URL в маршрут и связанные параметры. Аналогично, для создания URL менеджер URL ищет первое правило, которое соответствует заданному маршруту и параметрам, и использует его для создания URL.

Вы можете настроить yii\web\UrlManager::$rules в виде массива, ключами которого являются шаблоны, а значениями — соответствующие маршруты. Каждая пара «шаблон-маршрут» создает правило URL. Например, следующая конфигурация правил объявляет два правила URL. Первое правило соответствует URL posts и отображает его в маршрут post/index. Второе правило соответствует URL, соответствующему регулярному выражению post/(\d+), и отображает его в маршрут post/view и определяет параметр запроса с именем id.

'rules' => [
    'posts' => 'post/index',
    'post/<id:\d+>' => 'post/view',
]

Информация: Шаблон в правиле используется для сопоставления части пути URL. Например, часть пути /index.php/post/100?source=ad составляет post/100 (ведущие и завершающие косые черты игнорируются), что соответствует шаблону post/(\d+).

Помимо объявления правил URL как пар «шаблон-маршрут», вы также можете объявлять их как конфигурационные массивы. Каждый конфигурационный массив используется для настройки объекта одного правила URL. Это часто необходимо, когда вы хотите настроить другие свойства правила URL. Например,

'rules' => [
    // ...other url rules...
    [
        'pattern' => 'posts',
        'route' => 'post/index',
        'suffix' => '.json',
    ],
]

По умолчанию, если вы не укажете опцию class для конфигурации правила, она будет использовать по умолчанию класс yii\web\UrlRule, который является значением по умолчанию, определенным в yii\web\UrlManager::$ruleConfig.

Именованные параметры

Правило URL может быть связано с именованными параметрами запроса, которые указываются в шаблоне в формате <ParamName:RegExp>, где ParamName задаёт имя параметра, а RegExp — необязательное регулярное выражение, используемое для сопоставления значений параметра. Если RegExp не указано, это означает, что значение параметра должно быть строкой без каких-либо косых черт.

Примечание: Вы можете использовать регулярные выражения только внутри параметров. Остальная часть шаблона считается обычным текстом.

Когда правило используется для анализа URL, оно заполняет связанные параметры значениями, соответствующими соответствующим частям URL, и эти параметры будут доступны в $_GET позже компонентом приложения request. Когда правило используется для создания URL, оно принимает значения предоставленных параметров и вставляет их в места, где объявлены параметры.

Давайте рассмотрим несколько примеров, чтобы проиллюстрировать, как работают именованные параметры. Предположим, что мы объявили следующие три правила URL:

'rules' => [
    'posts/<year:\d{4}>/<category>' => 'post/index',
    'posts' => 'post/index',
    'post/<id:\d+>' => 'post/view',
]

Когда правила используются для анализа URL:

  • /index.php/posts анализируется в маршрут post/index с использованием второго правила;
  • /index.php/posts/2014/php анализируется в маршрут post/index, параметр year, значение которого 2014, и параметр category, значение которого php с использованием первого правила;
  • /index.php/post/100 анализируется в маршрут post/view и параметр id, значение которого 100, с использованием третьего правила;
  • /index.php/posts/php вызовет исключение yii\web\NotFoundHttpException, когда yii\web\UrlManager::$enableStrictParsing равно true, поскольку оно не соответствует ни одному из шаблонов. Если yii\web\UrlManager::$enableStrictParsing равно false (значение по умолчанию), часть пути posts/php будет возвращена как маршрут. Это либо выполнит соответствующее действие, если оно существует, либо выбросит исключение yii\web\NotFoundHttpException в противном случае.

И когда правила используются для создания URL:

  • Url::to(['post/index']) создает /index.php/posts с использованием второго правила;
  • Url::to(['post/index', 'year' => 2014, 'category' => 'php']) создает /index.php/posts/2014/php с использованием первого правила;
  • Url::to(['post/view', 'id' => 100]) создает /index.php/post/100 с использованием третьего правила;
  • Url::to(['post/view', 'id' => 100, 'source' => 'ad']) создаёт /index.php/post/100?source=ad с использованием третьего правила. Поскольку параметр source не указан в правиле, он добавляется как параметр запроса в созданный URL.
  • Url::to(['post/index', 'category' => 'php']) создает /index.php/post/index?category=php без использования какого-либо правила. Обратите внимание, что поскольку ни одно правило не применимо, URL создаётся путём простого добавления маршрута как части пути и всех параметров как части строки запроса.

Параметризация маршрутов

Вы можете встроить имена параметров в маршрут правила URL. Это позволяет использовать правило URL для сопоставления нескольких маршрутов. Например, следующие правила встраивают параметры controller и action в маршруты.

'rules' => [
    '<controller:(post|comment)>/create' => '<controller>/create',
    '<controller:(post|comment)>/<id:\d+>/<action:(update|delete)>' => '<controller>/<action>',
    '<controller:(post|comment)>/<id:\d+>' => '<controller>/view',
    '<controller:(post|comment)>s' => '<controller>/index',
]

Для анализа URL /index.php/comment/100/update, будет применено второе правило, которое устанавливает параметр controller в значение comment и параметр action в значение update. Маршрут <controller>/<action> таким образом разрешается как comment/update.

Аналогично, для создания URL для маршрута comment/index, будет применено последнее правило, которое создаёт URL /index.php/comments.

Информация: Параметризация маршрутов позволяет значительно сократить количество правил URL, что может существенно повысить производительность менеджера URL.

Значения параметров по умолчанию

По умолчанию все параметры, объявленные в правиле, являются обязательными. Если запрошенный URL не содержит определённого параметра, или если URL создаётся без определённого параметра, правило не будет применено. Чтобы сделать некоторые параметры необязательными, можно настроить свойство defaults правила. Параметры, указанные в этом свойстве, являются необязательными и принимают указанные значения, когда они не предоставлены.

В следующем объявлении правила параметры page и tag являются необязательными и принимают значение 1 и пустую строку соответственно, когда они не указаны.

'rules' => [
    // ...other rules...
    [
        'pattern' => 'posts/<page:\d+>/<tag>',
        'route' => 'post/index',
        'defaults' => ['page' => 1, 'tag' => ''],
    ],
]

Вышеуказанное правило может быть использовано для анализа или создания любого из следующих URL:

  • /index.php/posts: page равно 1, tag равно ''.
  • /index.php/posts/2: page равно 2, tag равно ''.
  • /index.php/posts/2/news: page равно 2, tag равно 'news'.
  • /index.php/posts/news: page равно 1, tag равно 'news'.

Без использования необязательных параметров вам пришлось бы создать 4 правила, чтобы добиться того же результата.

Примечание: Если шаблон содержит только необязательные параметры и косые черты, первый параметр можно опустить только в том случае, если все остальные параметры опущены.

Правила с именами серверов

Возможно включение имён веб-серверов в шаблоны правил URL. Это полезно в основном в тех случаях, когда ваше приложение должно вести себя по-разному для разных имён веб-серверов. Например, следующие правила преобразуют URL http://admin.example.com/login в маршрут admin/user/login и http://www.example.com/login в site/login.

'rules' => [
    'http://admin.example.com/login' => 'admin/user/login',
    'http://www.example.com/login' => 'site/login',
]

Вы также можете встраивать параметры в имена серверов, чтобы извлекать динамическую информацию из них. Например, следующее правило преобразует URL http://en.example.com/posts в маршрут post/index и параметр language=en.

'rules' => [
    'http://<language:\w+>.example.com/posts' => 'post/index',
]

С версии 2.0.11 вы также можете использовать протокольно-относительные шаблоны, которые работают как для http, так и для https. Синтаксис такой же, как выше, но без части http:, например: '//www.example.com/login' => 'site/login'.

Примечание: Правила с именами серверов не должны включать подпапку скрипта входа в их шаблонах. Например, если скрипт входа в приложение находится по адресу http://www.example.com/sandbox/blog/index.php, то вы должны использовать шаблон http://www.example.com/posts вместо http://www.example.com/sandbox/blog/posts. Это позволит развернуть ваше приложение в любом каталоге без необходимости изменения правил URL. Yii автоматически определит базовый URL приложения.

Суффиксы URL

Вам может потребоваться добавить суффиксы к URL для различных целей. Например, вы можете добавить .html к URL, чтобы они выглядели как URL для статических HTML-страниц; вы также можете добавить .json к URL, чтобы указать ожидаемый тип контента ответа. Вы можете достичь этой цели, настроив свойство yii\web\UrlManager::$suffix в конфигурации приложения следующим образом:

[
    // ...
    'components' => [
        'urlManager' => [
            'enablePrettyUrl' => true,
            // ...
            'suffix' => '.html',
            'rules' => [
                // ...
            ],
        ],
    ],
]

Данная настройка позволит менеджеру URL распознавать запрошенные URL и также создавать URL с .html в качестве суффикса.

Подсказка: Вы можете установить / в качестве суффикса URL, чтобы все URL заканчивались слешем.

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

Иногда вам может потребоваться использовать разные суффиксы для разных URL. Этого можно достичь, настроив свойство suffix отдельных правил URL. Когда в правиле URL установлено это свойство, оно переопределяет настройку суффикса на уровне менеджера URL. Например, следующая конфигурация содержит настраиваемое правило URL, которое использует .json в качестве суффикса вместо глобального суффикса .html.

[
    'components' => [
        'urlManager' => [
            'enablePrettyUrl' => true,
            // ...
            'suffix' => '.html',
            'rules' => [
                // ...
                [
                    'pattern' => 'posts',
                    'route' => 'post/index',
                    'suffix' => '.json',
                ],
            ],
        ],
    ],
]

HTTP-методы

При реализации RESTful API часто требуется, чтобы один и тот же URL был проанализирован в разные маршруты в зависимости от используемых HTTP-методов. Это легко достигается путем добавления поддерживаемых HTTP-методов к шаблонам правил. Если правило поддерживает несколько HTTP-методов, разделять имена методов запятыми. Например, следующие правила имеют одинаковый шаблон post/<id:\d+> с различной поддержкой HTTP-методов. Запрос к PUT post/100 будет проанализирован в post/update, а запрос к GET post/100 будет проанализирован в post/view.

'rules' => [
    'PUT,POST post/<id:\d+>' => 'post/update',
    'DELETE post/<id:\d+>' => 'post/delete',
    'post/<id:\d+>' => 'post/view',
]

Примечание: Если правило URL содержит HTTP-методы(ы) в своем шаблоне, правило будет использоваться только для целей анализа, если GET входит в указанные глаголы. Оно будет пропущено, когда менеджер URL вызывается для создания URL.

Подсказка: Для упрощения маршрутизации RESTful API Yii предоставляет специальный класс правил URL yii\rest\UrlRule, который очень эффективен и поддерживает некоторые интересные функции, такие как автоматическое множественное число идентификаторов контроллеров. Для получения более подробной информации, пожалуйста, обратитесь к разделу Маршрутизация в главе RESTful API.

Динамическое добавление правил

Правила URL могут быть динамически добавлены к менеджеру URL. Это часто требуется перераспределяемым модулям, которые хотят управлять своими правилами URL. Для того, чтобы динамически добавленные правила вступали в силу во время процесса маршрутизации, вы должны добавить их во время стадии инициализации приложения. Для модулей это означает, что они должны реализовать yii\base\BootstrapInterface и добавить правила в метод bootstrap(), как показано ниже:

public function bootstrap($app)
{
    $app->getUrlManager()->addRules([
        // rule declarations here
    ], false);
}

Обратите внимание, что вы также должны перечислить эти модули в yii\web\Application::bootstrap(), чтобы они могли участвовать в процессе инициализации.

Создание классов правил

Несмотря на то, что стандартный класс yii\web\UrlRule достаточно гибкий для большинства проектов, существуют ситуации, когда вам нужно создавать собственные классы правил. Например, на веб-сайте дилера автомобилей вы можете захотеть поддерживать формат URL, как /Manufacturer/Model, где как Manufacturer, так и Model должны соответствовать некоторым данным, хранящимся в таблице базы данных. Стандартный класс правил здесь не подойдет, так как он полагается на статически объявленные шаблоны.

Мы можем создать следующий класс правил URL для решения этой проблемы.

<?php

namespace app\components;

use yii\web\UrlRuleInterface;
use yii\base\Object;

class CarUrlRule extends Object implements UrlRuleInterface
{
    public function createUrl($manager, $route, $params)
    {
        if ($route === 'car/index') {
            if (isset($params['manufacturer'], $params['model'])) {
                return $params['manufacturer'] . '/' . $params['model'];
            } elseif (isset($params['manufacturer'])) {
                return $params['manufacturer'];
            }
        }
        return false; // this rule does not apply
    }

    public function parseRequest($manager, $request)
    {
        $pathInfo = $request->getPathInfo();
        if (preg_match('%^(\w+)(/(\w+))?$%', $pathInfo, $matches)) {
            // check $matches[1] and $matches[3] to see
            // if they match a manufacturer and a model in the database.
            // If so, set $params['manufacturer'] and/or $params['model']
            // and return ['car/index', $params]
        }
        return false; // this rule does not apply
    }
}

И использовать новый класс правил в конфигурации yii\web\UrlManager::$rules:

'rules' => [
    // ...other rules...
    [
        'class' => 'app\components\CarUrlRule',
        // ...configure other properties...
    ],
]

Нормализация URL

С версии 2.0.10 UrlManager может быть настроен для использования UrlNormalizer для обработки различных вариантов одного URL, например, с и без конечного слеша. Поскольку технически http://example.com/path и http://example.com/path/ являются разными URL, обслуживание одного и того же контента для обоих может ухудшить рейтинг SEO. По умолчанию нормализатор сворачивает последовательные слэши, добавляет или удаляет конечные слэши в зависимости от того, есть ли у суффикса конечный слэш, и перенаправляет на нормализованную версию URL с использованием постоянного перенаправления. Нормализующий компонент можно настроить глобально для менеджера URL или индивидуально для каждого правила — по умолчанию каждое правило будет использовать нормализатор из менеджера URL. Вы можете установить UrlRule::$normalizer на false для отключения нормализации для конкретного правила URL.

Следующее показывает пример конфигурации для UrlNormalizer:

'urlManager' => [
    'enablePrettyUrl' => true,
    'showScriptName' => false,
    'enableStrictParsing' => true,
    'suffix' => '.html',
    'normalizer' => [
        'class' => 'yii\web\UrlNormalizer',
        // use temporary redirection instead of permanent for debugging
        'action' => UrlNormalizer::ACTION_REDIRECT_TEMPORARY,
    ],
    'rules' => [
        // ...other rules...
        [
            'pattern' => 'posts',
            'route' => 'post/index',
            'suffix' => '/',
            'normalizer' => false, // disable normalizer for this rule
        ],
        [
            'pattern' => 'tags',
            'route' => 'tag/index',
            'normalizer' => [
                // do not collapse consecutive slashes for this rule
                'collapseSlashes' => false,
            ],
        ],
    ],
]

Примечание: По умолчанию UrlManager::$normalizer отключен. Вам необходимо явно настроить его, чтобы включить нормализацию URL.

Учёт производительности

При разработке сложного веб-приложения важно оптимизировать правила URL, чтобы время обработки запросов и создания URL было минимальным.

Использование параметризованных маршрутов может сократить количество правил URL, что значительно улучшит производительность.

При анализе или создании URL менеджер URL проверяет правила URL в порядке их объявления. Поэтому вы можете рассмотреть возможность корректировки порядка правил URL, чтобы более специфические и/или чаще используемые правила располагались перед менее используемыми.

Если некоторые правила URL имеют одинаковый префикс в своих шаблонах или маршрутах, вы можете рассмотреть использование yii\web\GroupUrlRule, чтобы они могли быть более эффективно проверены менеджером URL как группа. Это часто встречается, когда ваше приложение состоит из модулей, каждый из которых имеет свой собственный набор правил URL с идентификатором модуля в качестве общих префиксов.

© 2008–2017 by Yii Software LLC
Licensed under the three clause BSD license.
http://www.yiiframework.com/doc-2.0/guide-runtime-routing.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API