ris*_*eli 12 model-view-controller routes zend-framework2
我目前正在通过大致基于骨架应用程序开发一个小型MVC应用程序来学习ZF2.现在我试图隐藏一些基于匹配路由的固定HTML元素:举个例子,我不想在登录阶段显示主菜单.
我可以通过将切换参数作为控制器动作的返回值传递来轻松实现,但感觉不对,所以我只想从布局中检查匹配的路径并相应地构建布局.
问题是,我不知道如何在模板中获得匹配的路线.这可能吗?还有其他解决方案可以避免将布局逻辑添加到控制器中
在一些优秀的科学怪人工作之后编辑,我能够找到解决方案.我喜欢使用帮助器的想法,所以我只是尝试从主模块中的boostrap函数传递Application对象:
$app = $e->getApplication();
$serviceManager = $app->getServiceManager();
....
$serviceManager->get('viewhelpermanager')->setFactory('getRoute', function($sm) use ($app) {
return new Helper\GetRoute($app);
});
Run Code Online (Sandbox Code Playgroud)
和辅助函数:
use Zend\View\Helper\AbstractHelper;
class GetRoute extends AbstractHelper {
private $sm;
public function __construct($app) {
$this->sm = $app->getServiceManager();
}
public function echoRoute() {
$router = $this->sm->get('router');
$request = $this->sm->get('request');
$routeMatch = $router->match($request);
if (!is_null($routeMatch))
echo $routeMatch->getMatchedRouteName();
}
}
Run Code Online (Sandbox Code Playgroud)
也许有更清洁,更ZF2ish的方式来做到这一点......
小智 30
没有新匹配的另一种解决方案
$routeMatch = $serviceLocator->get('Application')->getMvcEvent()->getRouteMatch();
echo $routeMatch->getMatchedRouteName();
Run Code Online (Sandbox Code Playgroud)
Den*_*bov 12
有一种方法可以在布局中获得服务管理器:
$sm = $this->getHelperPluginManager()->getServiceLocator();
Run Code Online (Sandbox Code Playgroud)
然后你可以访问$sm->get('router')等
您可以创建一个实现ServiceManagerAwareInterface的View帮助程序.然后在View帮助程序内部使用ServiceManager实例检索路由器和请求对象,然后重新构建路由匹配.
$services = $this->getServiceManager();
$router = $services->get('router');
$request = $services->get('request');
$routeMatch = $router->match($request);
echo $routeMatch->getMatchedRouteName();
Run Code Online (Sandbox Code Playgroud)
我还建议编写View帮助程序,以便代码每个请求只触发一次.
当转移到ZF3时,你应该考虑使用这种方法...因为getLocator不再可用(并且它不正确注入它).
创建助手
namespace Application\View\Helper;
use Zend\Http\Request;
use Zend\Router\RouteStackInterface;
use Zend\View\Helper\AbstractHelper;
/**
* Helper to get the RouteMatch
*/
class RouteMatch extends AbstractHelper
{
/**
* RouteStackInterface instance.
*
* @var RouteStackInterface
*/
protected $router;
/**
* @var Request
*/
protected $request;
/**
* RouteMatch constructor.
* @param RouteStackInterface $router
* @param Request $request
*/
public function __construct(RouteStackInterface $router, Request $request)
{
$this->router = $router;
$this->request = $request;
}
/**
* @return \Zend\Router\RouteMatch
*/
public function __invoke()
{
return $this->router->match($this->request);
}
}
Run Code Online (Sandbox Code Playgroud)为此助手创建一个工厂
namespace Application\View\Helper;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
class RouteMatchFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$router = $container->get('router');
$request = $container->get('request');
return new RouteMatch($router, $request);
}
}
Run Code Online (Sandbox Code Playgroud)在你的工厂打电话给你的工厂,Module.php并为它创建一个别名.
public function getViewHelperConfig()
{
return array(
'factories' => array(
RouteMatch::class => RouteMatchFactory::class,
),
'aliases' => array(
'routeMatch' => RouteMatch::class,
)
);
}
Run Code Online (Sandbox Code Playgroud)就是这样......你有一个使用新的ZF3标准的RouteMatch Helper.
再见!
我相信您可以通过查找操作/控制器名称来解决它:
$controller = $this->getRequest()->getControllerName();
$action = $this->getRequest()->getActionName();
Run Code Online (Sandbox Code Playgroud)
一旦您知道了操作,您就可以根据特定条件来启用布局的各个部分。