Глубокие маршруты в Zend Framework без модулей — как?

Я пишу несколько маршрутов для службы REST. Один из URI моего ресурса выглядит так

ресурсы/пользователь/:id

Я также хочу дать доступ к отдельным атрибутам пользователя, которые будут выглядеть так

ресурсы/пользователь/:id/:атрибут

Но когда я пытаюсь определить этот последний маршрут, он не работает. Вот мой ini, где определены маршруты

routes.user.route = "resources/user/:id"
routes.user.defaults.controller = user
routes.user.defaults.action = get
routes.user.defaults.id = 0
routes.user.reqs.id = "\d+"

routes.user_attribute.route = "resources/user/:id/:attribute/"
routes.user_attribute.defaults.controller = user
routes.user_attribute.defaults.action = getAttribute
routes.user_attribute.defaults.id = 0
routes.user_attribute.defaults.attribute = ""
routes.user_attribute.reqs.id = "\d+"
routes.user_attribute.reqs.id = "reviews|lists"

Когда я пытаюсь получить доступ к ресурсам/пользователь/4/отзывы в своем браузере, я получаю следующий вывод

An error occurred
Page not found
Exception information:

Message: Invalid controller specified (resources)
Stack trace:

#0 /usr/local/lib/ZendFramework/ZendFramework-1.7.1-minimal/library/Zend/Controller/Front.php(934): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http))
#1 /home/baileyp/public_html/web/index.php(50): Zend_Controller_Front->dispatch()
#2 {main}

Request Parameters:

array(4) {
  ["controller"]=>
  string(9) "resources"
  ["action"]=>
  string(4) "user"
  [10]=>
  string(7) "reviews"
  ["module"]=>
  string(7) "default"
}

Таким образом, мой второй маршрут явно неправильно обрабатывается, так как он определяет контроллер как «ресурсы», а действие — как «пользователь». Что я здесь делаю неправильно? На сайте Zend я не нашел примеров, иллюстрирующих, как это реализовать.

И я не хочу использовать модули только для того, чтобы сделать это - избегание создания папок и тому подобного только для сопоставления с URI - это вся цель системы маршрутизации.


person Peter Bailey    schedule 17.12.2008    source источник


Ответы (2)


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

Таким образом, этот маршрут:

foo.com/resources/user/:id/:attribute

С этим вызовом:

foo.com/resources/user/12345/

Предположим, что ваше значение атрибута по умолчанию:

foo.com/resources/user/12345//

Поскольку пустое значение может быть удалено вашим веб-сервером (apache обрабатывает несколько косых черт как одну косую черту), я бы рекомендовал по умолчанию использовать для атрибута что-то, что можно было бы вызывать по имени, и он будет функционировать аналогично файлу index.html в папка:

foo.com/resources/user/12345/
foo.com/resources/user/12345/general/ (same result)

Лучшая удача, которую я имел при устранении неполадок, — это комментирование значений маршрута по умолчанию и требований построчно в последовательности. В конечном итоге вы увидите «край» самого маршрута (поскольку он вернется к значениям по умолчанию, поскольку вы предоставите ему меньше информации).

Кроме того, в вашем примере обратите внимание, что вы дважды определяете свои требования id:

 routes.user_attribute.reqs.id = "\d+"
 routes.user_attribute.reqs.id = "reviews|lists"

Будет скорректирован на:

 routes.user_attribute.reqs.id = "\d+"
 routes.user_attribute.reqs.attribute = "reviews|lists"

Это также может повлиять на ваши результаты. Надеюсь это поможет.

person Matt Gardner    schedule 16.02.2009

Я думаю, вам следует изменить только порядок правил... поэтому вы сначала помещаете более конкретные правила вверху, а более общие — внизу!

routes.user_attribute.route = "resources/user/:id/:attribute/"
routes.user_attribute.defaults.controller = user 
routes.user_attribute.defaults.action = getAttribute
routes.user_attribute.defaults.id = 0
routes.user_attribute.defaults.attribute = ""
routes.user_attribute.reqs.id = "\d+"
routes.user_attribute.reqs.id = "reviews|lists"

routes.user.route = "resources/user/:id"
routes.user.defaults.controller = user
routes.user.defaults.action = get
routes.user.defaults.id = 0
routes.user.reqs.id = "\d+"

У меня была аналогичная проблема, и это решило мою проблему!

person Community    schedule 17.12.2008
comment
На самом деле, это не работает. Он выдает точно такое же исключение. Но спасибо за предложение. - person Peter Bailey; 18.12.2008
comment
На первое место следует поставить более общие правила. - person David Snabel-Caunt; 12.07.2009