Документация для разработчиков

Обработка адресов

Понятие обработки адресов

Обработка адресов (UrlRewrite) применяется для того, чтобы скрипт мог отвечать не только по своему физическому, но и по любому другому указаному адресу. Например, можно задать настройки обработки адресов, чтобы скрипт в файле /fld/c.php, отвечающий по адресу

/fld/c.php?id=15

отвечал также по адресу

/catalog/15.php

Адрес, по которому будет отвечать скрипт, не должен физически существовать на сервере. Если такой адрес физически существует, то будет вызван скрипт по этому адресу. Система обработки адресов запущена в этом случае не будет.

Правила обработки

Правила обработки адресов настраиваются отдельно для каждого сайта и хранятся в корне сайта в файле urlrewrite.php. Файл содержит массив $arUrlRewrite, каждая запись которого является правилом обработки адреса. Файл urlrewrite.php имеет следующий вид:

<?
$arUrlRewrite = array(
    array(
        "CONDITION" => "#^/gallery/#",
        "RULE" => "",
        "ID" => "bitrix:photo",
        "PATH" => "/max/images/index.php",
    ),
    array(
        "CONDITION" => "#^/forum/#",
        "ID" => "bitrix:forum",
        "PATH" => "/forum/index.php",
    ),
    array(
        "CONDITION" => "#^/index/([0-9]+)/([0-9]+)/#",
        "RULE" => "mode=read&CID=$1&GID=$2",
        "ID" => "bitrix:catalog.section",
        "PATH" => "/newforum/index.php",
    ),
    array(
        "CONDITION" => "#(.+?)\\.html(.*)#",
        "RULE" => "$1.php$2",
    ),
);
?>

Каждое правило должно содержать уникальное в рамках сайта условие выполнения правила. Условие выполнения записывается в ключ "CONDITION" массива и является шаблоном Perl-совместимого регулярного выражения. Например, условие:

"CONDITION" => "#^/index/([0-9]+)/([0-9]+)/#"

указывает, что данное правило должно применяться для всех адресов, которые начинаются с подстрок вида:

/index/<число>/<число>/

Правило может содержать адрес физически существующего скрипта, который будет подключен при выполнении условия. Этот адрес записывается в ключ "PATH". Например, если в системе обработки адресов зарегистрировано правило:

array(
    "CONDITION" => "#^/gallery/#",
    "PATH" => "/max/images/index.php",
)

и пользователь запросил страницу:

/gallery/38.php

которая физически не существует, то система обработки адресов подключит скрипт:

/max/images/index.php

Правило может содержать правило замены, которое записывается в ключ "RULE". Если правило замены установлено, то адрес реально существующего подключаемого скрипта формируется заменой регулярным варажением условия выполнения (шаблона выражения) на конкатенацию физического пути (ключ "PATH") и правила замены (ключ "RULE"). Например, если в системе обработки адресов зарегистрировано правило:

array(
    "CONDITION" => "#^/index/([0-9]+)/([0-9]+)/#",
    "RULE" => "mode=read&CID=$1&GID=$2",
    "PATH" => "/newforum/index.php",
)

и пользователем запрошена страница:

/index/5/48/

то для формирования адреса скрипта, который будет подключен, выполнится код:

$url = preg_replace("#^/index/([0-9]+)/([0-9]+)/#", "/newforum/index.php?mode=read&CID=$1&GID=$2", "/index/5/48/");

и будет подключен скрипт:

/newforum/index.php?mode=read&CID=5&GID=48

Если в системе обработки адресов зарегистрировано правило:

array(
    "CONDITION" => "#(.+?)\\.html(.*)#",
    "RULE" => "$1.php$2",
)

и пользователем запрошена страница:

/about/company.html?show

то для формирования адреса скрипта, который будет подключен, выполнится код:

$url = preg_replace("#(.+?)\\.html(.*)#", "$1.php$2", "/about/company.html?show");

и будет подключен скрипт:

