Routing problems in ZF2 : Controller not mapped - php

I'm trying to create a simple CRUD in Zf2 to get to know it and I'm having problems routing the only controller I have. I have this error;
"The requested controller could not be mapped to an existing controller class".
I'm trying to call this route : http://zf2.local/Listapp
This is my structure :
module/Listapp/src/Listapp/Controller/ListappController.php
The namespace is namespace Listapp\Controller;
This is my autoloader config :
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
// Autoload Listapp classes
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
// Autoload ListappController classes
'ListappController' => __DIR__ . '/src/Listapp',
)
)
);
}
And this is my module.config.php :
return array(
'controllers' => array(
'invokables' => array(
'Listapp\Controller\Listapp' => 'Listapp\Controller\ListappController'
)
),
'router' => array(
'routes' => array(
'listapp' => 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' => 'Listapp\Controller\Listapp',
'action' => 'index',
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'Listapp' => __DIR__ . '/../view',
),
), );
Any help would be appreciated thanks !
EDIT:
This is the code in my controller (minus the other CRUD functions) :
namespace Listapp\Controller;
use Zend\Mvc\Controller\AbstractActionController;
class ListappController extends AbstractActionController
{
public function indexAction()
{
}
}

So just to further explain my comment, by including a :controller segment in your route, you've told ZF to try and match the first thing in your URL to something that the controller manager can load (in your case, one of the keys in you controller invokables). The controller default you defined in your route would only apply if you visited http://zf2.local/.
So for you, the quickest fix is to change your configuration to:
'controllers' => array(
'invokables' => array(
'Listapp' => 'Listapp\Controller\ListappController'
)
),
'Listapp' in the URL will then match this controller, and everything will work as you expect.
In general it makes things clearer if you avoid using :controller in routes and have at least one route per controller instead, e.g.:
'controllers' => array(
'invokables' => array(
'Listapp\Controller\Listapp' => 'Listapp\Controller\ListappController'
)
),
'router' => array(
'routes' => array(
'listapp' => array(
'type' => 'segment',
'options' => array(
'route' => '/listapp[/:action[/:id]]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Listapp\Controller\Listapp',
'action' => 'index',
),
),
),
),
),

Related

Zend 2 : Unable to render template

I have an error in my Zend Framework 2 project, I try to add a new view named " Blog "
I created the module.config and indexController, and the view but always I get this error and I don't know why :
Zend\View\Renderer\PhpRenderer::render: Unable to render template
"blog/index/index"; resolver could not resolve to a file
the module.config code
<?php
namespace Blog;
return array(
'router' => array(
'routes' => array(
// The following is a route to simplify getting started creating
// new controllers and actions without needing to create a new
// module. Simply drop new controllers in, and you can access them
// using the path /blog/:controller/:action
'blog' => array(
'type' => 'Literal',
'options' => array(
'route' => '/blog',
'defaults' => array(
'__NAMESPACE__' => 'Blog\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(
),
),
),
),
),
),
),
'controllers' => array(
'invokables' => array(
//'Blog\Controller\Index' => 'Blog\Controller\IndexController'
'Blog\Controller\Index' => Controller\IndexController::class
),
),
'view_manager' => array(
'template_path_stack' => array(
__DIR__ . '/../view',
),
),
);
?>
the indexController code :
<?php
namespace Blog\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class IndexController extends AbstractActionController
{
public function indexAction()
{
return new ViewModel();
}
}
?>
and finally my structure folders is like this :
I use version 2.4.13
The src folder should only contain PHP classes, your view templates should not be in there. Move the view folder up a level and it should work.
Take a look at the folder structure of the ZF skeleton app as a reference: https://github.com/zendframework/ZendSkeletonApplication/tree/master/module/Application

Zend framework 2 module name routing issue

