Поэтому я начал изучать 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 Ищете настоящий, хорошо объясненный ответ здесь. Я действительно хочу понять эту тему. Я был бы признателен, если бы кто-то нашел время, чтобы написать настоящий подробный ответ.
Класс Routing
(или Dispatcher
как его называли некоторые) просто направляет запрошенный URL-адрес указанному контроллеру / действию.
Таким образом, нормальный запрос приходит следующим образом:
http://localhost/news/economics/param1/param2
Без использования mod_rewrite запрос должен выглядеть примерно так:
http://localhost/index.php?route=news/economics/param1/param2
Таким образом, вам уже нужен класс, который разрешает параметр route
из URL-адреса. Это первое, что делает класс Routing
. Поэтому в этом случае он разрешает параметр:
И класс маршрутизации просто создает экземпляр контроллера запроса, вызывает запрошенный метод и передает в заданные параметры.
Но это то, что вы, наверное, уже знали?
Теперь класс, который вы показываете, просто разрешает запрошенный «маршрут» к правильному контроллеру / действию. Так, например, 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; }