4
votes

I am having an issue with zf2 routing. I am using skeleton example https://github.com/zendframework/ZendSkeletonApplication/blob/master/module/Application/config/module.config.php, but when I tying to access http://localhost/admin/ or http://localhost/admin/answers I am getting 404 with message:

A 404 error occurred

Page not found.

The requested controller could not be mapped to an existing controller class.

Controller:
Index(resolves to invalid controller class or alias: Index)
No Exception available

From error message I think router ignores __NAMESPACE__. Maybe someone could help me find solution to my problem?

I have used https://github.com/zendframework/ZFTool to create module and controllers. My file structure is:

module/Admin
├── config
│   └── module.config.php
├── Module.php
├── src
│   └── Admin
│       └── Controller
│           ├── AnswersController.php
│           └── IndexController.php
└── view
    └── admin
        ├── answers
        │   └── index.phtml
        └── index
            └── index.phtml

My module.config.php:

return array(
    'controllers'  => array(
        'invokables' => array(
            'Admin\Controller\Answers' => 'Admin\Controller\AnswersController',
            'Admin\Controller\Index'   => 'Admin\Controller\IndexController',
        ),
    ),
    'router'       => array(
        'routes' => array(
            'admin' => array(
                'type'          => 'literal',
                'options'       => array(
                    'route'    => '/admin',
                    'defaults' => array(
                        '__NAMESPACE__' => 'Admin\Controller',
                        'controller'    => 'Index',
                        'action'        => 'index',
                    ),
                ),
                'may_terminate' => true,
                'child_routes'  => array(
                    'default' => array(
                        'type'    => '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(
                            ),
                        ),
                    ),
                ),
            ),
        ),
    ),
    'view_manager' => array(
        'template_path_stack' => array(
            'admin' => __DIR__ . '/../view',
        ),
    ),
);

If I am changing: '\__NAMESPACE__' => 'Admin\Controller', 'controller' => 'Index', to 'controller' => 'Admin\Controller\Index' I can access Index controller, but not Answers .

Additional info:

I found strange behavior of skeleton application. I have downloaded fresh skeleton application and this configuration works. If I am going to localhost/application/index or localhost/application/answers it works as accepted. But if I am changing Application module name to Admin and changing router configuration (replacing all application to admin and Application to Admin) and config stops working. Can anyone explain this? Maybe Application module works as default in skeleton applications?

I am using Zend Framework 2.2.4.

3
did you add namespace Admin\Controller; within your controller? And it would be helpful if you could name your file structure. - cptnk
@cptnk Yes namespace was added by ZFTool. I have updated my question with file structure. - Lukas Ignatavičius
Did you ever find a solution to this? I'm still running into this in the year 2017. Thanks. - Leo Galleguillos
@HelloWorld I did not find the cause. We just wrote every route manually. - Lukas Ignatavičius

3 Answers

1
votes

add above default key

'answers' => array(
  'type' => 'Zend\Mvc\Router\Http\Literal',
  'options' => array(
    'route'    => '/answers',

    'defaults' => array(
      'controller' => 'Admin\Controller\Answers',
      'action'     => 'index',
    ),
  ),
),

if that not help try comment default key So maybe try wildcards ?

'application' => array( 
    'type'    => 'segment', 
    'options' => array( 
        'route'    => '/[:controller][/:action][/:id]', 
        'constraints' => array(
            'controller' => '[a-zA-Z][a-zA-Z0-9_-]*', 
            'action'     => '[a-zA-Z][a-zA-Z0-9_-]*', 
            'id'         => '[0-9]+', 
        ), 
        'defaults' => array( 
            'controller' => 'Application', 
            'action'     => 'index',
        ), 
    ), 
    'may_terminate' => true, 
    'child_routes' => array( 
        'default' => array( 
            'type'    => 'Wildcard', 
            'options' => array( 
            ), 
        ), 
    ), 
), 

it's only lead not complete solution

1
votes

Set in Module.php

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

I'am not 100% sure of what you are trying to achieve but this may help you in a way. In case you have a variable controller param I would set up my routes like this:

'router' => array(
    'routes' => array(
        'admin' => array(
            'type'    => 'segment',
            'options' => array(
                'route'    => '/admin[/:controller[/:action]]',
                'constraints' => array(
                'controller' => '[a-zA-Z][a-zA-Z0-9_-]+',
                'action' => '[a-zA-Z][a-zA-Z0-9_-]+',
                ),
                'defaults' => array(
                    'controller' => 'Admin\Controller\Admin',
                    'action'     => 'index',
                    ),
                ),
            ),
        ),
     ),

When redirecting you would need to specify the controller and the action this way though.

return $this->redirect()->toRoute('admin', array('action' => 'newAction', 'controller' => 'someOtherController'));

URL View-Helper equivalent:

$this->url('admin', array('action' => 'newAction', 'controller' => 'someOtherController'));

EDIT:

Zend framework2 merges all config fiels trough your models and provides the Router Module with the array you have configured. In fact you could extend the Router class and alter it to your likeing.

As you can probably see it actually is not "mandatory" to provide the router with the namespace of each module within your config files. The router has your invoked Controllers and can "track" them via the zf2 naming convention.

EDIT2: I forgot to add some constraint's to the route can you try it with the updated route configuration again?

enter image description here