Как работает маршрутизация MVC?

Поэтому я начал изучать MVC (реальный MVC, а не фреймворк MVC) немного более подробно, и я пытаюсь разработать небольшую структуру. Я работаю, читая другие фреймворки, такие как Symphony и Zend, видя, как они выполняют свою работу, и пытаюсь реализовать ее самостоятельно.

Место, где я застрял, – это система маршрутизации URL:

<?php namespace Application\Common; class RouteBuilder { public function create($name, $parameters) { $route = new Route($name); $route->resource = array_keys($parameters)[0]; $route->defaults = $parameters["defaults"]; $notation = $parameters["notation"]; $notation = preg_replace("/\[(.*)\]/", "(:?$1)?", $notation); foreach ($parameters["conditions"] as $param => $condition) { $notation = \str_replace($param, $condition, $notation); } $notation = preg_replace("/:([az]+)/i", "(?P<$1>[^/.,;?\n]+)", $notation); //@TODO: Continue pattern replacement!! } } /* How a single entry looks like * "main": { "notation": "/:action", "defaults": { "resource" : "Authentication", }, "conditions": { ":action" : "(login)|(register)" } }, */ 

Я просто не могу правильно обернуть голову. Каков рабочий процесс приложения отсюда?

Шаблон создается, вероятно, объект Route который должен храниться под объектом Request или что-то еще, то что? Как это работает?

PS Ищете настоящий, хорошо объясненный ответ здесь. Я действительно хочу понять эту тему. Я был бы признателен, если бы кто-то нашел время, чтобы написать настоящий подробный ответ.

Related of "Как работает маршрутизация MVC?"

Класс Routing (или Dispatcher как его называли некоторые) просто направляет запрошенный URL-адрес указанному контроллеру / действию.

Таким образом, нормальный запрос приходит следующим образом:

 http://localhost/news/economics/param1/param2 

Без использования mod_rewrite запрос должен выглядеть примерно так:

 http://localhost/index.php?route=news/economics/param1/param2 

Таким образом, вам уже нужен класс, который разрешает параметр route из URL-адреса. Это первое, что делает класс Routing . Поэтому в этом случае он разрешает параметр:

  • контроллер: NewsController.php
  • метод действия: EconomicsAction
  • параметры: param1 и param2

И класс маршрутизации просто создает экземпляр контроллера запроса, вызывает запрошенный метод и передает в заданные параметры.

Но это то, что вы, наверное, уже знали?

Теперь класс, который вы показываете, просто разрешает запрошенный «маршрут» к правильному контроллеру / действию. Так, например, URL-адрес выше:

 http://localhost/index.php?route=news/economics/param1/param2 

Это английский URL. Отсюда слова « дом и новости» . Предположим, вы хотели иметь переведенный URL для этого, скажем, голландский. Тогда это будет выглядеть так:

 http://localhost/index.php?route=nieuws/economie/param1/param2 

Итак, теперь, если вы ввели голландский URL-адрес в своем браузере, ваш класс маршрутизатора будет искать контроллер под названием nieuwsController.php , но он, конечно, не существует. Вот где ваш пример играет. Класс RouteBuilder .

Когда запрашивается такой переведенный URL-адрес, ваш класс Router должен сначала проверить, есть ли контроллер с этим именем. В этом случае nieuwsController.php . Если он не может найти файл PHP, он должен затем проверить определенный массив / объект, чтобы увидеть, соответствует ли запрошенный URL любому элементу массива / объекта. Простым примером такого объекта является:

 class MappedRouter { $route = array( array( 'url' => 'nieuws/economie/(.*?)', 'controller' => 'news', 'action' => 'economie' ), array( 'url' => 'weerbericht/locatie/(.*?)', 'controller' => 'weather', 'action' => 'location' ) ); } 

Таким образом, класс маршрутизатора просто выполняет итерацию по этому массиву, чтобы увидеть, соответствует ли один из массивов индексу url массивов $route . Если он находит совпадение, тогда он знает, какой контроллер и какое действие вызывать, а код затем просто продолжается, как обычно. Класс Router создает экземпляр связанного контроллера / действия, и он продолжается оттуда.

Обратите внимание, что класс MappedRouter – это просто простой способ сделать то, что делает ваш пример RouteBuilder .

Класс маршрутизатора из моей структуры. Код рассказывает историю:

 class Router { const default_action = 'index'; const default_controller = 'index'; protected $request = array(); public function __construct( $url ) { $this->SetRoute( $url ? $url : self::default_controller ); } /* * The magic gets transforms $router->action into $router->GetAction(); */ public function __get( $name ) { if( method_exists( $this, 'Get' . $name )) return $this->{'Get' . $name}(); else return null; } public function SetRoute( $route ) { $route = rtrim( $route, '/' ); $this->request = explode( '/', $route ); } private function GetAction() { if( isset( $this->request[1] )) return $this->request[1]; else return self::default_action; } private function GetParams() { if( count( $this->request ) > 2 ) return array_slice ( $this->request, 2 ); else return array(); } private function GetPost() { return $_SERVER['REQUEST_METHOD'] == 'POST'; } private function GetController() { if( isset( $this->request[0] )) return $this->request[0]; else return self::default_controller; } private function GetRequest() { return $this->request; }