Управление URL-адресами в веб-приложениях включает в себя два аспекта. Во-первых, приложению необходимо распарсить запрос пользователя, поступающий в виде URL, на удобоваримые параметры. Во-вторых, приложение должно предоставлять способ формирования адресов URL, с которыми оно сможет корректно работать. В Yii-приложениях эти задачи решаются с использованием класса CUrlManager.
В принципе, адреса URL можно захардкодить прямо в представлениях контроллера, однако куда удобнее создавать их динамически:
$url=$this->createUrl($route,$params);
где $this
относится к экземпляру контроллера; $route
соответствует маршруту запроса,
а $params
является списком параметров GET
для добавления к URL.
По умолчанию, адреса создаются посредством createUrl в get
-формате.
Например, при значениях параметров $route='post/read'
и $params=array('id'=>100)
, получим такой URL:
/index.php?r=post/read&id=100
где параметры указаны в виде набора пар имя=значение
, соединенных знаком &
, а
параметр r
указывает на маршрут. Однако, этот формат не очень
дружелюбен по отношению к пользователю.
Мы можем сделать так, чтобы адрес, приведенный в качестве примера выше, выглядел более аккуратно и понятно
за счет использования формата path
, который исключает использование
строки запроса и включает все GET-параметры в информационную часть адреса URL:
/index.php/post/read/id/100
Для изменения формата представления адреса URL, нужно настроить компонент приложения urlManager таким образом, чтобы метод createUrl мог автоматически переключиться на использование нового формата, а приложение могло корректно воспринимать новый формат адресов URL:
array(
......
'components'=>array(
......
'urlManager'=>array(
'urlFormat'=>'path',
),
),
);
Обратите внимание, что указывать класс компонента urlManager не требуется, т.к. он уже объявлен как CUrlManager в CWebApplication.
Подсказка: Адрес URL, генерируемый методом createUrl является относительным. Для того, чтобы получить абсолютный адрес, нужно добавить префикс, используя
Yii::app()->hostInfo
, или вызвать метод createAbsoluteUrl.
Если в качестве формата адреса URL используется path
, то мы можем определить правила формирования URL, чтобы
сделать адреса более привлекательными и понятными с точки зрения пользователя. Например, мы можем использовать
короткий адрес /post/100
вместо длинного варианта /index.php/post/read/id/100
. CUrlManager использует правила формирования URL
как для создания, так и для обработки адресов.
Правила формирования URL задаются путем конфигурации свойства rules компонента приложения urlManager:
array(
......
'components'=>array(
......
'urlManager'=>array(
'urlFormat'=>'path',
'rules'=>array(
'pattern1'=>'route1',
'pattern2'=>'route2',
'pattern3'=>'route3',
),
),
),
);
Правила задаются в виде массива пар шаблон-путь, где каждая пара соответствует одному правилу. Шаблон правила — строка, которая должна совпадать с путём в URL. Путь правила должен указывать на существующий путь контроллера.
Инфо: Начиная с версии 1.0.6, правилу можно задать свои опции
urlSuffix
иcaseSensitive
. Начиная с версии 1.0.8, правило может содержать параметрdefaultParams
, который представляет собой список пар имя-значение, которые станут частью массива$_GET
. Для настройки правила с этими параметрами, мы должны определить часть правила, отвечающую за маршрут, как массив:'pattern1'=>array('route1', 'urlSuffix'=>'.xml', 'caseSensitive'=>false)
Правило может быть ассоциировано с несколькими GET-параметрами. Эти параметры указываются в шаблоне правила в виде маркеров следующим образом:
<ParamName:ParamPattern>
где ParamName
соответствует имени GET-параметра, а необязательный
ParamPattern
— регулярному выражению, которое используется для проверки
соответствия значению GET-параметра. Если ParamPattern
не указан, то
параметр должен соответствовать любым символам, кроме слэша /
. В момент
создания URL маркеры будут заменены на соответствующие значения параметров,
а в момент обработки URL соответствующие GET-параметрам будут
присвоены результаты обработки.
Для наглядности приведем несколько примеров. Предположим, что наш набор правил состоит из трех правил:
array(
'posts'=>'post/list',
'post/<id:\d+>'=>'post/read',
'post/<year:\d{4}>/<title>'=>'post/read',
)
Вызов $this->createUrl('post/list')
сгенерирует /index.php/posts
. Здесь было применено первое правило.
Вызов $this->createUrl('post/read',array('id'=>100))
сгенерирует /index.php/post/100
. Применено второе правило.
Вызов $this->createUrl('post/read')
сгенерирует /index.php/post/read
. Использовано третье правило.
При использовании createUrl для генерации адреса URL, маршрут и GET-параметры, переданные методу, используются для определения правила, которое нужно применить. Правило применяется в том случае, когда все параметры, ассоциированные с правилом, присутствуют среди GET-параметров, а маршрут соответствует параметру маршрута.
Если же количество GET-параметров больше, чем требует правило, то лишние параметры
будут включены в строку запроса. Например, если вызвать $this->createUrl('post/read',array('id'=>100,'year'=>2008))
,
мы получим /index.php/post/100?year=2008
. Для того, чтобы лишние параметры были отражены в информационной части пути, необходимо
добавить к правилу /*
. Таким образом, используя правило post/<id:\d+>/*
получим URL вида /index.php/post/100/year/2008
.
Как уже говорилось, вторая задача правил URL - парсить URL-запросы. Этот процесс обратный процессу создания URL.
Например, когда пользователь запрашивает /index.php/post/100
, применяется второе правило из примера выше и запрос
преобразовывается в маршрут post/read
и GET-параметр array('id'=>100)
(доступный через $_GET
).
Примечание: Использование правил URL снижает производительность приложения. Это происходит по той причине, что в процессе парсинга запрошенного URL CUrlManager пытается найти соответствие каждому правилу до тех пор, пока какое-нибудь из правил не будет применено. Чем больше правил, тем больший урон производительности. Поэтому в случае высоконагруженных приложений использование правил URL стоит минимизировать.
Начиная с версии 1.0.5, появилась возможность использовать именованные параметры в маршруте правила. Такое правило может быть применено к нескольким марштутам, совпадающим с правилом. Это может помочь уменьшить число правил и, таким образом, повысить производительность приложения.
Для того, чтобы показать параметризацию маршрутов, используем следующий набор правил:
array(
'<_c:(post|comment)>/<id:\d+>/<_a:(create|update|delete)>' => '<_c>/<_a>',
'<_c:(post|comment)>/<id:\d+>' => '<_c>/read',
'<_c:(post|comment)>s' => '<_c>/list',
)
Мы использовали два именованных параметра в маршруте правил: _c
и _a
.
Первый соответствует названию контроллера и может быть равен post
или comment
,
второй — названию action-а и может принимать значения create
, update
или delete
.
Вы можете называть параметры по-другому, если их имена не конфликтуют с GET-параметрами,
которые могут использоваться в URL.
При использовании правил, приведённых выше, URL /index.php/post/123/create
будет обработано как маршрут post/create
с GET-параметромы id=123
.
По маршруту comment/list
с GET-параметром page=2
, мы можем создать URL
/index.php/comments?page=2
.
index.php
С целью сделать адрес URL еще более привлекательным можно спрятать имя входного скрипта index.php
. Для этого необходимо настроить
веб-сервер и компонент приложения urlManager.
Вначале сконфигурируем веб-сервер таким образом, чтобы адрес URL без указания имени входного скрипта все также
передавался на обработку входному скрипту. Для сервера Apache HTTP server это достигается
путем включения механизма преобразования URL и заданием нескольких правил. Для этого
необходимо создать файл /wwwroot/blog/.htaccess
, содержащий правила, приведённые ниже.
Те же правила могут быть размещены в файле конфигурации Apache
в секции Directory
для /wwwroot/blog
.
Options +FollowSymLinks IndexIgnore */* RewriteEngine on # if a directory or a file exists, use it directly RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # otherwise forward it to index.php RewriteRule . index.php
Далее нужно установить свойство showScriptName компонента
urlManager равным false
.
Теперь, вызвав $this->createUrl('post/read',array('id'=>100))
, мы получим URL /post/100
. Что важно, этот
адрес URL будет корректно распознан нашим веб-приложением.
В дополнение ко всему перечисленному выше, мы можем добавить к нашим адресам URL окончание. Например,
мы можем получить /post/100.html
вместо /post/100
, представив пользователю как будто бы статичную страничку.
Для этого нужно просто настроить компонент urlManager путем назначения свойству
urlSuffix любого желаемого окончания.
Signup or Login in order to comment.