Это хорошая идея, чтобы позволить маршрутизатору искать контроллеры из базы данных? - PullRequest
1 голос
/ 21 июня 2010

В большинстве руководств по структурам проектирования PHP MVC класс маршрутизатора используется для получения пользовательского ввода и поиска правильного контроллера для точной обработки этого ввода.Вход обычно принимает форму URL.Например, http://example.com/foo/bar/ попросит маршрутизатор найти контроллер с именем foo и запустить панель методов.

PHP также имеет функцию автоматического включения, которая требует использования согласованной системы имен для ваших классов.Например, если бы я хотел получить экземпляр класса Foo, мне понадобился бы файл с именем Foo.php, а внутри был бы класс с именем Foo.

К сожалению, в тандеме эти механизмы создают конкуренциютребования к системе имен.URL-адрес очень «передний», и поэтому клиентам часто это нужно, чтобы отражать содержание определенной страницы.Например, если у меня есть страница с указаниями места проведения, клиенту может потребоваться, чтобы эта страница была на http://example.com/venues/directions/.Позже содержимое может измениться, а количество мест сократится до 1, и теперь клиент желает, чтобы URL читал http://example.com/venue/directions/.Очевидно, это очень тривиальный пример, но я думаю, что необходимость иногда менять URL-адреса очевидна.

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

Какие решения существуют для этой проблемы?Мне кажется, что необходим своего рода каталог, в котором хранятся отношения между URL-адресами и контроллерами, так что любой URL-адрес может использоваться для вызова любого контроллера независимо от того, какой из них назван.Таким образом, у нас был бы контроллер мест и URL мест, и когда клиент запрашивает изменение в URL, мы просто вносим изменения в каталог, переводя новое «место» в «места».

Я думаю, что лучший способ сделать это - использовать таблицу базы данных, но для этого потребуется дополнительный запрос для каждого пользовательского запроса.Является ли база данных правильным способом реализации каталога?Каталог - даже лучший способ решить вышеупомянутую проблему?Эта проблема вообще проблема?

Ответы [ 2 ]

4 голосов
/ 21 июня 2010

Некоторые решения, которые я видел в этом, - это явно указать «соединение» маршрутизации с контроллером / действием.

Например, в NiceDog вы можете указать маршруты типа

R('venues?/directions')
  ->controller('VenueController')
  ->action('directionsAction')
  ->on('GET');

Разрешение регулярному выражению соответствовать URL. (Выражение выше будет соответствовать venue/directions или venues/directions). Мне нравится этот метод, потому что он отделяет схему именования контроллера от схемы именования URL.

Другим подходом, основанным на конфигурации, было бы иметь какое-то явное отображение:

$routes = array(
    'venues?' =>
      array('controller'=>'VenueController','action'=>'indexAction'),
    'venues?/directions' =>
      array('controller'=>'VenueController','action'=>'directionsAction')
);

А затем простая функция отправки:

function dispatch($url,$routes) {
    foreach ($routes as $pattern=>$map) {
        if (preg_match($pattern,$url,$matches)) {
            $controller = new $map['controller']();
            $action = $map['action'];
            call_user_func_array(
              array($controller,$action),
              array_slice($matches,1)
            );
            return true;
        }
    }
    throw new Exception('Route not found.');
}
0 голосов
/ 21 июня 2010

Хороший способ решить эту проблему - позволить среде MVC указать свои собственные правила маршрутизации.Например, см. URI Routing в документации платформы CodeIgniter.

Для того, чтобы следовать вашему примеру, это позволит вам переназначить запросы для /venues/ в /venue.

...