Блог Горошко Андрея 1C-Битрикс,PHP,Разработка Routing: Руководство разработчика

Routing: Руководство разработчика

Каждый PHP-разработчик, работающий с экосистемой Bitrix Framework, должен глубоко понимать работу её ключевых компонентов. В этой статье мы проведем подробный аудит темы «Routing: Руководство разработчика», проанализируем лучшие практики и покажем, как правильно использовать запросов в реальных задачах.

—
title: Роутинг
—

Роутинг — процесс определения, какой код должен быть выполнен при обращении к определенному URL.

Роутинг в Bitrix Framework управляет маршрутизацией запросов, направляя их на соответствующие обработчики. Это ключевой элемент для создания гибких и масштабируемых веб-приложений, так как он определяет, как URL-адреса соответствуют определенным функциям или контроллерам.

Доступно в модуле main начиная с версии 21.400.0.

Запуск

Чтобы активировать систему, перенаправьте обработку 404 ошибок на routing_index.php в .htaccess:

#RewriteCond %{REQUEST_FILENAME} !/bitrix/urlrewrite.php$
#RewriteRule ^(.*)$ /bitrix/urlrewrite.php [L]
RewriteCond %{REQUEST_FILENAME} !/bitrix/routing_index.php$
RewriteRule ^(.*)$ /bitrix/routing_index.php [L]

С версии 23.500.0 роутер доступен через метод \Bitrix\Main\Application::getRouter()

Конфигурация

Файлы конфигурации маршрутов находятся в /bitrix/routes/ и /local/routes/. Для подключения файла укажите его в .settings.php в секции routing:

'routing' => ['value' => [
       'config' => ['web.php', 'api.php']
]],
// подключатся файлы при их наличии:
// /bitrix/routes/web.php, /local/routes/web.php, 
// /bitrix/routes/api.php, /local/routes/api.php

Формат файла предполагает возврат замыкания с объектом конфигурации маршрутов:

<?php
use Bitrix\Main\Routing\RoutingConfigurator;
return function (RoutingConfigurator $routes) {
       // маршруты
};

Поиск совпадений происходит в том же порядке, в каком маршруты описаны в конфигурации.

Маршруты

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

Запросы

Маршруты начинаются с указания метода HTTP-запроса, который они обрабатывают. Это позволяет точно определить, какие действия должны выполняться для различных типов запросов, таких как GET, POST и другие.

GET-запросы

Используются для получения данных с сервера. Например, если вы хотите получить список стран, вы можете определить маршрут, который обрабатывает только GET-запросы:

$routes->get('/countries', function () {
       // Обработка GET-запроса
   });

В этом случае, когда пользователь обращается по адресу /countries, сервер выполнит указанную функцию.

POST-запросы

Применяются для отправки данных на сервер, например, для создания новой записи. Чтобы обработать POST-запрос, используйте метод post:

   $routes->post('/countries', function () {
       // Обработка POST-запроса
   });

Этот маршрут будет активироваться только при отправке данных на /countries с использованием метода POST.

Любые запросы

Если необходимо обрабатывать запросы любого типа, используйте метод any. Это может быть полезно, если одно и то же действие должно выполняться для разных методов:

   $routes->any('/countries', function () {
       // Обработка любого типа запроса
   });

Такой маршрут будет реагировать на GET, POST и другие методы HTTP.

Произвольные наборы методов

Если нужно обрабатывать только определенные методы, используйте methods. Например, чтобы обрабатывать только GET, POST и OPTIONS:

   $routes->any('/countries', function () {
       // Обработка GET, POST и OPTIONS
   })->methods(['GET', 'POST', 'OPTIONS']);

Также для указания произвольного набора методов можно использовать метод match.

$routes->match(['LOCK', 'UNLOCK'], $uri, $controller);

Параметры

Параметры маршрута — динамические части URL, которые могут принимать различные значения. Параметры заключаются в фигурные скобки {}. Например, если у вас есть маршрут для отображения информации о стране, можно использовать параметр {country}:

$routes->get('/countries/{country}', function ($country) {
       return "country {$country} response";
});

В этом примере, если пользователь введет /countries/USA, параметр country примет значение USA.

По умолчанию параметры соответствуют паттерну [^/]+, что означает, что они могут содержать любые символы, кроме /. Если нужно задать более специфические условия для параметра, используйте метод where. Например, чтобы ограничить параметр country только буквами:

