Tag Archives: ZF2

Unit testing multiple ZF2 modules at once

Although it’s been over a year since the release of Zend Framework 2, I have yet to see compelling documentation on how to execute unit tests for an entire application.  If you are using Zend Studio 10, the default ZF2 module template provides testing architecture that is largely incompatible with multi-module testing.

Setup testing architecture

First, create a tests directory in your ZF2 application root.

cd /home/zf2-app
mkdir tests

PHPUnit configuration

After that, create the following PHPUnit XML configuration file in the newly-created tests directory. To add code coverage, simply add a logging entry to the XML file. Depending on how you run the tests, this allows code coverage for the entire application in one report, or a module-specific code coverage report.

<phpunit bootstrap="Bootstrap.php" backupGlobals="false">
        <testsuite name="application">
        <testsuite name="anothermodule">
            <directory suffix=".php">../module</directory>
                <directory suffix=".php">../module/*/tests</directory>


Next, you’ll need to create the Bootstrap.php file referenced in the PHPUnit configuration. In this case, the bootstrap will load and setup the application configuration file and load the specified modules. It is remarkably similar to the initialization process used when running the application in a normal context.


use ZendServiceManagerServiceManager;
use ZendMvcServiceServiceManagerConfig;


include_once 'init_autoloader.php';

$testsPath = __DIR__;
if (is_readable($testsPath . '/TestConfiguration.php')) {
    require_once $testsPath . '/TestConfiguration.php';
} else {
    require_once $testsPath . '/TestConfiguration.php.dist';

$configuration = include 'config/application.config.php';

$serviceManager = new ServiceManager(new ServiceManagerConfig($configuration));
$serviceManager->setService('ApplicationConfig', $configuration);
$moduleManager = $serviceManager->get('ModuleManager');

Next, create the TestConfiguration.php.dist file. This allows environment-specific configuration without affecting the code base.

touch TestConfiguration.php.dist

Run them jawns

Now that we’re finished with the setup, you’ll need to create a few tests. Once you have some tests to run, you can execute them using the commands below.

# Run all module tests

# Run tests for specific module
phpunit --testsuite anothermodule

ZF1-ZF2 bridge project available on GitHub

The ZF1-ZF2 Bridge project, based on last week’s post on migrating Doctrine 2 from Zend Framework 1 to Zend Framework 2, has been posted to GitHub. The bridge project accomplishes the following goals, all of which are aimed at easing migration pains.

  • Created ZF1 controller action helper to access ZendMvcApplication
  • Created ZF1 view helper to access ZendViewHelper classes
  • Allow ZF1 controller actions to be routed to ZendMvcApplication without having to edit an .htaccess file
  • Access any ZF2 component from within ZF1 (e.g. ServiceManager, EventManager, MvcEvent, etc.)
  • Full Composer integration for both versions of Zend Framework

Download the ZF1-ZF2 Bridge project from GitHub

Issues with jQuery and ZendFormElementCheckbox

In addition to the more obvious backwards compatibility breaks encountered when migrating from ZF1 to ZF2, there are also more nuanced changes.  In this particular instance, the migration to ZendForm broke the standard code used to determine whether a checkbox input is checked.  The resultant value was always false.

The code we used to determine the a checkbox’s state was extremely simple.

var value = $('input[name="my_element"]').prop('checked') ? 1 : 0;

Next, the ZendForm code responsible for instantiating the element object:

namespace ApplicationForm;

class MyCheckboxForm extends Form
    public function __construct($name = null)
            'name' => 'my_checkbox',
            'type' => 'Checkbox',
            'options' => array(
                'label' => 'My Checkbox',

Under ZendForm, the standard resultant HTML for the checkbox element looks like this:

<input name="my_checkbox" value="0" type="hidden">
<input name="my_checkbox" value="1" type="checkbox">

Gasp… a hidden element! The first input element, which is most certainly not a checkbox, receives priority using the aforementioned selector query. There are a few simple ways to fix this…

Fix #1

It seems as though the creators of Zend Framework had some foresight, and gave programmers the option to disable the hidden element.

    'name' => 'my_checkbox',
    'type' => 'Checkbox',
    'options' => array(
        'label' => 'My Checkbox',
        'use_hidden_element' => false,

Fix #2: With Hidden Element

If you wish to retrain the hidden element, you can update the selector query as follows.

var value = $('input[name="my_element"]:checkbox').prop('checked') ? 1 : 0;

Migrating to ZF2: Integrating Composer and DoctrineORMModule

Due to the vast nuances of Zend Framework 2, migrating an application from Zend Framework 1 can be very tedious.  To make this process a little less painful, there is a way to slowly implement modules from ZF2 without making the application unusable. The methodology illustrated, which implements DoctrineModule and DoctrineORMModule into a Zend Framework 1 project, can be applied to a variety of ZF2 modules, making it an invaluable technique in the migration process.

Create the ZF2 project structure

  • /config
  • /config/autoload
  • /data
  • /module
  • /module/Application
  • /module/Application/src
  • /module/Application/src/Application
  • /public
  • /vendor

Install Zend Framework 2 and Doctrine ORM using Composer

At the very least, the composer.json file must include the following.

    "require" : {
        "zendframework/zendframework" : "2.2.*",
        "doctrine/orm" : "2.*",
        "doctrine/doctrine-orm-module": "0.*"

After updating the Composer configuration file, run Composer.

# Update Composer to latest version
php composer.phar self-update

# Install Composer packages
php composer.phar install

Add init_autoloader.php to application root directory

Integrating the Composer and ZF2 autoloading scheme can be a bit tricky if you rely on antiquated Zend Framework 1 components. To get around the peculiarities, use the classmap generator provided by Zend.

The init_autoloader.php file listed below is identical to the file provided in the ZendSkeletonApplication repository with a few exceptions. For one, the ZF2 autoloader is specified and configured making it simpler to use and understand. Secondly, several class maps are implemented as part of the default autoloading scheme. I recommend generating separate class map files for the application, library (if used), and ZF2 module directories. The class map file in the ZF2 module directory will be replaced with module-specific autoloading once the migration is complete.

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

    'ZendLoaderStandardAutoloader' => array(
        'autoregister_zf' => true,
    'ZendLoaderClassMapAutoloader' => array(
        __DIR__ . '/application/autoload_classmap.php',
        __DIR__ . '/module/autoload_classmap.php',

if (!class_exists('ZendLoaderAutoloaderFactory')) {
    throw new RuntimeException('Unable to load ZF2. Run `php composer.phar install` or define a ZF2_PATH environment variable.');

Update ZF1’s index.php for Composer compatibility

There are two changes that will help bring your index file more in line with that of Zend Framework 2.

Place this line at the top of index.php.

NOTE: If relative paths are used in other parts of the application, it is likely that they will need to be updated.

// All paths relative to application root

// Decline static file requests back to the PHP built-in webserver
if (php_sapi_name() === 'cli-server' && is_file(__DIR__ . parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH))) {
    return false;

// Setup autoloading
require 'init_autoloader.php';

Setup ZF2 configuration files

In /config, create an application.config.php file using this file as the base. Update the modules entry as listed below.

return array(
    'modules' => array(
        // Vendor modules

Next, create local.php in the /config/autoload directory using the code below. The database credentials should be updated to match your environment.


return array(
    'doctrine' => array(
        'connection' => array(
            'orm_default' => array(
                'driverClass' => 'DoctrineDBALDriverPDOMySqlDriver',
                'params' => array(
                    'host'     => 'localhost',
                    'port'     => 3306,
                    'user'     => 'mysqlUser',
                    'password' => 'mysqlPassword',
                    'dbname'   => 'mysql_db',
        'configuration' => array(
            'orm_default' => array(
                // Generate proxies should be FALSE on production servers
                'generate_proxies' => true,

Setup ZF2 “Application” module

ZF2’s per-module configuration files make it extremely easy to more effectively organize your entities and repositories. In /module/Application/config, create a file named module.config.php using the code below.


return array(
    'doctrine' => array(
        'driver' => array(
            'application_driver' => array(
                'class' => 'DoctrineORMMappingDriverAnnotationDriver',
                'cache' => 'array',
                'paths' => array(
                    dirname(__DIR__) . '/src/Application/Entity',
            'orm_default' => array(
                'drivers' => array(
                    'ApplicationEntity' => 'application_driver',

Next, create Module.php in /module/Application. This file will become more important once the migration is complete.


namespace Application;

use ZendModuleManagerFeatureConfigProviderInterface;
use ZendModuleManagerFeatureAutoloaderProviderInterface;

class Module implements ConfigProviderInterface,
    public function getConfig()
        return include __DIR__ . '/config/module.config.php';

    public function getAutoloaderConfig()
        return array(
            'ZendLoaderStandardAutoloader' => array(
                __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,

Relocate existing entities and repositories to ZF2

Assuming your entities and repositories share a common namespace, create two new directories inside /module/Application/src/Application. The first directory should be entitled Entity, and the second, Repository. Next, we will need to move existing entities into the Application module and adjust any references to said entities accordingly.

For example, if you were using Model_Entity or ModelEntity as the prefix or namespace, it will need to be updated to ApplicationEntity. The same applies to repositories; if the prefix or namespace was Model_Repository or ModelRepository, it will become ApplicationRepository.

In summation, our data structures will follow this scheme:

Type Class Name Location
Entities ApplicationEntityEntityName /module/Application/src/Application/Entity
Repository ApplicationRepositoryEntityName /module/Application/src/Application/Repository

Make ZendMvcApplication available in ZF1

Add the following method to Bootstrap.php.

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
    protected function _initZf2()
        $application = ZendMvcApplication::init(include 'config/application.config.php');

        Zend_Registry::set('zf2', $application);
        return $application;

How to use ZF2’s DoctrineORMModule in ZF1

Merely creating the ZendMvcApplication object will ensure that Doctrine is properly setup based on the local.php configuration file. From here, using Doctrine is quite simple. By storing the ZendMvcApplication object in the much maligned Zend_Registry, it is universally accessible via Zend_Registry::get('zf2'). The ZF2 application object can also be accessed using $bootstrap->getResource('zf2').

The following code illustrates how to access Doctrine’s EntityManager, and retrieve an entity and repository.

/* @var $application ZendMvcApplication */
$application = Zend_Registry::get('zf2');
$sm = $application->getServiceManager();
$entityManager = $sm->get('DoctrineORMEntityManager');

