2017-01-24 6 views
10

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

$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 для всех, кто хочет ответить, как использовать указанный маршрутизатор, используя подстановочный знак для соответствия контроллеру/методу.

ответ

6

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

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

Не забудьте добавить Symfony YAML парсер к вашему 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 анализатор так что оба метода весьма схожи)

From the doc

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(); 
3

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

//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)); 
    } 
} 

I надеюсь, что это помогает

+0

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

+0

даже в строке есть способ сделать массив, но он будет таким же, как писать много строк и делать нагрузку на файл как '$ pages = array ( array ('GET', '/', 'target.php ',' name '), массив (' GET ','/target ',' target2.php ',' name2 '), массив (' GET ','/target2 ',' target3.php ', null) // .. и все определенные массивы ); foreach ($ pages as $ page) { $ router-> map ($ page [0], $ page [1], $ page [2], $ page [3]); } ' –

2

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

// bootstrap 
$router = new AltoRouter(); 

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

Каждый контроллер разрешено прод uce, но многие маршруты, в которых он нуждается.

3

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

$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 и многие аналогичные маршрутизаторы требуют маршрутов по порядку предпочтения. Когда мне нужно использовать такой маршрутизатор, я положил его на дно, чтобы он случайно не поймал ничего.

Обратите внимание, что если вы хотите создать что-то подобное этому, вы можете это сделать - имея в виду, я не знаю, как выглядит ваш код в настоящее время или какая логика вам нужна, - заменив ваше регулярное выражение (в Пример Силекса, с фигурными скобками) и проверка $_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');