Removing Module from URL in Zend Framework 2

Published on September 16, 2012 by

If you have set up a Zend Framework 2 project by using the skeleton application, you might have noticed that you must enter the name of the module in the URL by default. This is in contrast to Zend Framework 1 where it was not necessary to enter the name of the default module. In the skeleton application, the existing module is called Application. What we want to do is for the URL localhost/user to map to the Application module’s User controller. By editing the home route, this can be accomplished quite easily.

First, open module/Application/config/module.config.php for editing. We will, as mentioned, be editing the home route, which can be found nested under router/routes. First, make a backup of the file just in case, and then replace your home route with the following. An explanation will follow.

'home' => array(
    'type' => 'Zend\Mvc\Router\Http\Literal',
    'options' => array(
        'route'    => '/',
        'defaults' => array(
            'controller' => 'Application\Controller\Index',
            'action'     => 'index',
    'may_terminate' => true,
    'child_routes' => array(
        'default' => array(
            'type' => 'Segment',
            'options' => array(
                'route' => '[:controller[/:action]]',
                'constraints' => array(
                    'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
                    'action' => '[a-zA-Z][a-zA-Z0-9_-]*'
                'defaults' => array(
                    'action' => 'index',
                    '__NAMESPACE__' => 'Application\Controller'

What we have done above is to add a child route to the home route. This allows us to build upon the parent route. Our parent’s route is /, so the child routes will build onto this route. Our child route is of the type Zend\Mvc\Router\Http\Segment, which will allow us to use segments or “placeholders” in our route. The surrounding brackets mean that the segments are optional. Then, constraints can be applied by using a regular expression pattern like in this example.

We can also specify default values to be used if a segment is not present. In our case, we have set the action to default to index so that we can make a URL of the type localhost/user instead of being forced to use localhost/user/index. We also need to specify the __NAMESPACE__; if we do not do this, then Zend Framework will do a lookup for the controller that we specified in the URL exactly as it is written. However, we would like to specify our controllers by prefixing the name of the module to prevent name collisions with other module controllers. That is, our controllers are added like this:

'controllers' => array(
	'invokables' => array(
		'Application\Controller\Index' => 'Application\Controller\IndexController',
		'Application\Controller\User' => 'Application\Controller\UserController'

If we do not specify the namespace, then a lookup for User will be done if we try to access localhost/user. By setting the namespace to Application\Controller, the lookup will instead be for Application\Controller\User, which will be successful. As you might be thinking, it is indeed entirely possible to just use the controller names only as the keys, e.g. User or Album; however, this may result in naming collisions, so this is certainly not recommended.

Now, when we try to access localhost/user, the route we have just added will be used and Zend Framework will do a lookup for a controller with the key Application\Controller\User and will then find the location of the controller to be Application\Controller\UserController. The appropriate action will then we executed; index if one is not present in the URL, and the action from the URL otherwise.

For a more detailed explanation of the various route settings, we encourage you to look at the official manual about his subject and the part about Segments in particular.


Learn Zend Framework today!

Take an online course and become a ZF2 ninja!

Here is what you will learn:

  • Understand the theory of Zend Framework in details
  • How to implement an enterprise-ready architecture
  • Develop professional applications in Zend Framework
  • Proficiently work with databases in Zend Framework
  • ... and much more!
Zend Framework logo
Author avatar
Bo Andersen

About the Author

I am a back-end web developer with a passion for open source technologies. I have been a PHP developer for many years, and also have experience with Java and Spring Framework. I currently work full time as a lead developer. Apart from that, I also spend time on making online courses, so be sure to check those out!

4 comments on »Removing Module from URL in Zend Framework 2«

  1. dev

    Hi, How to change the Module name in url?
    That is, is my url. Module name is “modulename”.
    I want to change “modulename” into “app” in url. When i visit this url, it should be redirected to modulename module.
    How can i do?

  2. Rafael Armenio


    • Hello Harsh,

      Thank you for your comment. I don’t know how you handle languages in your particular application, but you could perhaps do something like this (in module.config.php):

      return array(
          'router' => array(
              'routes' => array(
                  'about' => array(
                      'type' => 'Segment',
                      'options' => array(
                          'route' => '/about-us/:language',
                          'defaults' => array(
                              'controller' => 'Application\Controller\Index',
                              'action' => 'about',

      Of course you might want to find a more dynamic approach if you want to serve many static pages, but you should be able to find examples on how to do that online. If not, let me know and I will try to find an example for you.

      Best of luck! :-)

Leave a Reply

Your e-mail address will not be published.