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.
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!