Перейти к содержимому

Свои ЧПУ-адреса - правила обработки, порядок, конфликты

Делаем красивые адреса для своих страниц: правило обработки адреса, передача параметров, порядок проверки правил и разбор конфликтов с папками.

Что нужно знать заранее

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

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

Побеждает первое подходящее правило по порядку в общем списке. Общее правило, стоящее выше частного, перехватывает адреса и делает частное правило бесполезным навсегда.

Шаги

  1. Придумать образец адреса и решить, какие именно части станут параметрами страницы.
  2. Добавить правило обработки с этим образцом и с путём к странице-обработчику.
  3. Прочитать параметры в самой странице и отдать содержимое либо код ошибки.
  4. Проверить порядок правил: частные образцы должны стоять выше более общих.
  5. Убедиться, что папки с таким же именем в структуре сайта не существует.

Решение

Добавляем своё правило обработки адресов:

\CUrlRewriter::Add([
'CONDITION' => '#^/blog/([0-9a-z-]+)/#', // образец адреса с частью в скобках
'RULE' => 'code=$1', // часть адреса станет параметром code
'PATH' => '/blog/detail.php', // страница, которая обработает запрос
'ID' => '', // идентификатор комплексного компонента
]);

Правило состоит из образца адреса, правила параметров и пути к обработчику. Скобки в образце выделяют часть адреса, а правило параметров превращает её в обычный параметр запроса для страницы.

Читаем параметры в странице-обработчике:

// /blog/detail.php - физический файл, куда приходит запрос
$code = (string)($_GET['code'] ?? '');
$post = getPostByCode($code);
if (!$post) {
\Bitrix\Iblock\Component\Tools::process404('', true, true, true, '/404.php');
}

Страница-обработчик обязана уметь отдать ошибку при отсутствии записи. Адрес подошёл под образец, но это не значит, что запись существует: код из адреса приходит от посетителя и его проверяют.

Смотрим текущий список правил:

Окно терминала
grep -n "CONDITION" /home/bitrix/www/urlrewrite.php | head -20
grep -c "CONDITION" /home/bitrix/www/urlrewrite.php # сколько всего правил
# порядок строк в файле и есть порядок проверки правил

Проверяем образец на конкретном адресе:

var_dump((bool)preg_match('#^/blog/([0-9a-z-]+)/#', '/blog/kak-nastroit-obmen/'));
preg_match('#^/blog/([0-9a-z-]+)/#', '/blog/kak-nastroit-obmen/', $m); print_r($m);
// образец проверяют отдельно: ошибка в нём выглядит как «правило не работает»

Проверка образца отдельной строкой экономит час разбора. Ошибка в образце ведёт себя ровно как отсутствующее правило, и искать её в общем файле правил неудобно.

Обновляем правила после переноса:

\CUrlRewriter::ReIndexAll(); // пересборка правил комплексных компонентов сайта
// свои правила при этом сохраняются, если они добавлены штатным способом
// на крупной структуре пересборка идёт долго: её запускают вне часов пик

Пересборка правил нужна после переноса сайта и после массовых правок структуры. Свои правила при штатном добавлении переживают её, а дописанные в файл руками - теряются.

Типичные проблемы

Своё правило не срабатывает и адрес отдаёт ошибку.

Выше в списке стоит более общее правило, и оно перехватывает этот адрес. Частные образцы ставят выше общих, а самое общее правило оставляют последним.

Правило работает, а страница получает пустые параметры.

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

После переноса сайта свои правила исчезли.

Правила были дописаны в файл руками и стёрлись при первой пересборке. Свои правила добавляют штатным способом, и тогда пересборка их сохраняет.

Адрес открывает не ту страницу.

В структуре сайта есть папка с тем же именем, и запрос уходит в неё. Имена разделов сайта и образцов правил не должны совпадать между собой.

Несуществующая запись отдаёт пустую страницу.

Обработчик не проверяет наличие записи и не отдаёт нужный код ошибки. Отсутствие записи обрабатывают штатным вызовом страницы ошибки платформы.

Частые вопросы

Чем правила обработки отличаются от перенаправлений?

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

Где физически лежат правила?

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

Замедляют ли правила работу сайта?

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

Можно ли обойтись без правил вообще?

Да, если адреса можно построить папками и физическими файлами страниц. Правила нужны там, где часть адреса - это данные, а не структура сайта.

Как отладить сложный образец адреса?

Проверить его отдельным вызовом на нескольких реальных адресах сайта. Так сразу видно, ошибка в образце или в порядке правил.

Смежное

Первоисточник