Router in Zend Framework 2 : failed retrieving - php

I'm new with Zend Framework, i used to use framework CI and Laravel but in my project i should use ZF2. Honestly, i don't get it how to building app with ZF2. I followed the instructions from here : https://www.youtube.com/watch?v=OYkVHiXeGeY
but i got some error.
Zend\Mvc\Controller\ControllerManager::createFromInvokable: failed retrieving "csnusercontrolleruser(alias: CsnUser\Controller\User)" via invokable class "CsnUser\Controller\UserController"; class does not exist
my strucktur folder:
:: module
->CsnUser
>>config
->module.config.php
>>src
->CsnUser
->Controller
->UserController.php
>>view
->csn-user
->user
->index.phtml
>>Module.php
Module.php
<?php
namespace CsnUser;
use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
class Module{
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespace' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
}
module.config.php
<?php
return array(
'controllers' => array(
'invokables' => array(
'CsnUser\Controller\User' => 'CsnUser\Controller\UserController',
),
),
'router' => array(
'routes' => array(
'csn_user' => array(
'type' => 'Literal',
'options' => array(
'route' => '/csn-user',
'defaults' => array(
'__NAMESPACE__' => 'CsnUser\Controller',
'controller' => 'User',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => 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(),
),
),
),
),
),
),
'view_manager' => array(
/*'template_map' => array(
'layout/Auth' => __DIR__ . '/../view/layout/xxxx.phtml',
),*/
'template_path_stack' => array(
'csn_user' => __DIR__ . '/../view'
),
),
);
UserController.php
<?php
namespace CsnUser\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class UserController extends AbstractActionController{
public function indexAction()
{
return new ViewModel();
}
}
index.phtml
<h1>Welcome</h1>
Can anyone help me ?

Your getAutoLoaderConfig() method is incorrect.
Try this once:
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
Pay attention to the key namespaces in the array.
In your instruction video at 4:40 they also use the plural :)

I solved the problem by adding a string to composer.json:
"autoload": {
"psr-0": {
"MyModule": "module/MyModule/src/"
}
}
and then, in the console, I navigated to the project folder and ran:
php composer.phar update

Related

Zend Framework Module Setup