I have a problem with module routing. I have 2 modules, Application and Admin. Each modules have indexAction as default action:
localhost/ --> Application/index
localhost/admin/ -> Admin/index
Admin/index works only with localhost/admin/index/
This problem happens when a module name starts with the letter "A". If I rename Admin to "Cars", localhost/cars/ works correctly!
the error is:
A 404 error occurred
The requested controller was unable to dispatch the request.
Controller:
Application\Controller\Application
No Exception available
This is module.config.php inside Application module:
<?php
return array(
'router' => array(
'routes' => array(
'Application' => array(
'type' => 'Segment',
'options' => array(
'route' => '[/][:action/]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'controller' => 'Application\Controller\Application',
'action' => 'index',
),
),
),
),
),
'controllers' => array(
'invokables' => array(
'Application\Controller\Application' => 'Application\Controller\IndexController'
),
),
'view_manager' => array(
'display_not_found_reason' => true,
'display_exceptions' => true,
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => array(
'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
'Application/Application/index' => __DIR__ . '/../view/Application/index/index.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
),
'template_path_stack' => array(
'Application' => __DIR__ . '/../view',
),
),
);
?>
this is module.config.php inside Admin module:
<?php
return array(
'router' => array(
'routes' => array(
'Admin' => array(
'type' => 'Segment',
'options' => array(
'route' => '/admin/[:action/]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*'
),
'defaults' => array(
'controller' => 'Admin\Controller\AdminController',
'action' => 'index'
),
),
),
),
),
'controllers' => array(
'invokables' => array(
'Admin\Controller\AdminController' => 'Admin\Controller\AdminController'
),
),
'view_manager' => array(
'display_not_found_reason' => true,
'display_exceptions' => true,
'template_path_stack' => array(
'Admin' => __DIR__ . '/../view',
),
),
);
?>
IndexController.php
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class IndexController extends AbstractActionController
{
public function indexAction(){
}
}
AdminController.php
namespace Admin\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class AdminController extends AbstractActionController
{
public function indexAction()
{}
}
Anyone can help me?
First your error The requested controller was unable to dispatch the request. only occures when the router can't dispatch the request to its defined action. So please verify that your controller are correct and the actions are present and callable.
As allready pointed out your /admin/ route will point to two configured endpoints. This is not a problem in the first place when the admin route would be defined before the application route in the config.
So your route /admin/ route would never be routed to your AdminController as the other dynamic route would be matched first.
To get you expected result use the priority setting in your route, to make sure your Admin route will be matched before your Application route.
'router' => array(
'routes' => array(
'Admin' => array(
'priority' => 100,
'type' => 'Segment',
'options' => array(
'route' => '/admin/[:action/]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*'
),
'defaults' => array(
'controller' => 'Admin\Controller\AdminController',
'action' => 'index'
),
),
),
),
),
Beside your question, don't end php scripts with ?> as this could lead to bugs when a whitespace is after the end tag.

Multiple controller in one module in zend framework

hi i am new in zend framework2.2.0. i want to create one module with multiple controller i have download "Album" module from github and its working fine
Now i want to add the more controller in it
the below i have shown my folder structure for file in module
module/
Album/
config/
module.config.php
src/
Album/
Controller/
AlbumController.php
UserController.php
Form/
AlbumForm.php
UserForm.php
Model/
AlbumTable.php
Album.php
UserTable.php
User.php
view/
album/
album/
index.phtml
user/
index.phtml
i have also changed all the name space in file
namespace Album\Controller;
class UserController extends \Zend\Mvc\Controller\AbstractActionController
and some indexAction method witch returns a new \Zend\View\Model\ViewModel();
then you can create your viewfile in
Album/view/Album/user/index.phtml
i did above changes.
is there any chage needed in "Album/Module.php" file ?
can you tell me through which link i can see users list ?
i and tired with this error help me to get out of it
You may need to add url rules for user in module.config.php in Album/config folder. Then you can access the url like
// The following section is new and should be added to your file
'router' => array(
'routes' => array(
'album' => array(
'type' => 'segment',
'options' => array(
'route' => '/album[/:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Album\Controller\Album',
'action' => 'index',
),
),
),
'user' => array(
'type' => 'segment',
'options' => array(
'route' => '/user[/:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Album\Controller\User',
'action' => 'index',
),
),
),
),
),
Also
'controllers' => array(
'invokables' => array(
'Album\Controller\Album' => 'Album\Controller\AlbumController',
'Album\Controller\User' => 'Album\Controller\UserController',
),
),

Multiple namespaces under same module in ZF2

