ZF2 Gets the baseUrl Wrong

ZF2 Gets the baseUrl Wrong

There seems to be a problem in Zend Framework 2 beta 3 which prevents deployment of your application into a vhost subdirectory. There are hacks to circumvent this problem but if you like clean solutions, you will use the DluBaseUrl ‘mini’ module to do it right.

UPDATE: This bug has been fixed in Zend Framework 2 Beta 4. Update your ZF2 library to Beta 4 and use the latest Skeleton Application and you should be ok out of the box.

I was hit by this bug on my very first encounter with Zend Framework 2 when I tried to get the Zend Skeleton Application up and running. I had the application set-up on my localhost on the Apache web server in a vhost ‘subdirectory’ (i.e. alias) called zf2skeleton. I was trying to access it like this: http://localhost/zf2skeleton but I was only getting the following error:

The requested controller could not be mapped to an existing controller class.

After some unsuccessful tracing through the ZF2 MVC code I resorted to Rob Allen’s excellent Getting Started with ZF2 tutorial and followed it to the letter. That included setting up a dedicated vhost (i.e. no vhost subdirectory). And voilà, the Skeleton application worked! But wait, I do not want to create a new Apache vhost for every little ZF2 project I am going to play with. What’s wrong?

The bug

The problem is, that ZF2 is getting the baseUrl wrong. Instead of my actual baseUrl /zf2skeleton the Zend\Http\PhpEnvironment\Request::detectBaseUrl() method returns an empty string. There is an issue for this in the bugtracker here: baseUrl incorrect when installation is within a user’s document directory. Obviously not all users experience this incorrect behaviour, so it is likely it is related to a specific platform / webserver (I am on Windows / ZendServer / Apache). Anyway until this bug is removed, all those who are affected have to prime the ZF2 with a correct baseUrl manually.

Easy hack

If you want to go the quick and dirty road, you just need to squeeze one line of code into your /public/index.php:

$application = new Zend\Mvc\Application;
//Insert the following line with correct baseUrl

This will get the job done but you might feel uneasy about hacking the index.php in such a way. Although this modification is perfectly ok for experimenting with ZF2, it’s obviously inadequate for anything more.

DluBaseUrl module

There are probably many ways to accomplish the simple task of manually setting the baseUrl ‘the right way’. Using a custom ZF2 module may seem like an overkill but you shall see it is a good fit here.

Download or clone the DluBaseUrl module, install and enable it as usual. (The installation is described in detail on the module’s git repository overview page.)

Beside not having to touch the /public/index.php file the main benefit in using the DluBaseUrl module is its inherent relation to the application configuration – you can very easily get your fingers on the merged configuration in module’s bootstrap. Since the value of baseUrl is directly implied by the local environment, we should configure it in a local configuration file. ZF2 has a facility for this: put a config file with .local.config.php suffix into your /config/autoload directory. (There is a template config file shipped with DluBaseUrl module.) Configure your local baseUrl path in this config file and you are done.

By using this module you are also getting the benefit of an easy deactivation when the bug in ZF2 is removed. Just disable the DluBaseUrl module in your /config/application.config.php.

Modules are very powerful tool in ZF2. You can do great things with them, but you can also do very little things with them. Since they are designed to load and bootstrap quick, you do not have to worry about any negative impact on performance.

Your mileage may vary

As this bug is probably related to a specific platform, you might have not experienced it. I would be curious to know who encountered it and in what environment. Please drop me a line below saying if you are running ok out of the box or if you had to hack it somehow. If you have been hit by this bug, do not forget to vote for it.