// Get repository for EntityName
$repository = $entityManager->getRepository('ApplicationEntityEntityName');

// Find EntityName with ID #7
/* @var $entity ApplicationEntityEntityName */
$entity = $repository->find(7);


This “proxy-like” technique can be applied to many different ZF2 modules, making migration significantly less painful. If I left anything out, please let me know. Also, if you have a better way or other ideas on making migration easier, please feel free to post them.

Zend Framework 2.0 Buzz

Zend Framework logoThe buzz behind Zend Framework 2.0 is growing rapidly everyday, and not without good reason.  Zend Framework 2.0 will utilize the very best of PHP to create a more stable, secure, and better performing framework.  Although nothing is set in stone, listed below are some of the highlights so far:

  • Minimum version:  PHP 5.3+
  • Not backwards compatible
  • Improved consistence between componenets
    • __construct() – Constructors will accept options via arrays or Zend_Config
    • Option keys will not use camel caps or uppercase, but instead will utilize lowercase underscore-separated words
  • Elimination of most singletons
  • Utilization of PHP 5.3 features
    • __invoke() and closures – for use within plugin architecture
    • Namespaces – to help with the super-long class names (Zend_Search_Lucene_Analysis_Analyzer_Common_TextNum_CaseInsensitive comes to mind)
    • goto – to be used when creating Finite State Machines (FSM) and parsers (Zend_Search_Lucene, Zend_Ical, Zend_Markup)
  • Autoload-only for all ZF components
  • Zend_View
    • Allow optional use of streams for systems where short_open_tags are disabled
    • Automatic escaping of variables
    • Use PluginLoader instead of internal system for managing plugins

There’s a lot of great discussion going on within the official Zend Framework 2.0 Roadmap, as well as a general outline on Zend’s plans, so get over there and read up!