Получение перечня маршрутов в PHP приложениях
Основные подходы к листингу маршрутов
Наиболее эффективное решение
В современных веб-фреймворках PHP предусмотрены встроенные консольные команды для вывода списка всех зарегистрированных маршрутов. Это самый быстрый способ, не требующий дополнительной разработки. Команды позволяют увидеть методы HTTP, URI, имена маршрутов, привязанные контроллеры и middleware.
Как получить список маршрутов в Laravel?
Выполнить в терминале:
php artisan route:listListing php route (листинг маршрутов php)
Команда отображает таблицу со столбцами: Domain, Method, URI, Name, Action, Middleware. Для фильтрации добавьте флаги --method=GET или --path=api/*.
Как получить список маршрутов в Symfony?
Используйте команду debug:router:
php bin/console debug:routerВывод содержит Name, Method, Scheme, Host, Path, Controller. Для сортировки применяется опция --sort-by=path.
Как получить список маршрутов в Yii2?
В Yii2 нет встроенной консольной команды, но можно использовать расширение yii2-routes или программный доступ через компонент urlManager.
Возможные проблемы
Кэширование маршрутов (Laravel: route:cache) может привести к тому, что вывод команды будет основан на кэше, а не на реальных файлах. Сбросьте кэш командой php artisan route:clear перед выполнением листинга. В Symfony убедитесь, что маршруты не закэшированы в продакшене.
Как получить маршруты программно из кода PHP?
Когда доступ к консоли отсутствует (например, на хостинге), можно получить коллекцию маршрутов прямо в коде приложения. В Laravel это делается через фасад Route:
$routes = Route::getRoutes();
foreach ($routes as $route) {
echo $route->uri() . ' - ' . $route->getName() . PHP_EOL;
}В Symfony используйте RouterInterface:
use Symfony\Component\Routing\RouterInterface;
class SomeController {
public function list(RouterInterface $router) {
$collection = $router->getRouteCollection();
foreach ($collection->all() as $name => $route) {
echo $name . ': ' . $route->getPath() . PHP_EOL;
}
}
}Типичная ошибка
В Laravel при попытке получить маршруты до завершения загрузки провайдеров может быть возвращен пустой список. Убедитесь, что контекст выполнения находится после регистрации всех маршрутов.
Как создать собственный листинг маршрутов для кастомного роутера?
Если вы используете самописный роутер (например, на основе FastRoute или nikic/FastRoute), можно добавить метод для вывода всех маршрутов. Пример для FastRoute:
use FastRoute\RouteCollector;
$routes = [];
$dispatcher = FastRoute\simpleDispatcher(function(RouteCollector $r) use (&$routes) {
$r->addRoute('GET', '/users', 'getUsers');
$r->addRoute('POST', '/users', 'createUser');
// сохраним маршруты в переменную
$routes = $r->getData();
});
// структура данных сложная, требуется рекурсивный обход
function listRoutes(array $routeData, $prefix = '') {
foreach ($routeData as $method => $items) {
if (is_array($items)) {
foreach ($items as $uri => $handler) {
echo $method . ' ' . $prefix . $uri . ' -> ' . (is_string($handler) ? $handler : 'Closure') . PHP_EOL;
}
} else {
// рекурсивные группы
listRoutes($items, $prefix);
}
}
}Этот подход требует понимания внутренней структуры getData().
Проблема
FastRoute не предоставляет простого метода для получения всех маршрутов; данные возвращаются в оптимизированном виде. Для листинга проще хранить отдельную коллекцию маршрутов при регистрации.
Как использовать Reflection для анализа маршрутов?
В больших фреймворках можно задействовать Reflection API для извлечения маршрутов из контейнера или роутерных файлов. Например, в Laravel получить маршруты можно через рефлексию сервиса router:
$router = app('router');
$reflection = new ReflectionClass($router);
$property = $reflection->getProperty('routes');
$property->setAccessible(true);
$routes = $property->getValue($router);
// $routes будет объектом RouteCollectionВнимание:
Такой код считается хрупким, так как зависит от внутренней структуры класса. При обновлении фреймворка свойство может измениться.
Ошибка доступа
Reflection может не сработать, если свойство объявлено как private с финальным модификатором или отсутствует. Используйте только для отладки.
Расширенные примеры использования листинга маршрутов
Экспорт маршрутов в JSON (Laravel)
Создайте консольную команду, которая собирает маршруты и выводит их в JSON для передачи фронтенду:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Route;
class ExportRoutesJson extends Command
{
protected $signature = 'route:export-json';
protected $description = 'Экспорт маршрутов в JSON';
public function handle()
{
$routes = Route::getRoutes();
$data = [];
foreach ($routes as $route) {
$data[] = [
'method' => implode('|', $route->methods()),
'uri' => $route->uri(),
'name' => $route->getName(),
'action' => $route->getActionName(),
'middleware' => $route->middleware(),
];
}
$this->line(json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
}
}Запуск:
php artisan route:export-json > routes.jsonРезультат (фрагмент):
[
{
"method": "GET|HEAD",
"uri": "api/users",
"name": "users.index",
"action": "App\\Http\\Controllers\\UserController@index",
"middleware": ["api", "auth:api"]
},
{
"method": "POST",
"uri": "api/users",
"name": "users.store",
"action": "App\\Http\\Controllers\\UserController@store",
"middleware": ["api", "auth:api"]
}
]Фильтрация маршрутов по middleware (Symfony)
use Symfony\Component\Routing\RouterInterface;
public function filterByMiddleware(RouterInterface $router)
{
$collection = $router->getRouteCollection();
$filtered = [];
foreach ($collection->all() as $name => $route) {
$defaults = $route->getDefaults();
$middleware = $route->getOption('_middleware'); // или свой ключ
// если middleware содержит 'auth'
if (strpos($middleware, 'auth') !== false) {
$filtered[] = [
'name' => $name,
'path' => $route->getPath(),
'methods' => $route->getMethods()
];
}
}
return $filtered;
}Результат может быть использован для генерации документации.
Листинг маршрутов с группировкой по префиксу (Yii2)
В Yii2 маршруты хранятся в конфигурации urlManager. Получить их можно так:
$manager = Yii::$app->urlManager;
$rules = $manager->rules;
$grouped = [];
foreach ($rules as $rule) {
$prefix = explode('/', $rule->name)[0];
$grouped[$prefix][] = [
'route' => $rule->route,
'pattern' => $rule->pattern,
'verb' => $rule->verb
];
}
print_r($grouped);Результат:
Array
(
[api] => Array
(
[0] => Array
(
[route] => user/index
[pattern] => api/users
[verb] => GET
)
)
[admin] => Array
(
[0] => Array
(
[route] => admin/dashboard
[pattern] => admin
[verb] => GET
)
)
)Поиск маршрутов по имени в PHP (любой фреймворк)
Пример функции для поиска:
function findRouteByName($name, $collection) {
// $collection может быть RouteCollection Laravel или Symfony
foreach ($collection->all() as $routeName => $route) {
if ($routeName === $name) {
return $route;
}
}
return null;
}Может применяться для проверки существования маршрута перед генерацией ссылки.
Создание HTML-таблицы маршрутов для административной панели
$html = '<table><tr><th>Method</th><th>URI</th><th>Name</th></tr>';
foreach (Route::getRoutes() as $route) {
$methods = implode(' ', $route->methods());
$html .= "<tr><td>{$methods}</td><td>{$route->uri()}</td><td>{$route->getName()}</td></tr>";
}
$html .= '</table>';
echo $html;Результат на странице отобразится красивой таблицей. Этот подход требует осторожности с XSS: экранируйте вывод.