Проблемы Zend Routing - PullRequest
       3

Проблемы Zend Routing

5 голосов
/ 24 февраля 2012

Я прочитал все сообщения о маршрутизации и Zend Documentation, но все еще не могу решить эту проблему.

У меня многоязычное приложение с двумя модулями: default и admin.Выбор языка работает нормально (в плагине Controller routeShutdown), но у меня есть некоторые проблемы при настройке маршрутизатора:

Я хочу, чтобы эти URL работали:

/
/controller
/controller/action
/action                  (default controller)
/controller/param        (default action)
/admin
/admin/admin-controller
/admin/admin-controller/action

и используя языкселектор это будет:

/en
/en/controller
/en/controller/action
/en/action                  (default controller)
/en/controller/param        (default action)
/en/admin/admin-controller
/en/admin/admin-controller/action

Я добавил это в свой файл начальной загрузки (index.php):

$frontController = Zend_Controller_Front::getInstance();
$router = $frontController->getRouter();
$router->removeDefaultRoutes();
$router->addRoute('langmodcontrolleraction',

new Zend_Controller_Router_Route('/:lang/:module/:controller/:action',
    array('lang' => ':lang'))
);

$router->addRoute('langmodcontroller',
new Zend_Controller_Router_Route('/:lang/:module/:controller',
    array('lang' => ':lang',
        'action' => 'index'))
);

$router->addRoute('langmod',
new Zend_Controller_Router_Route('/:lang/:module',
    array('lang' => ':lang',
        'action' => 'index',
        'controller' => 'index'))
);

$router->addRoute('lang',
new Zend_Controller_Router_Route('/:lang',
    array('lang' => ':lang',
        'action' => 'index',
        'controller' => 'index',
        'module' => 'default'))
);

$frontController->setControllerDirectory(array(
'default'=>BASE_PATH.'app/modules/default/controllers',
'admin'=>BASE_PATH.'app/modules/admin/controllers'));    

Чтобы проверить, как маршрутизатор анализирует URL, я добавилvar_dump для плагина routeShutdown:

При входе в / en я получаю:

array
'lang' => string 'en' (length=2)
'action' => string 'index' (length=5)
'controller' => string 'index' (length=5)
'module' => string 'default' (length=7)

, что в порядке.Но когда я вхожу в / en / controller1 , я получаю:

array
'lang' => string 'en' (length=2)
'module' => string 'controller1' (length=8)
'action' => string 'index' (length=5)
'controller' => string 'index' (length=5) 

Это установка модуля в "controller1".Как я могу сказать маршрутизатору установить значение по умолчанию для модуля?И для URL, как / en / controller / param?(установка модуля и действия по умолчанию)

1 Ответ

6 голосов
/ 26 февраля 2012

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

Во-первых, маршрутизатор не знает, что является действительным модулем, контроллером или действием;все, что он делает, это сопоставляет строки в URL с переменными в маршруте.Он делает это, проверяя каждый маршрут по очереди, в обратном порядке, пока не найдет совпадение.Когда вы нажимаете /en/controller, он сначала проверяет ваш /:lang маршрут, который не будет совпадать.Затем он проверяет /:lang/:module, что будет соответствовать, потому что /:lang/:module будет соответствовать / что угодно / что угодно, если вы не скажете иначе.

Имея это в виду, вы не сможете иметь оба:

/en/controller
/en/action

, если вы не установите некоторые ограничения, так как URL, такой как /en/foo, всегда будет соответствовать любому из двух, которые вы определили последним.

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

$router->addRoute('langmod', new Zend_Controller_Router_Route(
    '/:lang/:module', 
    array(
        'lang' => ':lang',
        'action' => 'index',
        'controller' => 'index'
    ),
    array(
        'module' => '(foo|bar|something)'
    )
));

заменить foo, bar и т. д. действительными именами модулей.Теперь, когда вы нажмете /en/controller1, он не будет соответствовать этому маршруту, потому что controller1 не соответствует шаблону регулярного выражения, определенному для переменной: module.Затем вам потребуется отдельный /:lang/:controller маршрут (или, возможно, /:lang/:controller/:action), чтобы он соответствовал.

Вы спросили, как установить значение по умолчанию для некоторых переменных.На самом деле вы уже делаете это с действием в нескольких ваших маршрутах, но для контроллера / модуля не все будет работать так, как вы надеетесь.Если мы возьмем ваш маршрут langmodcontroller и изменим его на:

$router->addRoute('langmodcontroller',new Zend_Controller_Router_Route(
    '/:lang/:module/:controller',
    array(
        'lang' => ':lang',
        'controller' => 'index'
        'action' => 'index' 
    )
));

, то теперь есть значение по умолчанию для переменной контроллера.Если мы на секунду притворимся, что это единственный маршрут, запрос на /en/blog теперь будет соответствовать этому и установит параметры запроса в lang = en, module = blog, controller = index, action = index./en/blog/index/foo также будет соответствовать этому маршруту и ​​даст вам модуль = блог, контроллер = индекс, действие = foo.Но обратите внимание, что хотя controller = index, вам все равно нужно это в URL.Итак, ограничение номер два заключается в том, что вам всегда нужна переменная в URL (даже если она установлена ​​по умолчанию), если после нее есть что-то, что не является значением по умолчанию.

С учетом этих ограниченийЯ бы посоветовал вам использовать что-то вроде этого (определенное в следующем порядке):

/:lang/:controller/:action/ (with 'index' defaults for controller and action)
/:lang/:action (with 'action' restricted to some predefined values)
/:lang/admin/:controller/:action (with 'admin' as a string in the URL, and :module set to 'admin' as the default)

Это даст вам URL-адреса вроде этого:

/en
/en/controller
/en/controller/action
/en/action
/en/controller/param
/en/admin/controller
/en/admin/controller/action

, что в значительной степени то, что вы естьпосле.

Маршрутизация в ZF очень мощная, вам просто нужно знать ее причуды.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...