我写了一个简单的网址视图助手,它扩展了Zend\View\Helper\Url
并将其附加到ViewHelperManager
:
MyNamespace\View\Helper\Url
namespace MyNamespace\View\Helper;
use Zend\View\Helper\Url as ZendUrl;
class Url extends ZendUrl {
public function __invoke($name = null, array $params = array(), $options = array(), $reuseMatchedParams = false) {
$link = parent::__invoke($name, $params, $options, $reuseMatchedParams);
...
return $link;
}
}
Application\Module
namespace Application;
use ...
class Module {
public function onBootstrap(MvcEvent $mvcEvent) {
$application = $mvcEvent->getApplication();
$serviceManager = $application->getServiceManager();
$viewHelperManager = $serviceManager->get('ViewHelperManager');
$viewHelperManager->setInvokableClass('url', 'MyNamespace\View\Helper\Url');
...
}
}
现在应用程序抛出异常:
致命错误:在/ var / www / foo / bar / vendor / zendframework / zendframework / library / Zend / View / Helper / Url中显示消息'未提供RouteStackInterface实例'的未捕获异常'Zend \ View \ Exception \ RuntimeException'第76行的.php
Zend \ View \ Exception \ RuntimeException:第76行的/var/www/foo/bar/vendor/zendframework/zendframework/library/Zend/View/Helper/Url.php中没有提供RouteStackInterface实例
我调试了两个Url
类。使用Wenn MyNamespace\View\Helper\Url
,未调用方法Zend\View\Helper\Url#setRouter(...)
且未设置路由器。不明白为什么......
如何让它运作?
答案 0 :(得分:1)
没有测试过,所以我不知道它是否有效,我只是在猜测:
替换:
$viewHelperManager->setInvokableClass('url', 'MyNamespace\View\Helper\Url');
使用:
$viewHelperManager->setFactory('url', function ($sm) use($serviceLocator) {
$helper = new \MyNamespace\View\Helper\Url;
$router = Console::isConsole() ? 'HttpRouter' : 'Router';
$helper->setRouter($serviceLocator->get($router));
$match = $serviceLocator->get('application')
->getMvcEvent()
->getRouteMatch();
if ($match instanceof RouteMatch) {
$helper->setRouteMatch($match);
}
return $helper;
});
答案 1 :(得分:1)
您也可以使用初始化程序!
'view_helpers' => array(
'invokables' => array(
'MyUrl' => 'MyModule\View\Helper\MyUrl'
),
'initializers' => array(
function ($instance, $sm) {
if ($instance instanceof \Zend\View\Helper\Url) {
$serviceLocator = $sm->getServiceLocator();
$router = \Zend\Console\Console::isConsole() ? 'HttpRouter' : 'Router';
$instance->setRouter($serviceLocator->get($router));
$match = $serviceLocator->get('application')
->getMvcEvent()
->getRouteMatch();
if ($match instanceof RouteMatch) {
$instance->setRouteMatch($match);
}
}
}
)
)
你可以根据需要扩展\ Zend \ View \ Helper \ Url
namespace MyModule\View\Helper;
use Zend\View\Helper\Url as ZendUrl;
class MyUrl extends ZendUrl {
public function __invoke() {
return parent::__invoke('MyRoute');
}
}
答案 2 :(得分:0)
Aydin的解决方案对我有用,我把代码或多或少都没有触及到module.php的getViewHelperConfig
public function getViewHelperConfig()
{
return array(
'invokables' => array(
.....
),
'factories' => array(
'modalurl' => function ($helperPluginManager) {
$serviceLocator = $helperPluginManager->getServiceLocator();
$view_helper = new \Application\View\Helper\ModalUrl();
$router = \Zend\Console\Console::isConsole() ? 'HttpRouter' : 'Router';
$view_helper->setRouter($serviceLocator->get($router));
$match = $serviceLocator->get('application')
->getMvcEvent()
->getRouteMatch();
if ($match instanceof RouteMatch) {
$view_helper->setRouteMatch($match);
}
return $view_helper;
}
),
);
}
答案 3 :(得分:0)
虽然这个问题已经过时了,但可以考虑在这里添加一个基于配置的覆盖,以及使用HelperPluginManager
注册的工厂:
在module.config.php
:
'view_helpers' => array(
'factories'=> array(
'url' => 'Application\View\Helper\UrlFactory',
)
),
视图助手插件工厂本身:
<?php
namespace Application\View\Helper;
use Zend\Console\Console;
use Zend\Mvc\Router\RouteMatch;
use Zend\Mvc\Router\RouteStackInterface;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\View\Helper\Url as BaseUrlHelper;
use Zend\View\HelperPluginManager;
class UrlFactory implements FactoryInterface
{
/**
* Create service
*
* @param ServiceLocatorInterface $helperPluginManager
* @return mixed
*/
public function createService(ServiceLocatorInterface $helperPluginManager)
{
/**
* @var $helperPluginManager HelperPluginManager
* @var $router RouteStackInterface
*/
$serviceLocator = $helperPluginManager->getServiceLocator();
$helper = new Url();
$router = Console::isConsole() ? 'HttpRouter' : 'Router';
$router = $serviceLocator->get($router);
$helper->setRouter($router);
$match = $serviceLocator->get('application')
->getMvcEvent()
->getRouteMatch()
;
if ($match instanceof RouteMatch) {
$helper->setRouteMatch($match);
}
return $helper;
}
}
这里的诀窍在于,在这个工厂中,只接收HelperPluginManager
服务定位器。要访问其他服务,首先需要获取全局服务定位器(这是由use
所有其他解决方案中的闭包外部的全局服务定位器完成的。