Zend Framework routes always seem to point to current URL?

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Zend Framework routes always seem to point to current URL?

Post by Chris Corbyn »

I must be doing something wrong in my ZF newbiness, but for some reason anything I do that tries to generate a URL from the route map is just returning the current URL unless I make the route name explicit.

I'll to show what I mean.

routemap.php which is included in my bootstrap file:

Code: Select all

<?php
 
/*
 swiftmailer.org route map file.
 Adds routes for the front controller.
 */
 
$router = Zend_Controller_Front::getInstance()->getRouter();
 
$router->addRoute('index', new Zend_Controller_Router_Route(
  '/',
  array('controller'=>'index', 'action'=>'index')
  ));
 
$router->addRoute('docs', new Zend_Controller_Router_Route(
  '/docs',
  array('controller'=>'documentation', 'action'=>'index')
  ));
 
$router->addRoute('docs-file', new Zend_Controller_Router_Route(
  '/docs/:topic',
  array('controller'=>'documentation', 'action'=>'load-file')
  ));
 
unset($router);
 
And in my navigation:

Code: Select all

         <div id="navigation">
            <ul>
              <li><a href="<?php echo $this->url(array('controller'=>'index', 'action'=>'index'), 'index'); ?>">home</a></li>
              <li><a href="<?php echo $this->url(array('controller'=>'download', 'action'=>'index')); ?>">download</a></li>
              <li><a href="<?php echo $this->url(array('controller'=>'documentation', 'action'=>'load-file', 'topic'=>'start'), 'docs-file'); ?>">documentation</a></li>
              <li><a href="#">bugs</a></li>
              <li><a href="#">contact</a></li>
              <li class="tab corners top right left"><a href="#">download 4.0.0</a></li>
            </ul>
          </div>
If I'm at the "start" page of the docs, then my URL is at /docs/start. The link for "downloads" then points to /docs/start, instead of /download, because that is the current page.

If I'm on the home page, then my current URL is / and therefore ZF is trying to link my "downloads" URL to /.

I've had this working in another project so I'm confused what I've done wrong here :(

Notice in my navigation, the URLs for "documentation" and "home" explicitly have the route name parameter in them? That's because if I take it out ZF tries to just generate a URL that is the same as the current URL.

Any clues?
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: Zend Framework routes always seem to point to current URL?

Post by Eran »

The third parameter the url helper takes is a boolean determining whether to override the default parameters in the route. For some reason its default value is 'false', so you should pass 'true' as the third parameter.
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: Zend Framework routes always seem to point to current URL?

Post by Chris Corbyn »

pytrin wrote:The third parameter the url helper takes is a boolean determining whether to override the default parameters in the route. For some reason its default value is 'false', so you should pass 'true' as the third parameter.
Ah sweet thanks. It still doesn't seem to work though :(

Code: Select all

<?php echo $this->url(array('controller'=>'download', 'action'=>'index'), null, true); ?>
That just prints the current URL that the user is at. Also, if I leave out the route name of my other routes ZF exhibits this sort of behaviour.

I'm really confused what I've done :P

EDIT | Full source is here if it helps http://github.com/swiftmailer/swiftmail ... ree/master
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: Zend Framework routes always seem to point to current URL?

Post by Chris Corbyn »

So I've discovered that if I remove the explicit "/" route from my route map then the URLs are created, but they all use the default route rather than the routes given in my route map.

Hmmm....

These are my routes now:

Code: Select all

$router->addRoute('docs', new Zend_Controller_Router_Route(
  'docs',
  array('controller'=>'documentation', 'action'=>'index')
  ));
 
$router->addRoute('docs-file', new Zend_Controller_Router_Route(
  'docs/:topic',
  array('controller'=>'documentation', 'action'=>'load-file')
  ));
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: Zend Framework routes always seem to point to current URL?

Post by Eran »

possibly you are using rewritebase in your htaccess? I use trailing slashes in my routes and they work ok
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Zend Framework routes always seem to point to current URL?

Post by Weirdan »

Chris, have you solved this? I'm facing the same problem. I'm not very keen on going through the code and adding 'default' route name to all url() calls just because I added another route (we were using standard module/controller/action route exclusively).
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: Zend Framework routes always seem to point to current URL?

Post by Chris Corbyn »

Weirdan wrote:Chris, have you solved this? I'm facing the same problem. I'm not very keen on going through the code and adding 'default' route name to all url() calls just because I added another route (we were using standard module/controller/action route exclusively).
Solved it yeah. Personally I think it's the most stupid router system I've ever used but here's how it works.

1. All routes have a name associated with them.
2. When you go to a certain URL, one of those routes is used to load the page.
3. When you call $this->url() in the view, if you don't pass a route name, the route found by (2) is used to create the URL
4. If you pass a route name (which you should do based on the above) then it will use that route, rather than the currently used one (i.e rather than the one that matches your request URI)

This seems stupid to me. But that's how it works. I barely ever generate URLs that will be created based on the same routing rule as the one used for the current URL, but nontheless ZF seem to think this is clear and sensible.

I prefer that my router finds the "best" route based on the parameters you give it.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Zend Framework routes always seem to point to current URL?

Post by Weirdan »

So the only option is to mention route name in url() calls explicitly?
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: Zend Framework routes always seem to point to current URL?

Post by Chris Corbyn »

Weirdan wrote:So the only option is to mention route name in url() calls explicitly?
Basically yes. Crap? Correct.

I wonder how easy it is to replace ZF's router with your own implementation. Personally I prefer a rails-style system. ZF's router is really unpredictable and fragile unless you use a route name in every url() call IMHO.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Zend Framework routes always seem to point to current URL?

Post by Christopher »

Chris Corbyn wrote:I prefer that my router finds the "best" route based on the parameters you give it.
Can you give some examples on how you would like to to work?

You may want to look into Horde Routes...
(#10850)
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: Zend Framework routes always seem to point to current URL?

Post by Chris Corbyn »

arborint wrote:
Chris Corbyn wrote:I prefer that my router finds the "best" route based on the parameters you give it.
Can you give some examples on how you would like to to work?
Route map:

Code: Select all

$map->addRoute('/documentation/:topic',
  array('controller'=>'documentation', 'action'=>'load-topic'));
 
$map->addRoute('/documentation/:version/:topic',
  array('controller'=>'documentation', 'action'=>'load-topic-for-version'));
Now, in ZF, if I'm viewing the URL:

http://site.tld/documentation/introduction

Then the route that is being used is the first one. So if my page makes any calls to url() without a route name it will try to use this route to create the URL.

For example, if I want to say:

Code: Select all

You are viewing the documentation for version 1.2.  To see the 1.4 documentation for this topic,
<a href="<?php echo $this->url(array(
  'controller'=>'documentation', 'action'=>'load-topic-for-version',
  'version'=>'1.4', 'topic'=>$topicName
)); ?>">click here</a>.
This is incredibly frustrating and confusing, because ZF completely ignores the fact you have a more suitable route that fits this set of parameters. If you're viewing a page that uses the default route, then ZF will create a URL like:

http://site.tld/documentation/load-topi ... troduction

When what you'd expect is:

http://site.tld/documentation/1.4/introduction

That's exactly what a rails-style route map would do. It matches the route that includes all of your parameters (or a wildcard). If more than 1 route happens to match, then it takes the shortest (presumably cleanest) one of the two.

In ZF, if you're on a page that doesn't use the default route, and the parameters passed to url() do not work with the route, it seems it just gives up and returns the page's request URI instead (I guess under-the-surface it uses the current request parameters as a fallback).
arborint wrote:You may want to look into Horde Routes...
Thanks, I'll check it out. I've written my own in the past too. They're not that hard to do really.
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Re: Zend Framework routes always seem to point to current URL?

Post by Benjamin »

Seeing this makes me glad I'm using symfony. Here's a sample routing.yml file:

Code: Select all

 
# default rules
homepage:
  url:   /
  param: { module: content, action: index }
 
content:
  url: /:action.html
  param: { module: content }
 
default_index:
  url:   /:module
  param: { action: index }
 
default:
  url:   /:module/:action/*
 

Code: Select all

 
<?php echo link_to('Home', '@content?action=index', array('class' => 'menu_lnk')); ?>
<?php echo link_to('Home', 'content/index', array('class' => 'menu_lnk')); ?>
 
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Zend Framework routes always seem to point to current URL?

Post by Christopher »

Chris Corbyn wrote:Now, in ZF, if I'm viewing the URL:

http://site.tld/documentation/introduction

Then the route that is being used is the first one. So if my page makes any calls to url() without a route name it will try to use this route to create the URL.

For example, if I want to say:

Code: Select all

You are viewing the documentation for version 1.2.  To see the 1.4 documentation for this topic,
<a href="<?php echo $this->url(array(
  'controller'=>'documentation', 'action'=>'load-topic-for-version',
  'version'=>'1.4', 'topic'=>$topicName
)); ?>">click here</a>.
This is incredibly frustrating and confusing, because ZF completely ignores the fact you have a more suitable route that fits this set of parameters. If you're viewing a page that uses the default route, then ZF will create a URL like:

http://site.tld/documentation/load-topi ... troduction

When what you'd expect is:

http://site.tld/documentation/1.4/introduction
I think maybe it is doing what it thinks is the right thing because you have 'action'=>'load-topic-for-version', in your array.
(#10850)
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Zend Framework routes always seem to point to current URL?

Post by Weirdan »

arborint wrote:I think maybe it is doing what it thinks is the right thing because you have 'action'=>'load-topic-for-version', in your array.
Nope. It uses current route, unless you explicitly specify a route name:

Code: Select all

 
class Zend_View_Helper_Url extends Zend_View_Helper_Abstract
{
    /**
     * Generates an url given the name of a route.
     *
     * @access public
     *
     * @param  array $urlOptions Options passed to the assemble method of the Route object.
     * @param  mixed $name The name of a Route to use. If null it will use the current Route    <===================== It's documented, here
     * @param  bool $reset Whether or not to reset the route defaults with those provided
     * @return string Url for the link href attribute.
     */
    public function url(array $urlOptions = array(), $name = null, $reset = false, $encode = true)
    {
        $router = Zend_Controller_Front::getInstance()->getRouter();
        return $router->assemble($urlOptions, $name, $reset, $encode);
    }
}
 
Post Reply