my first ZF2 application (ZF2 MVC tutorial debugged)

At time of writing, ZF2 version beta4 is out and there is no real formal documentation on how to write a ZF2 based application.

I tried to create my first application (now called “module”) using ZF2, following this documentation: http://packages.zendframework.com/docs/latest/manual/en/zend.mvc.quick-start.html

Unfortunately, this did not work straight out of the box. It seems that the tutorial was designed for a version lower than beta4 and is not working anymore. Below is a summary of the issues I faced following the tutorial and how they were solved.

autoload.php

Below error was found

Warning: include_once(vendor/autoload.php): failed to open stream: No such file or directory in

After careful analysis, we can see below error message as well:

Fatal error: Uncaught exception ‘RuntimeException’ with message ‘vendor/autoload.php could not be found. Did you run `php composer.phar install`?’

Following the instructions found within the error message, running ‘php composer.phar install’ saved the issue.
To do this,

  1. make sure gd, imap and mcrypt php extensions are activated (sudo apt-get install php5-gd php5-imap php5-mcrypt)
  2. go to your application’s root directory (ZendSkeletonApplication/) and make sure it contains a file named composer.phar
  3. run “php composer.phar self-update” first, in order to update it to latest version
  4. run “php composer.phar install” (this step might take a while)

Refresh your page and the error should be gone by now (and a whole lot of files should have been created under /vendor folder).

service_manager

After solving the autoload.php issue, a new error is generated:

Notice: Undefined index: service_manager in XXX
Catchable fatal error: Argument 1 passed to Zend\Mvc\Service\ServiceManagerConfiguration::__construct() must be an array, null given

This message simply means that file /config/application.config.php must return an array with ‘service_manager’ as key.

You file should at least contain:

<?php
return array(
 'service_manager' => array(
  'use_defaults' => true,
  'factories'    => array(
  ),
 ),
);

Refresh your page, this should solve the issue.

module_listener_options

Now we face this new error message:

Undefined index: module_listener_options in XXX
Undefined index: modules in XXX
Fatal error: Uncaught exception ‘Zend\ModuleManager\Exception\InvalidArgumentException’ with message ‘Parameter to Zend\ModuleManager\ModuleManager’s Zend\ModuleManager\ModuleManager::setModules method must be an array or implement the \Traversable interface’ in XXX

Well, the reason is the same as with service_manager. Our /config/application.config.php file has not enough information. On top of ‘service_manager’ entry, we must also define ‘module_listener_options’ and ‘modules’ entries, as below:

<?php
return array(
 'modules' => array(
  'Application',
  'RdTest',
 ),
 'module_listener_options' => array(
  'config_glob_paths'    => array(
   'config/autoload/{,*.}{global,local}.php',
  ),
  'config_cache_enabled' => false,
  'cache_dir'            => 'data/cache',

  'module_paths' => array(
   './module',
   './vendor',
  ),
 ),
 'service_manager' => array(
  'use_defaults' => true,
  'factories'    => array(
  ),
 ),
);

Note: in this example, we assume that our application will have two modules:

  1. first one will be named Application (and as such a folder /module/Application must exists – this one was created using ZendSkeletonApplication)
  2. second one will be named RdTest (and as such a folder /module/RdTest must exists – this one is created on my own and will contain my user-defined application)

Refresh the page, issues should be gone by now.

AutoloaderProvider

Now we face a new error message:

Fatal error: Interface ‘RdTest\AutoloaderProvider’ not found in /ZendSkeletonApplication/module/RdTest/Module.php on line 6

This error is here because in /RdTest/Module.php, I declared my class as follows:

<?php
namespace RdTest;
class Module implements AutoloaderProviderInterface
{

I am implementing AutoloaderProviderInterface interface without having imported it first.

Simply add the following line before declaring the class:

use Zend\ModuleManager\Feature\AutoloaderProviderInterface;

Refresh the page, error should be gone by now.

Note: in versions < beta4 (and in the 1st ZF2 app tutorial found on zend.com), it seems that AutoloaderProviderInterface was named AutoloaderProvider and the path to AutoloaderProvider interface was Zend\Module\AutoloaderProvider

Done!

Refreshing the page, my dummy module is now working correctly and default ZF2 homepage is showing up!

routes

Now when I tried to follow the mvc quick start tutorial and tried to go to /hello/world url, I got a nasty page 404 error.

Comparing the /module/Application/config/module.config.php against what was advised in the mvc quick start tutorial revealed the source of the problem.

In the tutorial, the following content for /config/module.config.php is advised:

return array(
 'routes' => array( 
  '<module name>-hello-world' => array(
   'type' => 'Literal',
   'options' => array(
    'route' => '/hello/world',
    'defaults' => array(
     'controller' => '<module namespace>-Hello',
     'action' => 'world',
    ),
   ),
  ),
 ),
 'controller' => array(

whereas when looking at /module/Application/module.config.php, the content is as follows:

return array(
 'router' => array(
  'routes' => array(
   'default' => array(
    'type' => 'Zend\Mvc\Router\Http\Segment',
    'options' => array(

As one can see, the top-most ‘router’ level is missing in the tutorial. Once this issue is fixed as displayed below, and page is refreshed, everything works great!

return array(
 'router' => array( 
  'routes' => array( 
   '<module name>-hello-world' => array(
    'type' => 'Literal',
    'options' => array(
     'route' => '/hello/world',
     'defaults' => array(
      'controller' => '<module namespace>-Hello',
      'action' => 'world',
     ),
    ),
   ),
  ),
  'controller' => array(

view script location

Now we face a new issue when refreshing the page:

Fatal error: Uncaught exception ‘Zend\View\Exception\RuntimeException’ with message ‘Zend\View\Renderer\PhpRenderer::render: Unable to render template “rd-test/hello/world”; resolver could not resolve to a file’

In its current state, the ZF2 MVC Quickstart guide is reading:

Create the directory view/<module-name>hello. Inside that directory, create a file named world.phtml.

This is not correct, the directory should rather be view/<module-name>/hello, i.e. you must create a subdirectory inside the /view/<module-name> directory named “hello” and not a single directory named “<module-name>hello”.

Refresh the page, now everything works as expected!

sources

One Comment Trackback URL | Comments RSS

  1. Anes Says:

    Hi Dear, I cannot make a success in "Hello world" yet. please advise me with a more detailed solution to Thanks, Anes

Post a Comment

Your email is never published nor shared. You're allow to say what you want...