Deep routes in Zend Framework without modules - how?

I am writing multiple routes for a REST service. One of my resource URIs looks like this:

resources / user /: id

I also want to give access to individual user attributes which will look like this

resources / user /: id /: attribute

But when I try to figure out this last route it doesn't work. Here's my ini where routes are defined

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"

      

When I try to access resources / users / 4 / reviews in my browser I get the following output

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"
}

      

So it is clearly not handling my second route correctly, as it is that the controller is "resources" and the action is "user". What am I doing wrong here? There are no examples on the Zend site that I have found that illustrate how to implement this.

And I don't want to use modules just to do this - avoiding creating folders, and only for URI matching is the whole purpose of the routing system.

0


source to share


2 answers


I think you only need to reorder the rules ... so you put more specific rules at the top and more general ones at the bottom first!

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+"

      



I had a similar problem and it fixed my problem!

+1


source


Not sure if you are defining both of these sides. In my experience, the first route you are trying to map will actually only be handled with a penalty by the second (thanks to the default you specified for attribute

).

So this route:

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

      

With this call:

foo.com/resources/user/12345/

      

Let's assume your default value is:

foo.com/resources/user/12345//

      

Since an empty value can be removed by your web server (apache treats multiple slashes as a single forward slash), I would recommend defaulting to assigning an attribute to whatever might be named, and will function like the index.html file in the folder:



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

      

The best part I've had troubleshooting is to comment out route defaults and requirements one by one in sequence. You end up seeing the "edge" of the route itself (as it will revert to the defaults as you give it less information).

Also, in your example, notice that you are defining your requirements twice id

:

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

      

Will be configured to:

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

      

May also affect your results. Hope this helps.

+1


source







All Articles