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.
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
$application->getRequest()->setBaseUrl('/my-base-url');
$bootstrap->bootstrap($application);
$application->run()->send();
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.
Tried setting the baseUrl in the index.php and the appConfig still didn’t work , am using the Zend Skeleton and i have issue calling another Controller/Action, it says “The requested URL could not be matched by routing.” would love to see your index.php , i use Windows 7, Apache Zend Server CE 5.6 thanks
Hi Okeowo, my index.php is either completely stock (in case I am using the DluBaseUrl module) or it has the single extra line (see the Easy hack paragraph) and everything works. I think your problem lies somewhere else (at least the error message suggests so). I would first check the Apache configuration – is rewriting set-up correctly for your vhost? Do not forget to check the .htaccess file too. If that’s ok, I would go to your router configuration and check the defined routes.
If you are using the router configuration from the skeleton’s Application module (i.e. the route ‘/[:controller[/:action]]’) to route to your controllers, you need to set an alias in your DI instance configuration to map the controller name used in your URL to the actual class name of the controller.
If everything fails, go debug and trace (not fun, I know) and see what and where is wrong with the routing.
Let me know if you made it work.
There is no “$application = new Zend\Mvc\Application;” in beta 4, but I still have this bug
No idea to resolve it, I cannot try this stuff in /public/index.php.
This bug has been fixed in ZF2 Beta 4 – or at least it’s ok in my environment
Update your ZF2 library and use the latest Skeleton Application (that’s important, lots of things changed in beta4 and your old application written for beta3 won’t work). The index.php is quite different in beta4. I’d suggest deploying the new Skeleton App as a new project and when you have it running, move your custom modules from your beta3 app to the new beta4 app.
Hello,
Thank you for your help.
I still have this error woth Beta 4 :
A 404 error occurred
Page not found.
The requested controller could not be mapped to an existing controller class.
Controller:
=> this for every page except “/”.
It comes probably for an error of me. I’m looking why, but I think ZF2 is quite weird and difficult to learn compared to ZF1…
Ok it’s resolved !
The source zip file I have downloaded didn’t contain these files :
* /module/Application/autoload_classmap.php
* /module/Application/autoload_function.php
* /module/Application/autoload_register.php
Sorry for posting here, this was not a baseurl problem, you were right dlu
Sorry for refreshing this topic, but I have exactly the same problem. ZF2 Beta4 and the error “The requested controller could not be mapped to an existing controller class”.
Can you explain in more detail, what you meant with the missing files? I have those not too but I cannot find them in the repository as well.
Thanks for helping.
Suse.
First of all, update your ZF2 library. You are two releases behind, the current version is 2.0.0rc1. This bug has really been removed, so your problem is elsewhere. Also get the latest Skeleton Application. The
index.phpfile (beside others) looks quite different from beta4The missing
autoload_....phpfiles in the Skeleton Application are ok, they are optional. I suspect either your router configuration is wrong or your controller configuration is wrong. Check those, if you are still stuck, post those configs here and I’ll have a look at them.