I'm trying to setup a module in the Zend Framework. Right now all I want is for it to go to my summary.phtml page, which will display Hello World.
I have setup the directory structure under my module directory as follows:
My files are as follows:
module.config.php
<?php
return array(
'controllers' => array(
'invokables' => array(
'BlindQC\Controller\BlindQC' => 'BlindQC\Controller\BlindQCController',
),
),
// The following section is new and should be added to your file
'router' => array(
'routes' => array(
'blinqc' => array(
'type' => 'Literal',
'options' => array(
'route' => '/summary',
'defaults' => array(
'__NAMESPACE__' => 'BlindQC\Controller',
'controller' => 'BlindQC',
'action' => 'summary',
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'blindqc' => __DIR__ . '/../view',
),
),
);
BlindQCController.php
<?php
namespace BlindQC\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class BlindQCController extends AbstractActionController{
public function summaryAction(){
}
};
summary.phtml
<h1>Hello World</h1>
autoload_classmap.php
<?php
return array();
Module.php
<?php
namespace BlindQC;
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 getConfig() {
return include __DIR__ . '/config/module.config.php';
}
}
I also modified my project's application.config.php to include my module:
// This should be an array of module namespaces used in the application.
'modules' => array(
'Application',
'UIExperiment',
'Developer',
'User',
'Project',
'Report',
'ProjectFamily',
'FMEProcessManager',
'BlindQC'
),
When I try to go to the summary route (/blindqc/summary) I get a 404. Any idea what I'm doing wrong?
All I had to do was change the route in module.config.php to /blindqc/summary and rename view/blindqc/blindqc to view/blind-qc/blind-qc in my directory structure.

Where i did mistake in this first Zend Framework 2 program

First create a folder coinsproject then,
coinsproject-->config folder,src folder,view folder,autoload_classmap.php,Module.php
In Coinsproject/autoload_classmap.php
<?php
return array();
?>
In Coinsproject/Module.php
<?php
namespace Coinsproject;
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 getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
}
?>
In Coinsproject/config/module.config.php
<?php
return array(
'controllers' => array(
'invokables' => array(
'Coinsproject\Controller\Coinsproject' => 'Coinsproject\Controller\CoinsprojectController',
),
),
'router' => array(
'routes' => array(
'album' => array(
'type' => 'segment',
'options' => array(
'route' => '/coinsproject[/][:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Coinsproject\Controller\Coinsproject',
'action' => 'index',
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'coinsproject' => __DIR__ . '/../view',
),
),
);
?>
In Coinsproject/src/Coinsproject/Controller/CoinsprojectController.php
<?php
namespace Coinsproject\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class CoinsprojectController extends AbstractActionController
{
public function indexAction()
{
return new ViewModel();
}
}
?>
In Coinsproject/view/coinsproject/coinsproject/index.phtml
<html>
my name is swapnil.
</html>
And after that i call my module in root/config/application.config.php but when i run it its not working anything.Where i did my mistakes?
In Coinsproject/config/module.config.php
'routes' => array(
'album' => array(
to
'routes' => array(
'coinsproject' => array(
you forget to change the route into coinsproject first, i don't know if it's the only correction to make, but it's a beginning.
may be you should put index.phtml in
Coinsproject/view/coinsproject/index.phtml
[Modulename]/view/[Controllername]/[actionname].phtml
not in
Coinsproject/view/coinsproject/coinsproject/index.phtml
and try to correct define view script (phtml file) in module.config.php in view_manager
'view_manager' => array(
'template_map' => array(
coinsproject/coinsproject/index => __DIR__ . '/../view/coinsproject/index.phtml
)
)

ZF2 dynamic routing

I have problem with the routing in ZF2. I want to make dynamic routing for the software, that I'm making.
For example:
This is the URL: http://localhost:8080/application/index.json/
And this is my module.config (router part):
'router' => array(
'routes' => array(
'home' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/',
'defaults' => array(
'controller' => 'Application\Controller\Index',
),
),
),
'restful' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/:module/[:controller[/:action][.:formatter][/:id]]',
'constraints' => array(
'module' => '[a-zA-Z][a-zA-Z0-9_-]*',
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'formatter' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[a-zA-Z0-9_-]*'
),
),
),
),
),
Everything is working fine, but when I create new controller, have to add it to controllers['invokables'] setting in module.config.
'controllers' => array(
'invokables' => array(
'index' => 'Application\Controller\IndexController',
'cloud' => 'Application\Controller\CloudController',
),
),
So the question is, how to automate the controllers['invokables'] to process requests dynamically, without describing every controller in it.
Fast and dirty, but you get the idea.
namespace Application;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
class Module
{
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$eventManager->attach (MvcEvent::EVENT_ROUTE, function (MvcEvent $e) {
$controller_loader = $e->getApplication ()->getServiceManager ()->get ('ControllerLoader');
$controller = $e->getRouteMatch ()->getParam ('controller');
$controller_class = '\Application\Controller\\'.ucfirst ($controller).'Controller';
// Add service locator to the controller
$controller_object = new $controller_class;
$controller_object->setServiceLocator ($e->getApplication ()->getServiceManager ());
// ------------------------------------
$controller_loader->setService ($controller, $controller_object);
});
}
public function getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
}

ZF2: Module could not be initialized

I'm trying to get started with ZF2 and I have a problem when I writting code from tutorial (on ZF website). My code:
Module.php:
<?php
namespace About;
class About
{
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 getConfig()
{
return include __DIR__ . '/config/module.config.php';
}
}
?>
config/module.config.php:
<?php
return array(
'controllers' => array(
'invokables' => array(
'About\Controller\About' => 'About\Controller\AboutController',
),
),
'router' => array(
'routes' => array(
'album' => array(
'type' => 'segment',
'options' => array(
'route' => '/about[/:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'About\Controller\About',
'action' => 'index',
),
),
),
),
),
'view_manager' => array(
'template_path_stack' => array(
'about' => __DIR__ . '/../view',
)
),
);
Problem is:
Fatal error: Uncaught exception 'Zend\ModuleManager\Exception\RuntimeException' with message 'Module (About) could not be initialized.' in /var/www/zend2/vendor/zendframework/zendframework/library/Zend/ModuleManager/ModuleManager.php on line 175
Why it's shown on start? (in my project: /var/www/zend2/). If I remove module declaration from application.config.php it works okay. What is my problem? :/
Ouch, solved!
In Module.php class must be named Module, not own name...
When having this issue with PSR-4 loading you could also check whether the module name and path to the folder are correct for autoloading inside your composer.json file:
"autoload": {
"psr-4": {
"YourModule\\": "module/YourModule/src/",
... other modules ...
}
},
And then after fixing things run:
composer update
I believe your class indexes are outdated, you can follow this command:
composer install -o

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

Categories