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.
<?php /** * 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.
I can’t make the setBaseUrl to work, so I improved the baseurl method like this:
function baseUrl()
{
$s = $_SERVER['PHP_SELF'];
$base_url = substr($s, 0, -(strlen($s) – strpos($s, ‘index.php’)));
return $base_url;
}
This will find the first occurrence of the ‘index.php’ and remove everything after it leaving the baseurl only.
Regards!
You don’t need to…The helper works out the box
ZF 1.9.2 have Zend_View_Helper_BaseUrl
but it doesn’t work, why?
Can you rephrase that? Did you try my helper and it didn’t work? I didn’t tested it in ZF 1.9.2, but it should work…
I see a BaseUrl helper in ZF, but it doesn’t work.
So I googled the web finding this and other post talking about a BaseUrl helper.
My question is why the default helper doesn’t work.
I ask this question here because Your post almost recent.
Your Helper too doesn’t work if I don’t use ‘/beta’ subdir (see belowe)
the Lensselink’s one work in my case. (but not as I like)
My bootstrap:
My helper:
My View calls to the helper:
looking at my helper you see two vars: $base_url and $file.
only $file is returned, $base_url return always empty if I use ‘/’ in setBaseUrl().
If I try ‘/subdir’ in setBaseUrl() it works!
If I use ‘/’ the output is:
on a page like http://localhost/resource
baseUrl(); // render ” that become the link ‘http://localhost/resource’
baseUrl(‘page’); // render ‘page’ that become the link http://localhost/page
baseUrl(’style.css’); // render style.css
on a page like http://localhost/resource/
baseUrl(); // render ” that become the link ‘http://localhost/resource/’
baseUrl(‘page’); // render ‘page’ that become the link ‘http://localhost/resource/page’
baseUrl(’style.css’); // render style.css
the Lensselink’s one render as belowe:
baseUrl(); // render ‘/’ that become the link ‘http://localhost/’
baseUrl(‘page’); // render ‘/page’ that become the link ‘http://localhost/page’
baseUrl(’style.css’); // render /style.css
no one render ‘http://localhost/’ as I wish
I took the liberty of altering your comment and adding the proper markup. You can use <pre lang=”php”> code </pre> . I don’t know why the default helper doesn’t work, as I haven’t used the 1.9.2 version of the framework yet.
My helper was posted here on the 31st of January 2009, so it’s fairly old. It simply returns the base url as it’s encapsulated in the FrontController object.
You must understand that the front controller doesn’t keep any record about the domain your site is running on. For instance, my baseUrl() will return the path part of the url (see this page for details).
The domain the application is running at a given time shouldn’t be relevant to the application itself. But if really want your domain to be returned by the baseUrl() helper, you have to parse the data from the $_SERVER superglobal. You can find an useful example here.
Was this useful?
thanks for the tips about the path.
anyway the helpers (neither yours or the zend one) seems to work, this can be helpfull for other people looking for it.
thanks again
Since I’ve used my helper without any problems in several projects that are now live and Zend Framework’s components are thoroughly tested prior to their release, I’m inclined to believe that you’ve made a mistake somewhere in your application.
They may not work in the way that you want them to work – returning the whole URL with the domain name. With this, I agree. But again, they shouldn’t. An application should be domain independent.
Best of luck in finding a component suitable for you. And,.after you do, perhaps you’ll find the time to post it here, so it will be helpful to others…
The Zend helper should work out of the box with a simple one liner –
baseUrl(‘blah’) ?>
Assuming you’ve set the baseUrl up in your config file of course –
resources.frontController.baseUrl = “http://example.com:7000/”