Отображение нескольких маршрутов (контроллер) с использованием маршрутизатора

Я смотрю на библиотеку роутера Дэнни Ванкоотена Вот. Это выглядит хорошо (хотя не уверен, как он будет обрабатывать проект от среднего до большого, например, сайт электронной коммерции). Теперь, исходя из примера, это отображение

$router->map('GET','/', 'home.php', 'home');
$router->map('GET','/home/', 'home.php', 'home-home');
$router->map('GET','/plans/', 'plans.php', 'plans');
$router->map('GET','/about/', 'about.php', 'about');
$router->map('GET','/contact/', 'contact.php', 'contact');
$router->map('GET','/tos/', 'tos.html', 'tos');

Допустим, у меня есть сценарий, в котором мой сайт имеет 20-30 статических страниц или около 50 контроллеров с 2-3 действиями / методом каждая.

Как мне их всех отобразить. Если я использую описанный выше метод отображения, у меня, вероятно, будет более 100 строк отображения, и это выглядит неправильно.

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

Как правильно составить карту всех маршрутов?

PS. Выдача вознаграждения в размере 50 каждому, кто желает ответить на вопрос о том, как использовать указанный маршрутизатор с использованием подстановочного знака для сопоставления контроллера / метода.

10

Решение

Что вы можете сделать, чтобы облегчить ваш файл маршрутизатора, это переместить определение маршрута в файл YAML. У вас все еще будет много строк в YAML, но он будет более читабельным.

В вашем router.php файл, используйте этот код:

Не забудьте добавить в ваш парсер YAML symfony composer.json

use Symfony\Component\Yaml\Yaml;
$yaml_file = 'routes.yaml';
$routes = Yaml::parse(file_get_contents($yaml_file));
foreach ($routes as $route_name => $params) {
$router->map($params[0],$params[1], $params[2].'#'.$params[3], $route_name);
}

// match current request
$match = $router->match();

Ваш файл routes.yaml будет выглядеть так

index:      ["GET", "/", "home_controller", "display_item"]
content:    ["GET", "/content/[:parent]/?[:child]?", "content_controller", "display_item"]
article:    ["GET", "/article/[:page]", "article_controller", "display_item"]

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

Чтобы сделать что-то вроде этого, вы должны изменить router.php код что-то вроде этого:

use Symfony\Component\Yaml\Yaml;
$yaml_files = ['front.yaml', 'static.yaml', 'admin.yaml'];
foreach ($yaml_files as $yaml_file) {
$routes = Yaml::parse(file_get_contents($yaml_file));
foreach ($routes as $route_name => $params) {
$router->map($params[0],$params[1], $params[2].'#'.$params[3], $route_name);
}
}

// match current request
$match = $router->match();

Дэнни Ван Кутен также сделал PHP-Router который имеет встроенную поддержку файлов YAML. (Если вы посмотрите на исходный код, вы увидите, что он использует синтаксический анализатор Symfony, поэтому оба метода очень похожи)

Из документа

Определение маршрута YAML

base_path: /blog

routes:
index: [/index, someClass.indexAction, GET]
contact: [/contact, someClass.contactAction, GET]
about: [/about, someClass.aboutAction, GET]

router.php

require __DIR__.'/vendor/autoload.php';

use PHPRouter\RouteCollection;
use PHPRouter\Config;
use PHPRouter\Router;
use PHPRouter\Route;

$config = Config::loadFromFile(__DIR__.'/router.yaml');
$router = Router::parseConfig($config);
$router->matchCurrentRequest();
6

Другие решения

в библиотеке нет функции, которая делает что-то, как вы хотели, но есть альтернативный способ сделать это, чтобы сохранить эти страницы в базе данных, так что у вас будет что-то вроде этого ниже

//your query
// "SELECT `method`, `route`, `page`, `name` FROM `static_pages`
$pages = (query); //your executed query
if(count($pages) > 0){
foreach($pages as $page){
$router->map($page['method'],$page['route'], $page['target'], (($page['name'] !== null || !empty($page['name']) ) ? $page['name'] : null));
}
}

надеюсь, это поможет

3

Если вы используете предварительно встроенный маршрутизатор, как кремнезем Вы можете сделать что-то вроде этого:

$app->get('{route}', function($route) {
$dir = "/path/to/my/static/files/";
$file = $dir . $route . '.php';
if (file_exists($file)) {
require $file;
} else {
require '/path/to/custom/404.php';
}
});

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

Обратите внимание, что, если вы хотите создать что-то подобное этому, вы можете сделать это — имея в виду, что я не знаю, как выглядит ваш код в настоящее время или какая логика вам нужна, — подставив ваше регулярное выражение (в примере Silex это с фигурными скобками) и проверка $_SERVER['REQUEST_URI'] против вашего сформулированного регулярного выражения.

Если это пользовательское приложение, вам, возможно, не нужно чрезмерно проектировать это.

// routing class
foreach ($routes as $route) {
if ($route != self::DEFAULT_ROUTE) {
// do your normal routing logic
} else {
// check if file exists (as with code above), else send to error 404
}
}

Затем позвоните с чем-то вроде:

$router->map('GET',Router::DEFAULT_ROUTE, 'legacyRouter.php', 'legacy');
3

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

// bootstrap
$router = new AltoRouter();

FooController::mapRoutes($router);
BarController::mapRoutes($router);
// etc.

Каждому контроллеру разрешено создавать сколько угодно маршрутов.

2
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector