Zend Framework 2 (ZF2) is an open source, object-oriented web application framework. Installation of a basic (minimal) project in a XAMPP environment requires several steps. Experience with XAMPP and Composer is recommended.

* create a directory c:\\xampp\htdocs\zf2project
* in the httpd-vhosts.conf add a virtualHost for this project and add the project to the vhosts file.
* Start apache in the Xampp control panel
* open a command line tool such as git Bash and check if Composer is available by typing : composer.
* Allow composer to self-update by typing composer self-update.
* create a file called composer.json and enter:

    "name": "ZF2 project",
    "description": "A ZF2 project",
    "license": "BSD-3-Clause",
    "keywords": [
    "homepage": "http://framework.zend.com/",
    "require": {
        "php": ">=5.4",
        "zendframework/zendframework": "*"

* Start composer by typing: composer update
* Composer will now retrieve the ZF2 library (latest version) and place it in a directory called vendor. Composer will also create a composer directory.

Next create a directory called public and in it create a file called .htaccess with:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR] // if the request is for an existing file
RewriteCond %{REQUEST_FILENAME} -l [OR] // or for an existing symlink
RewriteCond %{REQUEST_FILENAME} -d  // or for an existing directory
// then do not rewrite (-) 
// and no rewrites will follow after this one (L)
// NC = case-insensitive
RewriteRule ^.*$ - [NC,L]   
// continue with remaining requests
// and rewrite all to index.php
RewriteRule ^(.*)$ index.php [NC,L]

This way all requests are handled by a single file, index.php (bootstrapping)
index.php contains just three lines:

// Setup autoloading
require 'init_autoloader.php';
// Run the application
Zend\Mvc\Application::init(require 'config/application.config.php')->run();

and the init_autoloader.php file contains:

if (file_exists('vendor/autoload.php')) {
    $loader = include 'vendor/autoload.php';

This code will make sure composer will take care of the vendor autoloading (See previous post on ZF2 autoloading).

Zend Framework 2 is all about modules. There should be at least one, and the main module is usually called Application. The modules that should be loaded are defined in the config/application.config.php:

return array(
    'modules' => array(

    'module_listener_options' => array(
        'module_paths' => array(

Each module is located in the module directory and comes with its own module/Application/config/module.config.php and module/Application/Module.php.

The main purpose for the Module.php is to inform the application about the config file and about the type of module autoloading:

namespace Application;

class Module

    public function getConfig()
        return include __DIR__ . '/config/module.config.php';

    public function getAutoloaderConfig()
        return array(
            'Zend\Loader\StandardAutoloader' => array(
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,

The module.config.php sets up the routing to the index page, sets the IndexController as an invokable and informs the application about the location of the layout file.

        'routes' => array(
            'home' => array(
                'type' => 'Zend\Mvc\Router\Http\Literal',
                'options' => array(
                    'route' => '/',
                    'defaults' => array(
                        'controller' => 'Application\Controller\Index',
                        'action' => 'index',

    'controllers' => array(
        'invokables' => array(
            'Application\Controller\Index' => 'Application\Controller\IndexController',
   'view_manager' => array(
        'template_map' => array(
            'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
        'template_path_stack' => array(
            __DIR__ . '/../view',

The layout file just adds minimal HTML around the actual content.

The controller responsible for showing the index page is module/Application/src/Application/Controller/IndexController.php. All it does for now is return a ViewModel.

namespace Application\Controller;

use Zend\View\Model\ViewModel;
use Zend\Mvc\Controller\AbstractActionController;

class IndexController extends AbstractActionController

    public function indexAction()
        return new ViewModel();


The view itself is located in module/Application/view/application/index/index.phtml and contains just one line: “Hello world!”.

The full directory tree then looks like this:

zf2project filestructure

The index page now contains just the line “Hello world!”

All code described here is available at https://github.com/hrvanderlingen/orinoco-river-zf2-project.