$routes->get('/countries/{country}', function ($country) {
       return "country {$country} response";
})->where('country', '[a-zA-Z]+');

Если параметр может содержать символ /, используйте паттерн .*, чтобы разрешить любые символы:

$routes->get('/search/{search}', function ($search) {
       return "search {$search} response";
})->where('search', '.*');

Параметры также могут иметь значения по умолчанию. Это полезно, если параметр не всегда присутствует в URL. Например, если параметр country не указан, он по умолчанию будет равен Australia:

$routes->get('/countries/{country}', function ($country) {
       return "country {$country} response";
})->default('country', 'Australia');
// маршрут будет выбран при запросе /countries/
// при этом параметр country будет иметь указанное значение

Кроме того, вы можете задать параметры, которые не участвуют в формировании адреса, но могут быть использованы в обработчике:

$this->routes->get('/countries/hidden', function ($viewMode) {
       return 'countries response {$viewMode}';
})->default('viewMode', 'custom');

Доступ к значениям параметров можно получить через параметры функции-обработчика или через объект текущего маршрута:

$routes->get('/countries/{country}', function ($country) {
       return "country {$country} response";
});
...
$app = \Bitrix\Main\Application::getInstance();
$country = $app->getCurrentRoute()->getParameterValue('country');   

Имена

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

Присвоить имя маршруту

Чтобы задать имя маршруту, используйте метод name. Это позволяет легко ссылаться на маршрут в других частях приложения. Например:

   $routes->get('/path/with/name', function () {
       return 'path with name';
   })->name('some_name');

В этом примере маршруту /path/with/name присвоено имя some_name.

Использовать имена для генерации ссылок

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

   $router = \Bitrix\Main\Application::getInstance()->getRouter();
   $url = $router->route('country_detail', ['country' => 'Australia']);
   // $url: /countries/Australia

Это полезно, если структура URL может измениться, так как ссылки, основанные на именах, останутся актуальными.

Изменить формат ссылки

Если необходимо изменить статическую часть URL, например, с /countries/{country} на /страны/{country}, вы можете сделать это, не меняя все ссылки в коде:

   // Старый маршрут
   $routes->get('/countries/{country}', function () {
       return 'some output';
   })->name('country_detail');
   // Новый маршрут
   $routes->get('/страны/{country}', function () {
       return 'some output';
   })->name('country_detail');

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

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

Контроллеры

Контроллер — класс или функция, которая обрабатывает запросы, поступающие на определенный маршрут. В Bitrix Framework поддерживается несколько видов контроллеров, что позволяет гибко настраивать логику обработки запросов.

Контроллеры Bitrix\\Main\\Engine\\Controller

Эти контроллеры позволяют использовать методы классов для обработки запросов. Например, если у вас есть контроллер SomeController с методом viewAction, вы можете настроить маршрут следующим образом:

   $routes->get('/countries', [SomeController::class, 'view']);

В этом случае, при обращении к /countries, будет вызван метод viewAction контроллера SomeController.

Отдельные действия

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

   $routes->get('/countries', SomeAction::class);

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

Замыкания

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

   $routes->get('/countries/', function () {
       return "countries response";
   });

Замыкания позволяют быстро определить логику обработки прямо в маршруте.

Аргументы контроллеров

В качестве аргументов в контроллерах можно использовать объекты запроса HttpRequest, объект текущего маршрута Route, а также именованные параметры маршрута:

   use Bitrix\Main\HttpRequest;
   use Bitrix\Main\Routing\Route;
   $routes->get('/countries/{country}', function ($country, HttpRequest $request) {
       return "country {$country} response";
   });
   $routes->get('/countries/{country}', function (Route $route) {
       return "country {$route->getParameterValue('country')} response";
   });

Обратная совместимость

Для поддержки старых публичных страниц предусмотрен класс Bitrix\Main\Routing\Controllers\PublicPageController, который позволяет использовать существующие страницы в новой системе роутинга:

   $routes->get('/countries/', new PublicPageController('/countries.php'));

Группы

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

Объединение в группы

Создать группу маршрутов

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

   $routes->group(function (RoutingConfigurator $routes) {
       $routes->get('/path1', function () {
           // Обработка запроса для path1
       });
       $routes->get('/path2', function () {
           // Обработка запроса для path2
       });
       $routes->get('/path3', function () {
           // Обработка запроса для path3
       });
   });

В этом примере маршруты /path1, /path2 и /path3 объединены в одну группу, что позволяет легко управлять их общими свойствами.

Общие параметры для группы

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

   $routes
       ->where('serviceCode', '[a-z0-9]+')
       ->group(function (RoutingConfigurator $routes) {
           $routes->get('/{serviceCode}/info', [ServicesController::class, 'info']);
           $routes->get('/{serviceCode}/stats', [ServicesController::class, 'stats']);
   });

Здесь параметр serviceCode должен соответствовать паттерну [a-z0-9]+ для всех маршрутов в группе.

Префиксы для группы

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

   $routes->prefix('about')->group(function (RoutingConfigurator $routes) {
       $routes->get('company', function () {
           // Обработка запроса для /about/company
       });
       $routes->get('personal', function () {
           // Обработка запроса для /about/personal
       });
       $routes->get('contact', function () {
           // Обработка запроса для /about/contact
       });
   });

В этом примере все маршруты в группе имеют префикс about, что делает их URL более структурированными.

Параметры группы

Задать общие параметры

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

   $routes
       ->where('serviceCode', '[a-z0-9]+')
       ->group(function (RoutingConfigurator $routes) {
           $routes->get('/{serviceCode}/info', [ServicesController::class, 'info']);
           $routes->get('/{serviceCode}/stats', [ServicesController::class, 'stats']);
   });

В этом примере параметр serviceCode должен соответствовать паттерну [a-z0-9]+ для всех маршрутов в группе, что гарантирует единообразие и правильность данных.

Упростить управление параметрами

Задавая параметры на уровне группы, вы можете легко изменять условия для всех маршрутов одновременно. Это упрощает поддержку и развитие приложения, так как изменения нужно вносить только в одном месте:

   $routes
       ->where('category', '[a-z]+')
       ->group(function (RoutingConfigurator $routes) {
           $routes->get('/{category}/list', [CategoryController::class, 'list']);
           $routes->get('/{category}/details', [CategoryController::class, 'details']);
   });

Здесь параметр category должен быть строкой, состоящей только из букв, для всех маршрутов в группе.

Префикс группы

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

Задать префикс для группы

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

   $routes->prefix('user')->group(function (RoutingConfigurator $routes) {
       $routes->get('/profile', [UserController::class, 'profile']);
       $routes->get('/settings', [UserController::class, 'settings']);
   });

В этом примере все маршруты в группе будут начинаться с /user.

Упростить изменение структуры URL

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

   $routes->prefix('account')->group(function (RoutingConfigurator $routes) {
       $routes->get('/overview', [AccountController::class, 'overview']);
       $routes->get('/security', [AccountController::class, 'security']);
   });

Если изменить префикс с account на что-то другое, все маршруты в группе автоматически обновятся.

Организовать маршруты

Префиксы помогают организовать маршруты по логическим группам:

   $routes->prefix('admin')->group(function (RoutingConfigurator $routes) {
       $routes->get('/dashboard', [AdminController::class, 'dashboard']);
       $routes->get('/users', [AdminController::class, 'users']);
   });

В этом примере все маршруты, связанные с административной панелью, имеют префикс admin, что упрощает их идентификацию и управление.

Имя группы

Задать имя для группы

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

   $routes->name('user.')->group(function (RoutingConfigurator $routes) {
       $routes->get('/profile', [UserController::class, 'profile'])->name('profile');
       $routes->get('/settings', [UserController::class, 'settings'])->name('settings');
   });

В этом примере все маршруты в группе будут иметь имена, начинающиеся с user., такие как user.profile и user.settings.

Упростить генерацию ссылок

Используя имена групп, вы можете легко генерировать ссылки на маршруты, добавляя префикс к имени маршрута.

   $router = \Bitrix\Main\Application::getInstance()->getRouter();
   $url = $router->route('user.profile');
   // $url: /user/profile

Здесь имя user.profile используется для генерации ссылки на маршрут /user/profile.

Организовать имена маршрутов

Имена групп помогают организовать маршруты по логическим группам:

$routes->name('admin.')->group(function (RoutingConfigurator $routes) {
    $routes->get('/dashboard', [AdminController::class, 'dashboard'])->name('dashboard');
    $routes->get('/users', [AdminController::class, 'users'])->name('users');
});

