In the first part of the ‘Hello World’ app we got to the point of creating our first Zend Framework 2 module. Now it’s time to make this module and see some results for our work.

So lets get down do get stuck in, first let’s create the directories we need so in a terminal in our app root we

and create a new file in our ‘Application’ folder called ‘autoload_classmap.php’

in this file for now we will just return an empty array so:

press Ctrl O and then Ctrl X to exit the editor.

don’t worry this file will get used and you will see why too, this file will tell Zend AutoLoader where to find our class files, but more on this in a minute.

Module Configuration

OK let setup the module config file now in this file were are going to have default routing and navigation and also which views will display for actions in our app.

First create the config directory

then create new file in this directory called ‘module.config.php’

In this file we add our routing and view config so:

press Ctrl O and then Ctrl X to exit the editor.

Well there’s a lot going here, basically we have configured three things here

  1. router with a default home route
  2. navigation with a default home item
  3. view manager options with a template map

Routing

The first section in this config file is the router setup, this is where we configure all the modules routes and which controllers will be called on this route. This is what Zend Framework website says on routing:

It’s important to understand how the framework expects the pages to be organised. Each page of the application is known as an action and actions are grouped into controllers within modules. Hence, you would generally group related actions into a controller; for instance, a news controller might have actions of current, archived and view.

As our module only has one page (the home page) we only need to setup one route for this and we have called this route ‘home’. In ‘home’ route we set all the its options. first we specify the type of route which in this case is called “Literal’ the route options are:

  • ‘route’ which is the url after the domain part e.g. if we want a url like http://www.mydomain.com/home, we would put here /home but because we want this as our entry page we just use / which will be mapped to http://www.mydomain.com.
  • ‘defaults’ is an array of default parameters we want for this route the first one is the namespace our controller is located (for more information on namespaces see here http://php.net/manual/en/language.namespaces.rationale.php) this tell zf2 that our controller can be found in the controller folder which we will create shortly, don’t worry this will become clear as we build our app and you see for yourselves the outcome. The second parameter is which controller will be called. Then the last one is which action we be called. So this array says to zf2 router ‘on this route we want the index action in the Index controller in the Application/Controller namespace to deal with this’. Anyway you will see later how this works.

Navigation

The next section deals with our site navigation, here we have just one menu called ‘default’ and one menu item called ‘home’, we give the ‘home’ item a label and a route, so we have only one route at this time so we insert ‘home’ for the route. We will get more into the navigation options later.

View Manager

The view manager is where we setup our html template files. First lets talk about the ‘template_map’ option, here we mapping template names the the actual files so here we have an map that provides locations for:

  1. Our main layout (‘layout/layout’)
  2. Our error pages (‘error/index’ and 404 page ‘error/404’)
  3. Our home page template (‘application/index/index’)

and all these files will be found in the view directory of our module and we will create these next.

The ‘doctype’ option tells the view manager to render all html tags according to the doctype, this happens when we use the view helper to create menus, forms and so on and you will see this when we are finished.

The ‘display_exceptions’ option tells the MVC that we want to display any exceptions raised by our actions and display it in a template which we defined in our ‘template_map’ array which is ‘error/index’.

Also the ‘display_not_found_reason’ is set to true and tells the MVC that if a route is not found then display the reason for this and render it in our template ‘error/404’ this error get triggered if:

  1. No route matches the current request.
  2. The controller in the route match cannot be found.
  3. The controller in the route match does not implement the DispatchableInterface.
  4. The response from a controller set the response status to 404.

This is a very quick overview of the options this file can have. There are lots more but for know I don’t want to overload you all these options we will learn more as we progress though when we our next modules to make this app useable in the real world.

Next lets make the ‘Module.php’ file this file will bootstrap our module so:

in the terminal

and in this new file add:

press Ctrl O and then Ctrl X to exit the editor. Now a breakdown of what this does.

Line 3: First we declare our module namespace, here we use the module name because ‘Zend\ModuleManager\ModuleManager’ expects to find it that way. Zend Framework 2 uses PHP namespaces so our module does to, it took me a while to get my head round namespaces but once you do you’ll say ‘hey, why didn’t I use them before.’, it makes writing classes much easier as long class names are eliminated. A good  article on namespaces is “PHP 5.3 namespaces for the rest of us” but as we go you should get the hang of namespaces in no time at all.

Lines 5: Here we are importing one file into our namespace so we use the use command. We are importing the MvcEvent class from the Zend library. This is how we import other classes we will want to use when we create a new class.

Line 8: Our class is called ‘Module’ each module we create has to have this class so the MVC application can bootstrap our module.

Lines 10-16: As Zend Framework 2 MVC is event driven the first thing we have to do is attach the ‘EventManager’ to the ‘ModuleRouteListener’ we do this in the ‘onBootstrap’ method, this is called when the ‘ModuleManager’ has finished loading all our modules and is given the ‘MvcEvent’ which gives us access to the ‘Application’ and ‘ServiceManager’ instances. For the MVC to work we need to attach the ‘EventManager’ to the ‘ModuleRouteListener’, so we retrieve the ‘Application’ instance and assign it to $app variable, then we retrieve the ‘EventManager’ from the ‘Application’ instance and assign to the $eventManager variable, then we get the ‘ModuleRouteListener’ from the ‘ServiceManager’ and assign it to the $moduleRouteListener variable. And now we can attach the ‘EventManager’ to the ‘ModuleRouteListener’ using the listeners attach() method.

Lines 18-21: In the getConfig() method we are just returning the ‘config/module.config.php’ file which return an the config array.

Lines 23-30: In the getControllerConfig() method we return an array of controllers we want the MVC to know about here we are just one controller called ‘Application\Controller\Index’ which we will create shortly. We use use a key/value pair, the key is an alias and the value is the file in PSR-0 autoloading format. (see below)

Lines 32-39: In the getAutoloaderConfig() this returns an array of autoloaders for this module. Here we have configure just one autoloader which is ‘Zend\Loader\ClassMapAutoloader’  this registers the ‘autoload_classmap.php’ file so the autoloader can find our module class files. we could of also added a more dynamic autoloader called ‘Zend\Loader\StandardAutoloader’ but this can can a performance problem as our app grows. there is a tool to auto generate this file called ‘classmap_generator.php’ which can be found in ‘vendor/bin’ folder, we may explore this at another time.

Now lets add our files to our ‘autoload_classmap.php’

then adjust our array to look like:

This only has two entries as we will only have two classes in this module our ‘Module.php’ and ‘IndexController.php’ and now these files will autoload.

Since we are using the ‘ServiceManager’ to get our class ‘ModuleRouteListener’ instance we will need to tell it where to find it, so open the ‘config/application.config.php’ file in our editor and add this to the end of the array:

so our ‘config/application.config.php’ file should look like this:

Here we are saying to the ‘ServiceManager’: “Hey! You can find ‘ModuleRouteListener’ in ‘Zend\Mvc\ModuleRouteListener'”, this will map to the directory ‘vendor/zendframework/zendframework/library/Zend/Mvc’ where it will find our class file. The ‘invokables’ array a key/value pair, the key is our alias and the value the class file. We don’t need to put the ‘.php’ suffix because Zend Framework follows the PSR-0 Autoloading Standard.

Controller

Now we have setup our module config it’s time to create our controller class. first create the the directories:

then the class file:

and put this code in it:

press Ctrl O and then Ctrl X to exit the editor.

This controller is pretty simple for our ‘Hello World’ application first we declare our namespace (remember we are using PSR-0 standard here so our namespace reflects this <module_name>\<directory>)

We are importing the ‘Zend\Mvc\Controller\AbstractActionControler’ and extending our class with it, this will gives access to controller plugins and the ‘ServiceManager’ this we will use when we make a more useful module.

The only method we need for this class is the indexAction all our action we want have the ‘Action’ suffix so if we have an edit action in our route then we would have an ‘editAction()’ method in our controller. All that the ‘indexAction’ does is return and empty array as we don’t have any data to pass to our view, this will pass no parameters to our view. We will start to pass parameters to our view in our next module.

So that’s our controller for now and all that’s left is to configure our views. I will deal will this in part 3 of our ‘Hello World’ application.

Thanks and I welcome your comment and questions on this.