可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I know with ZF1 you would retrieve the module/controller name using custom View Helpers that would get the singleton frontController object and get the name there.
Using ZF2 as they've abolished alot of the singleton nature of the framework and introduced DI where I've specified aliases for all of my controllers within this module... I can imagine I would get it through accessing the DI or perhaps injecting the current name into the layout.
Anyone got any idea how you would do it. I guess there a hundred different ways but after sniffing about the code for a few hours I can't really figure out how its meant to be done now.
The reason I wanted the controller name is to add it to the body as a class for specific controller styling.
Thanks, Dom
回答1:
ZF2 is out and so is the skeleton. This is adding on top of the skeleton so it should be your best example:
Inside Module.php
public function onBootstrap($e)
{
$e->getApplication()->getServiceManager()->get('translator');
$e->getApplication()->getServiceManager()->get('viewhelpermanager')->setFactory('controllerName', function($sm) use ($e) {
$viewHelper = new View\Helper\ControllerName($e->getRouteMatch());
return $viewHelper;
});
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
}
The actual ViewHelper:
// Application/View/Helper/ControllerName.php
namespace Application\View\Helper;
use Zend\View\Helper\AbstractHelper;
class ControllerName extends AbstractHelper
{
protected $routeMatch;
public function __construct($routeMatch)
{
$this->routeMatch = $routeMatch;
}
public function __invoke()
{
if ($this->routeMatch) {
$controller = $this->routeMatch->getParam('controller', 'index');
return $controller;
}
}
}
Inside any of your views/layouts
echo $this->controllerName()
回答2:
This would be a solution I got to work with zf2 beta5
module/MyModule/Module.php
namespace MyModule;
use Zend\Mvc\ModuleRouteListener;
use MyModule\View\Helper as MyViewHelper;
class Module
{
public function onBootstrap($e)
{
$app = $e->getApplication();
$serviceManager = $app->getServiceManager();
$serviceManager->get('viewhelpermanager')->setFactory('myviewalias', function($sm) use ($e) {
return new MyViewHelper($e->getRouteMatch());
});
}
...
}
module/MyModule/src/MyModule/View/Helper.php
namespace MyModule\View;
use Zend\View\Helper\AbstractHelper;
class Helper extends AbstractHelper
{
protected $route;
public function __construct($route)
{
$this->route = $route;
}
public function echoController()
{
$controller = $this->route->getParam('controller', 'index');
echo $controller;
}
}
In any viewfile
$this->myviewalias()->echoController();
回答3:
instead of extending onBootStrap()
in Module.php
, you can use getViewHelperConfig()
(also in Module.php
). The actual helper is unchanged, but you get the following code to create it:
public function getViewHelperConfig()
{
return array(
'factories' => array(
'ControllerName' => function ($sm) {
$match = $sm->getServiceLocator()->get('application')->getMvcEvent()->getRouteMatch();
$viewHelper = new \Application\View\Helper\ControllerName($match);
return $viewHelper;
},
),
);
}
回答4:
Short Code here :
$this->getHelperPluginManager()->getServiceLocator()->get('application')->getMvcEvent()->getRouteMatch()->getParam('action', 'index');
$controller = $this->getHelperPluginManager()->getServiceLocator()->get('application')->getMvcEvent()->getRouteMatch()->getParam('controller', 'index');
$controller = array_pop(explode('\', $controller));
回答5:
I wanted to access current module/controller/route name in navigation menu partial and there was no way but to implement custom view helper and access it, i came up with the following, i am posting it here.
<?php
namespace Application\View\Helper;
use Zend\View\Helper\AbstractHelper;
/**
* View Helper to return current module, controller & action name.
*/
class CurrentRequest extends AbstractHelper
{
/**
* Current Request parameters
*
* @access protected
* @var array
*/
protected $params;
/**
* Current module name.
*
* @access protected
* @var string
*/
protected $moduleName;
/**
* Current controller name.
*
* @access protected
* @var string
*/
protected $controllerName;
/**
* Current action name.
*
* @access protected
* @var string
*/
protected $actionName;
/**
* Current route name.
*
* @access protected
* @var string
*/
protected $routeName;
/**
* Parse request and substitute values in corresponding properties.
*/
public function __invoke()
{
$this->params = $this->initialize();
return $this;
}
/**
* Initialize and extract parameters from current request.
*
* @access protected
* @return $params array
*/
protected function initialize()
{
$sm = $this->getView()->getHelperPluginManager()->getServiceLocator();
$router = $sm->get('router');
$request = $sm->get('request');
$matchedRoute = $router->match($request);
$params = $matchedRoute->getParams();
/**
* Controller are defined in two patterns.
* 1. With Namespace
* 2. Without Namespace.
* Concatenate Namespace for controller without it.
*/
$this->controllerName = !strpos($params['controller'], '\\') ?
$params['__NAMESPACE__'].'\\'.$params['controller'] :
$params['controller'];
$this->actionName = $params['action'];
/**
* Extract Module name from current controller name.
* First camel cased character are assumed to be module name.
*/
$this->moduleName = substr($this->controllerName, 0, strpos($this->controllerName, '\\'));
$this->routeName = $matchedRoute->getMatchedRouteName();
return $params;
}
/**
* Return module, controller, action or route name.
*
* @access public
* @return $result string.
*/
public function get($type)
{
$type = strtolower($type);
$result = false;
switch ($type) {
case 'module':
$result = $this->moduleName;
break;
case 'controller':
$result = $this->controllerName;
break;
case 'action':
$result = $this->actionName;
break;
case 'route':
$result = $this->routeName;
break;
}
return $result;
}
}
In order to access the values in layout/view here is how i do it.
1. $this->currentRequest()->get('module');
2. $this->currentRequest()->get('controller');
3. $this->currentRequest()->get('action');
4. $this->currentRequest()->get('route');
Hope this helps someone.
回答6:
In zf2 beta4 it made in this manner:
public function init(ModuleManager $moduleManager)
{
$sharedEvents = $moduleManager->events()->getSharedManager();
$sharedEvents->attach('bootstrap', 'bootstrap', array($this, 'onBootstrap'));
}
public function onBootstrap($e)
{
$app = $e->getParam('application');
// some your code here
$app->events()->attach('route', array($this, 'onRouteFinish'), -100);
}
public function onRouteFinish($e)
{
$matches = $e->getRouteMatch();
$controller = $matches->getParam('controller');
var_dump($controller);die();
}
回答7:
I created CurrentRoute View Helper for this purpose.
Install it:
composer require tasmaniski/zf2-current-route
Register module in config/application.config.php:
'modules' => array(
'...',
'CurrentRoute'
),
Use it in any view/layout file:
$this->currentRoute()->getController(); // return current controller name
$this->currentRoute()->getAction(); // return current action name
$this->currentRoute()->getModule(); // return current module name
$this->currentRoute()->getRoute(); // return current route name
You can see full documentation and code https://github.com/tasmaniski/zf2-current-route
回答8:
$this->getHelperPluginManager()->getServiceLocator()->get('application')
->getMvcEvent()->getRouteMatch()->getParam('action', 'index');
$controller = $this->getHelperPluginManager()->getServiceLocator()
->get('application')->getMvcEvent()->getRouteMatch()
->getParam('controller', 'index');
$controller = explode('\\', $controller);
print_r(array_pop($controller));