I’m a new Zend Framework user, coming from CakePHP. I like ZF’s approach on things, it’s much more flexible and allows a greater degree of control on things. (this doesn’t mean I’ve given up on CakePHP, I have a post comparing these two on the way). But still, Zend Framework lacks some – quite basic – features, such as the ability to easily get the application’s root url.

I’ve googled around for a solution and found this post on Thijs Lensselink’s blog. His first implementation was:

class Zend_View_Helper_BaseUrl
{
    function baseUrl()
    {
        $base_url = substr($_SERVER['PHP_SELF'], 0, -9);
        return $base_url;
    }
}

Quite an interesting approach, that works most of the times, because no matter how complicated the url is (www.example.com/controller/action/first/value1/second/value2/and-so/on) it will still be rewritten to the index.php file by Apache’s mod_rewrite. Thus, the value stored in the $_SERVER['PHP_SELF'] superglobal will always be the site’s URL in the format www.example.com/index.php. The string “index.php” is 9 characters long, so the substr will return the correct base url.

But if the project was launched in a hurry and still has some bugs, it’s a good idea to call it a beta version. It’s quite a common practice nowadays, in our web2.0 world to hold a project in a perpetual beta. So, instead of www.example.com, one might want to rewrite all the urls to www.example.com/beta. This is quite simple to achieve with ZF, with some minor changes in the bootstrap.php file:

$front_controller = Zend_Controller_Front::getInstance();
// your bootstrap
$request = new Zend_Controller_Request_Http();
$request->setBaseUrl( $request->getBaseUrl() . '/beta' );
$front_controller->dispatch( $request );

Now, the first approach – with substr – won’t work as expected. That leaves us with one bullet proof option: to write a helper that will return the base url that is encapsulated in the front controller object.

/**
 * Helper that retuns the base url
 *
 * @package View Helpers
 */

class Generic_View_Helper_BaseUrl {
    /**
     * returns the base url
     *
     * @return string
     */
    public function baseUrl() {
        return Zend_Controller_Front::getInstance()->getBaseUrl();
    }
}
// EOF

And this won’t create overhead, because Zend_Controller_Front::getInstance() returns a static singleton object, just as the user called Gary said on the original post.