В этом примере все маршруты, связанные с административной панелью, имеют имена, начинающиеся с admin., такие как admin.dashboard и admin.users.

Генерация ссылок

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

Маршруты с именем

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

Присвоить имя маршруту

Чтобы задать имя маршруту, используйте метод name. Это позволяет легко ссылаться на маршрут в других частях приложения. Например, если у вас есть маршрут для отображения информации о стране, вы можете присвоить ему имя:

$routes->get('/countries/{country}', function () {
    return 'Country information';
})->name('country.info');

В этом примере маршруту /countries/{country} присвоено имя country.info.

Упростить генерацию ссылок

Имя маршрута можно использовать при создании ссылки.

$router = \Bitrix\Main\Application::getInstance()->getRouter();
$url = $router->route('country.info', ['country' => 'Australia']);
// $url: /countries/Australia

Здесь имя country.info используется для генерации ссылки на маршрут, и параметр country автоматически подставляется в URL.

Управлять изменениями в URL

Чтобы изменить структуру URL, не меняя все ссылки в коде, достаточно изменить маршрут. Все ссылки, основанные на его имени, автоматически обновятся:

// Старый маршрут
$routes->get('/countries/{country}', function () {
    return 'Country information';
})->name('country.info');

// Новый маршрут
$routes->get('/nations/{country}', function () {
    return 'Country information';
})->name('country.info');

В этом примере структура URL изменилась с /countries/{country} на /nations/{country}, но имя маршрута осталось прежним, что упрощает управление ссылками.

Маршруты без имени

Маршруты без имени — это стандартные маршруты, которые не имеют уникального идентификатора. Они могут быть полезны для простых приложений или временных решений, но использование маршрутов без имени может усложнить управление ссылками и поддержку кода в долгосрочной перспективе.

Создать маршрут без имени

Маршруты без имени создаются без использования метода name. Это означает, что для обращения к такому маршруту необходимо использовать его полный URL. Например, если у вас есть маршрут для отображения списка стран, он может выглядеть так:

$routes->get('/countries', function () {
    return 'List of countries';
});

В этом примере маршрут /countries не имеет имени, и для его использования необходимо указывать полный URL.

Частые ошибки и решения

1. Ошибка 404 после настройки роутинга. Убедитесь, что изменения в .htaccess применены правильно и файл routing_index.php доступен.

2. Некорректная работа параметров маршрута. Проверьте, что паттерны в методе where соответствуют ожидаемым значениям.

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

💡 Экспертное мнение и рекомендации

Ключевые выводы по теме «Routing: Руководство разработчика»:

Использование современных стандартов D7 при работе с запросов позволяет писать чистый, масштабируемый и безопасный код. Не забывайте обрабатывать исключения (try/catch) и проверять права доступа текущего пользователя перед выполнением критических операций.

Похожая задача в бизнесе?

Помогу автоматизировать процессы и внедрить ИИ

Меня зовут Андрей Горошко. Я Full-stack разработчик и эксперт по 1С-Битрикс. Настраиваю CRM Битрикс24, разрабатываю защищенные API и создаю умных ИИ-агентов для автоматизации рутины.

Related Post

Как использовать метод SDK crm.dealcategory.update в Битрикс24Как использовать метод SDK crm.dealcategory.update в Битрикс24

При разработке и поддержке проектов на платформе 1С-Битрикс критически важно использовать современные стандарты D7 API. В этом руководстве мы детально изучим тему «Как использовать метод SDK crm.dealcategory.update в Битрикс24», разберем

Обновить стадию канбана или «Моего плана» task.stages.updateОбновить стадию канбана или «Моего плана» task.stages.update

Каждый PHP-разработчик, работающий с экосистемой Bitrix Framework, должен глубоко понимать работу её ключевых компонентов. В этой статье мы проведем подробный аудит темы «Обновить стадию канбана или «Моего плана» task.stages.update», проанализируем

Изменить товар crm.product.updateИзменить товар crm.product.update

Эффективная интеграция и кастомизация функционала в Битрикс24 часто требует работы на уровне API. Сегодня мы подробно рассмотрим «Изменить товар crm.product.update». Вы узнаете экспертные методики работы с crm.product.update и научитесь избегать