/about/company.php?show

Правило может содержать имя компонента, который создал это правило. Это имя записывается в ключ "ID". При автоматическом пересоздании файла правил urlrewrite.php с помощью средств административной части сайта пересоздаются только правила, у которых заполнен ключ "ID". Эти правила пересоздаются на основании анализа физических файлов в папке сайта. Правила с пустым ключом "ID" при автоматическом пересоздании файла правил не изменяются.

Подключение системы обработки адресов

Перед началом использования система обработки адресов должна быть подключена на сайте. Для этого необходимо:

  • если у вас на веб-сервере настроена обработка ошибки 404 (например, для Apache установлена директива ErrorDocument 404 /404.php), то вы должны изменить файл /404.php, вставив в самое начало файла команду:
    include_once($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/urlrewrite.php');
  • если вы для Apache используете модуль mod_rewrite, то в его настройках вы можете указать (например, в файле .htaccess):
    <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-l
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteCond %{REQUEST_FILENAME} !/bitrix/urlrewrite.php$
        RewriteRule ^(.*)$ /bitrix/urlrewrite.php [L]
    </IfModule>

Поддержка компонентов 2.0

При добавлении на страницу компонента с поддержкой ЧПУ ("человеко-понятный URL") (если файл сохраняется с помощью API), автоматически создаётся правило обработки адреса. Если страница создаётся не с помощью API, а, например, записывается через FTP, то необходимо выполнить пересоздание правил (кнопка на панели инструментов на странице настройки правил обработки адресов).

Поддержка ЧПУ включается в компоненте с помощью предопределённого входного параметра SEF_MODE. При этом в предопределённом входном параметре SEF_FOLDER устанавливается папка, в которой работает компонент. Папка может быть виртуальной (т.е. физически может не существовать). При сохранении страницы с размещённым на ней компонентом, переключенным в режим ЧПУ (параметр SEF_MODE равен Y), через стандартный интерфейс правило обработки адресов создаётся следующим образом: в ключ условия применения шаблона ("CONDITION") записывается регулярное выражение, полученое из папки в параметре SEF_FOLDER, в ключ "ID" записывается имя компонента, в ключ пути ("PATH") записывается физический адрес страницы.

Например, пусть компонент "bitrix:catalog" размещён на странице /fld/c.php и его подключение выглядит следующим образом:

$APPLICATION->IncludeComponent(
    "bitrix:catalog",
    "",
    Array(
        "SEF_MODE" => "Y",
        "SEF_FOLDER" => "/mycatalog/",
        "IBLOCK_TYPE_ID" => "catalog",
        "BASKET_PAGE_TEMPLATE" => "/personal/basket.php",
    )
);

Тогда при сохранении страницы /fld/c.php в системе обработки адресов добавится запись:

array(
    "CONDITION" => "#^/mycatalog/#",
    "RULE" => "",
    "ID" => "bitrix:catalog",
    "PATH" => "/fld/c.php",
)

Таким образом, при запросе адресов, начинающихся со строки /mycatalog/, будет подключаться скрипт /fld/c.php. В этом скрипте запрошеный адрес может быть проанализирован и выполнены требуемые действия.

См. также



Пользовательские комментарии

Мы будем рады, если разработчики добавят свои комментарии по практическому использованию методов системы.

Для этого нужно всего лишь авторизоваться на сайте

Но помните, что Пользовательские комментарии, несмотря на модерацию, не являются официальной документацией. Ответственность за их использование несет сам пользователь.

Также Пользовательские комментарии не являются местом для обсуждения функционала. По подобным вопросам обращайтесь на форумы.
2
Максим Мамыкин
Есть готовое решение позволяющее задавать произвольную сортировку правил в файле urlrewrite есть бесплатное готовое решение - http://marketplace.1c-bitrix.ru/solutions/cosmos.urlrewrite/
4
Darkness_Paladin
Иногда важно помнить, что проверки на "более точное соответсвие" нет, и правила проверяются в том порядке, как они записаны в файле urlrewrite.php. Например, если два правила записаны так:
Код
   array(
      "CONDITION"   =>   "#^/([a-zA-Z_-]*)/([a-zA-Z_-]*)/([a-zA-Z_-]*)/?#",
      "RULE"   =>   "CODE=$3",
      "ID"   =>   "",
      "PATH"   =>   "/main/page.php",
   ),
   array(
      "CONDITION"   =>   "#^/news/blog/([0-9]+).*/#",
      "RULE"   =>   "ID=$1&$2",
      "ID"   =>   "",
      "PATH"   =>   "/about/news/detail.php",
   )

второе правило не сработает для "своего" адреса (например /about/news/55/), т.к. первое, универсальное, срабатывает для этого адреса. То есть, более точные правила нужно писать в начало файла, а обобщённые — в конец.
5
Борис Байзулаев
Адрес физического файла, подключенного в результате обработки адреса записывается в
Код
$_SERVER["REAL_FILE_PATH"]
1
Алексей Комаров
Настройка ЧПУ. Тема на форуме
В теме рассмотрены типовые примеры настройки ЧПУ для вывода разделов и элементов разделов инфоблока. Требуется, когда нужно вместо динамических адресов сделать переход на ЧПУ адреса (статические).
3
Sergey Leshchenko
Упрощенный вариант правила, решающий проблему, описанную Денисом Мальцевым в предыдущем комментарии.

Код
array( 
    "CONDITION"   => "#^/news/([0-9]+)\.php.*#", 
    "RULE" => "ID=$1", 
    "PATH" => "/news/detail.php", 
)
8
Денис Мальцев
Одна интересная особенность, которую надо учитывать.

Допустим вам надо сделать преобразование такого вида, чтобы при открытии страницы /news/445.php происходило преобразование в /news/detail.php?ID=445
Можно использовать такое правило
Код
array(
    "CONDITION"   => "#^/news/([0-9]+)\\.php#",
    "RULE" => "ID=$1",
    "PATH" => "/news/detail.php",
)


Оно даже будет работать, но ровно до тех пор пока в строке не появятся дополнительные параметры. Например пользователь перешел с внешнего ресурса и в URL была добавлена метка для Google Analitics, запрошенный URL получился примерно такой /news/445.php?utm_source=google. Вместо текста новости вы увидите сообщение "Элемент не найден", потому что в результате преобразования получился такой адрес /news/detail.php?ID=445?utm_source=google.

Ниже приведен код, решающий эту проблему:

Код
array(
    "CONDITION"   => "#^/news/([0-9]+)\\.php(\\?(.*))?#",
    "RULE" => "ID=$1&$3",
    "PATH" => "/news/detail.php",
)
3
Роберт Басыров
Задача: Выполнить 301 редирект с одного домена на другой, чтобы любой адрес домена olddomain вёл на тот же адрес, но в домене newdomain.

Решение:
В файл .htaccess прописать правило:
Код
#RewriteEngine On 
#RewriteCond %{HTTP_HOST} ^olddomain\.ru$ [NC] 
#RewriteRule ^(.*)$ http://newdomain.ru/$1 [R=301,L]


в этом же файле создать условие:
Код
<IfModule mod_rewrite.c> 
   RewriteEngine On 

   RewriteCond %{HTTP_HOST} ^olddomain\.ru$ [NC] 
   RewriteRule ^(.*)$ http://newdomain.ru/$1 [R=301,L] 

   RewriteCond %{REQUEST_FILENAME} !-f 
   RewriteCond %{REQUEST_FILENAME} !-l 
   RewriteCond %{REQUEST_FILENAME} !-d 
   RewriteCond %{REQUEST_FILENAME} !/bitrix/urlrewrite.php$ 
   RewriteRule ^(.*)$ /bitrix/urlrewrite.php [L] 
</IfModule>
© «Битрикс», 2001-2019, «1С-Битрикс», 2019
Наверх