Боюсь, вам нужно немного переосмыслить свою схему 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 очень мощная, вам просто нужно знать ее причуды.