I'm having trouble configuring multiple namespaces/classes under same module.
For example, I have a module called "Account", in which I'd like to include all account related classes (companies: 'accounts', users: 'users', external api: 'api' etc.. ). Module structure looks like this..
/Account
- Module.php
- /config
- /view
- /src
- /Account
- /Controller (AccountController.php)
- /Form (AccountForm.php)
- /Model (Account.php + AccountTable.php)
- /User
- /Controller (UserController.php)
- /Form (UserForm.php)
- /Model (User.php + UserTable.php)
- /Api
- Api.php (simple class)
Being new to ZF2, I decided to keep things simple and stupid and Not to try implementing complex routing to Account module. So, in order to trigger indexAction for UserController, url should be /user (!)
Here's the module class:
namespace Account;
use Account\Model\AccountTable;
use Account\Model\UserTable;
class Module
{
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php',
),
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
public function getServiceConfig()
{
return array(
'factories' => array(
'Account\Model\AccountTable' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$table = new AccountTable($dbAdapter);
return $table;
},
'Account\Model\UserTable' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$table = new UserTable($dbAdapter);
return $table;
},
),
);
}
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
}
And the module.config file
return array(
'controllers' => array(
'invokables' => array(
'Account\Controller\Account' => 'Account\Controller\AccountController',
'Account\Controller\User' => 'Account\Controller\UserController',
),
),
'router' => array(
'routes' => array(
'account' => array(
'type' => 'segment',
'options' => array(
'route' => '/account[/:action[/:accountId]]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'accountId' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Account\Controller\Account',
'action' => 'index',
),
),
/*
'may_terminate' => true,
'child_routes' => array(
'user' => array(
'type' => 'literal',
'options' => array(
'route' => '/user[/:action[/:userId]]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'userId' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Account\Controller\User',
'action' => 'index'
)
)
)
),
*/
),
'user' => array(
'type' => 'segment',
'options' => array(
'route' => '/user[/:action[/:userId]]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'userId' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Account\Controller\User',
'action' => 'index',
),
),
)
),
),
'view_manager' => array(
'template_path_stack' => array(
'account' => __DIR__ . '/../view',
'user' => __DIR__ . '/../view',
),
),
);
But the error I'm getting is, "Class 'Account\Controller\UserController' not found". I am sure i've missed something. Any clue please?
Thanks
You must let the StandardAutoloader know about your new namespace:
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php',
),
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
// This is for the Account namespace
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
// And this is for the User namespace
'User' => __DIR__ . '/src/' . 'User',
),
),
);
}
In the module.config.php
return array(
'controllers' => array(
'invokables' => array(
'Account\Controller\Account' => 'Account\Controller\AccountController',
// The key can be what ever you want, but the value must be a valid
// class name. Your UserController lives in the User namespace,
// not in Account
'Account\Controller\User' => 'User\Controller\UserController',
),
),
/* ... */
);
The StandardLoader needs to know where to find the classes. You can define it with an option called namespaces which is an array that contains absolute (or relative to the current script) paths. It should look like this:
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__
)
)
__NAMESPACE__ is the name of the module, and __DIR__ the absolute path to the Module.php script
Check http://framework.zend.com/manual/2.0/en/modules/zend.loader.standard-autoloader.html
The ClassMapAutoloader is used for performance: you define the class key and its exactly path to the file, instead of a folder which zf2 has to browse its contents doing filesystem operations (StandardLoader's way).
Check http://framework.zend.com/manual/2.0/en/modules/zend.loader.class-map-autoloader.html

Zend Framework Config file JSON

Currently I'm learning ZF2. While going through "Getting start", I see that each config file for module is quite filled with PHP arrays. An example from documentation:
<?php
return array(
'controllers' => array(
'invokables' => array(
'Album\Controller\Album' => 'Album\Controller\AlbumController',
),
),
// The following section is new and should be added to your file
'router' => array(
'routes' => array(
'album' => array(
'type' => 'segment',
'options' => array(
'route' => '/album[/:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Album\Controller\Album',
'action' => 'index',
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'album' => __DIR__ . '/../view',
),
),
);
Array with array in it with array. Actually I know, that array is just name of function and it's more like map with key/value pair.
One of the Zend MODS pointed that we can use JSON for config files:
http://framework.zend.com/manual/2.0/en/user-guide/routing-and-controllers.html#comment-696979913
Does anyone can provide example for beginner? I'd really prefer to use JSON format for those file configs instead of arrays/map, but I couldn't find it on ZF homepage. Or maybe I shouldn't do it?
I would try modifying the getConfig() function inside your Module.php file:
return \Zend\Config\Factory::fromFile(__DIR__ . '/config/module.config.json', false);

Categories