S.Gholizadeh S.Gholizadeh - 12 days ago 5
PHP Question

Zend2 Routing __NAMESPACE__ doesn't work or be ignored

I'm using this config as my application module config in Zend2 which is really normal and every one suggested as a standard routing rule:

'controllers' => array(
'invokables' => array(
'Application\Controller\Index' => 'Application\Controller\IndexController',
),
),
'router' => array(
'routes' => array(
'home' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/',
'defaults' => array(
'controller' => 'Application\Controller\Index',
'action' => 'index',
),
),
),
'application' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/application',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Zend\Mvc\Router\Http\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(
),
),
),
),
),
),
),


the routing for
home
works fine. but for
http://localhost/application
I get:


Index(resolves to invalid controller class or alias: Index)


and for
http://localhost/application/index/index
I get:


index(resolves to invalid controller class or alias: index)


if I change this:

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


to this:

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


As you know definitely for
http://localhost/application
it will work fine like
home
url

if I use this:

'controllers' => array(
'invokables' => array(
'index' => 'Application\Controller\IndexController',
),
),


as you know the configurations will merge and I should have just one index controller in the project.

Why the line
'__NAMESPACE__' => 'Application\Controller',
be ignored and it looks for just Index or index in the controllers array which no exist??

EDIT:

With comparing to other projects I added this to
Application/Module.php
:

public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
}


and it works now but I need and explanation. is it the solution? I mean should I add this to one of
Module.php
files in the project to make routing rules work fine? and why without it the
__NAMESPACE__
will be ignored in routing rules?

Answer

You already found the solution, adding the ModuleRouteListener is the right thing to do. The explanation can be found in the description of the onRoute method inside this listener:

Listen to the "route" event and determine if the module namespace should be prepended to the controller name.

If the route match contains a parameter key matching the MODULE_NAMESPACE constant, that value will be prepended, with a namespace separator, to the matched controller parameter.