简体   繁体   中英

Deep routes in Zend Framework without modules - how?

I'm writing some routes for a REST service. One of my resource's URI looks like this

resources/user/:id

I also want to give access to individual attributes of a user, which would look like this

resources/user/:id/:attribute

But when I try to define that latter route, it doesn't work. Here's my ini where the 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/user/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's clearly not processing my 2nd route correctly, since it things the controller is "resources" and the action is "user". What am I doing wrong here? There's no examples on the Zend site that I've found that illustrate how to implement this.

And I don't want to use modules just to get this done - avoiding the creation of folders and such just to match a URI is the entire purpose of a routing system.

I think you should only change the ordering of the rules ... so you first put more specific rules on the top and more general on the bottom!

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!

Am not sure if you're defining both these side by side. In my experience, the first route you're attempting to map would would actually be handled just fine by the second (thanks to the default value you provided for attribute ).

Thus, this route:

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

With this call:

foo.com/resources/user/12345/

Would assume your default attribute value:

foo.com/resources/user/12345//

As the blank value may be removed by your web server (apache treats multiple slashes as a single slash), I'd recommend defaulting the attribute to something that could be called by name and it will function similar to an index.html file in a folder:

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

The best luck I've had troubleshooting is commenting out the route default values and requirements line-by-line in a sequence. You end up seeing the 'edge' of the route itself (as it will fall back to the defaults as you give it less information).

Also, in your example, note that you're defining your id requirements twice:

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

Would be adjusted to:

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

May have an effect on your results as well. Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM