Issues

ZF-10923: Url action helper adds a slash in front of url

Description

Zend_Controller_Action_Helper_Url always adds a slash in front of generated url. So, if baseUrl is defined. it leads to the incorrect urls:

$this->_helper->url('action', 'controller', 'module')

=> '/http://yourbase.com/module/controller/action'

Comments

Removing the leading slash would break existing applications, as the URLs generated would now be relevant to the current page, not the document root.

How are you defining the baseUrl? Is it being auto-determined for you, or have you set it explicitly? I'm guessing, based on the URL you display above, that you are setting it explicitly. The baseUrl should only contain path information, not the protocol and host -- if you need the protocol and host, you should use the serverUrl() view helper, or grab the information from the request object.

I'm setting baseUrl in application.ini config.

You can look through the class source code. It gets basDir from front controller if availible and adds it to the url. After that it adds the leading slash without any conditions.

The right behavior is if leading slash would be added only if baseUrl was not defined in front controller.

And hasn't changed since then. Infact i remember two more issue dubles.

Confirmed. If a fully-qualified baseUrl is supplied to the front controller, then the bug outlined in this ticket manifests itself. Troublesome code: !50a1a8.png!

Unit test:


Index: tests/Zend/Controller/Action/Helper/UrlTest.php
===================================================================
--- tests/Zend/Controller/Action/Helper/UrlTest.php (revision 24820)
+++ tests/Zend/Controller/Action/Helper/UrlTest.php (working copy)
@@ -178,6 +178,21 @@
         $url = $this->helper->simple('action', null, null, array('foo' => 'bar'));
         $this->assertEquals('/baseurl/module/controller/action/foo/bar', $url);
     }
+
+    /**
+     * @group ZF-10923
+     */
+    public function testFullyQualifiedBaseUrlDoesNotGetSlashPrepended()
+    {
+        $this->front->setBaseUrl('http://example.com');
+
+        $request = $this->front->getRequest();
+        $request->setModuleName('module')
+                ->setControllerName('controller');
+
+        $url = $this->helper->simple('action', null, null, array('foo' => 'bar'));
+        $this->assertEquals('http://example.com/module/controller/…', $url);
+    }
 }
 
 // Call Zend_Controller_Action_Helper_UrlTest::main() if this source file is executed directly.

And result of running it:


There was 1 failure:

1) Zend_Controller_Action_Helper_UrlTest::testFullyQualifiedBaseUrlDoesNotGetSlashPrepended
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-http://example.com/module/controller/…
+/http://example.com/module/controller/…

FAILURES!
Tests: 1, Assertions: 1, Failures: 1.

After discussing the issue with [~dasprid], this is the intended behavior of {{setBaseUrl}}. That method's primary purpose is to allow Zend Framework applications to run in sub-folders by specifying the path prefix that should be stripped from the request URI before being processed by the router. This request URI is an absolute path, not a fully-qualified URI, and so setting the base URL to a fully-qualified URL will break this feature (and the view helper too).

If you need to use the FQDN URL in your view scripts, you can wrap the call to the URL view helper in a call to the {{serverUrl}} helper:


<?php echo $this->serverUrl($this->url(...)); ?>

Or set the base tag in the header of your HTML page:


I've updated the relevant manual pages (SVN r24827) with a note about fully-qualified base URLs not being supported.